Connecting MAX6675 and 3 digit 7 segment display to Arduino Nano (or Uno) - Page 1
Forum section: electronics / beginners

author: mike_mike
author_rank: Super Contributor
timestamp: March 20, 2021, 02:30:32 pm
content: Hi! I am working at a project, which will be a soldering station, and it will use a 3 digit 7 segment display instead of LCD display as I used previously.I wanted to ask what library and what code should I write for the 3 digit 7 segment display in order to not interfere with the MAX6675 module ?The schematic with the connections from Arduino to the display (but using only 3 digits) is attached.

author: ledtester
author_rank: Super Contributor
timestamp: March 20, 2021, 03:01:17 pm
content: My guess is that your problem is that the Arduino only has 14 GPIO pins and you're already using 12 of them for your 3-digit display not leaving enough for the max6675.Common solutions are:- use a shift register for the segment drivers - this will free up several GPIOs:https://create.arduino.cc/projecthub/meljr/7-segment-led-displays-102-using-a-shift-register-6b6976- use a MAX7219 module or chip to drive the LED digit display (just search for max7219 + arduino)

author: mike_mike
author_rank: Super Contributor
timestamp: March 21, 2021, 09:32:22 am
content: Tried this code. It works. Please have a look and tell me what you think ? (especially with the loop() function) ?The code didn't worked until I introduced the reading of the thermocouple (MAX6675) into the if (millis() - lastupdate > updaterate).Is the Arduino correctly reading the MAX6675, at correct time intervals ?Code:#include <PID_v2.h>#include <max6675.h>int thermoDO = 12;int thermoCS = 10;int thermoCLK = 13;MAX6675 thermocouple(thermoCLK, thermoCS, thermoDO);//protectionint relay_pin = A5;int led_pin = 8;//This array contains what segments need to be turned on to display numbers 0-9byte const digits[] = {B00111111, B00000110, B01011011, B01001111, B01100110, B01101101, B01111101, B00000111, B01111111, B01101111};int digit_common_pins[] = {A2, A3, A4}; //Common pins for the triple 7-Segment LED displayint max_digits = 3;int current_digit = max_digits - 1;unsigned long updaterate = 700; //Change how fast the display updates. No lower than 500unsigned long lastupdate;int temperature = 0;//Define Variables we'll be connecting todouble Setpoint, Input, Output;double heaterTemp;//Define the aggressive and conservative Tuning Parametersdouble aggKp = 4, aggKi = 0.2, aggKd = 1;double consKp = 1, consKi = 0.05, consKd = 0.25;//Specify the links and initial tuning parametersPID myPID(&Input, &Output, &Setpoint, consKp, consKi, consKd, DIRECT);void setup(){DDRD = B11111111; // sets Arduino pins 0 to 7 as outputsfor (int y = 0; y < max_digits; y++){pinMode(digit_common_pins, OUTPUT);}//We do not want to drive the soldering iron at 100% because it may burn, so we set it to about 85% (220/255)myPID.SetOutputLimits(0, 220);myPID.SetMode(AUTOMATIC);lastupdate = millis();Setpoint = 0;pinMode(led_pin, OUTPUT);pinMode(relay_pin, OUTPUT);digitalWrite(led_pin, LOW);digitalWrite(relay_pin, LOW);delay(1000);digitalWrite(relay_pin, HIGH);}void loop() {if (millis() - lastupdate > updaterate) {lastupdate = millis();// Read temperatureheaterTemp = thermocouple.readCelsius();Input = (0.779828 * heaterTemp) - 10.3427;//Display temperatureif (isnan(heaterTemp) or Input >= 432) // No TC Connection OR over-temperature{while (true) {digitalWrite(relay_pin, LOW);digitalWrite(11, LOW);PORTD = B00000000;digitalWrite(led_pin, HIGH);}}temperature = Input;}//Read setpoint and transform it into degrees celsius(minimum 150, maximum 350)double newSetpoint = analogRead(A1);newSetpoint = map(newSetpoint, 0, 1023, 150, 400);//Display setpointif (abs(newSetpoint - Setpoint) > 3) {Setpoint = newSetpoint;temperature = newSetpoint;lastupdate = millis();}double gap = abs(Setpoint - Input); //distance away from setpointif (gap < 10){ //we're close to setpoint, use conservative tuning parametersmyPID.SetTunings(consKp, consKi, consKd);}else{//we're far from setpoint, use aggressive tuning parametersmyPID.SetTunings(aggKp, aggKi, aggKd);}myPID.Compute();//Drive the outputanalogWrite(11, Output);//Display the temperatureif (temperature < 50) {show(50);}else{show(temperature);}}void show(int value) {int digits_array[] = {};boolean empty_most_significant = true;for (int z = max_digits - 1; z >= 0; z--) //Cycle through each digit{digits_array = value / pow(10, z); //We now take each digit from the numberif (digits_array != 0 ) empty_most_significant = false; //Do not display leading zerosvalue = value - digits_array * pow(10, z);if (z == current_digit){if (!empty_most_significant || z == 0) { //Check to see that we do not have leading zeros and display the current digitPORTD = digits[digits_array]; //Remove ~ for common cathode}else{PORTD = B00000000;}digitalWrite(digit_common_pins, HIGH);//Change to LOW for common cathode} else {digitalWrite(digit_common_pins, LOW);//Change to HIGH for common cathode}}current_digit--;if (current_digit < 0){current_digit = max_digits; //Start over}}

author: mike_mike
author_rank: Super Contributor
timestamp: March 23, 2021, 09:46:32 am
content: I found the problem. I will write the solution here, probably it will be useful to someone.The max6675 module needs to be read at a minimum interval of 250mS. Please have a look at this code, were is a comment that explains the mentioned time interval:https://github.com/adafruit/MAX6675-library/blob/master/examples/serialthermocouple/serialthermocouple.inoThen I modified the code as shown below:Code:#include <PID_v2.h>#include <max6675.h>//MAX6675 module data pinsint thermoDO = 12;int thermoCS = 10;int thermoCLK = 13;MAX6675 thermocouple(thermoCLK, thermoCS, thermoDO);//Protection pinsint relay_pin = A2;//int led_pin = 8;//This array contains what segments need to be turned on to display numbers 0-9byte const digits[] = {B00111111, B00000110, B01011011, B01001111, B01100110, B01101101, B01111101, B00000111, B01111111, B01101111};int digit_common_pins[] = {A3, A4, A5}; //Common pins for the triple 7-Segment LED displayint max_digits = 3;int current_digit = max_digits - 1;unsigned long updaterate = 700; //Change how fast the display updates. No lower than 500unsigned long lastupdate, lastupdate_max;int temperature = 0;//Define Variables we'll be connecting todouble Setpoint, Input, Output;double heaterTemp;//Define the aggressive and conservative Tuning Parametersdouble aggKp = 4, aggKi = 0.2, aggKd = 1;double consKp = 1, consKi = 0.05, consKd = 0.25;//Specify the links and initial tuning parametersPID myPID(&Input, &Output, &Setpoint, consKp, consKi, consKd, DIRECT);void setup(){DDRD = B11111111; // sets Arduino pins 0 to 7 as outputsfor (int y = 0; y < max_digits; y++){pinMode(digit_common_pins, OUTPUT);}//We do not want to drive the soldering iron at 100% because it may burn, so we set it to about 85% (220/255)myPID.SetOutputLimits(0, 220);myPID.SetMode(AUTOMATIC);lastupdate = millis();lastupdate_max = millis();Setpoint = 0;//pinMode(led_pin, OUTPUT);pinMode(relay_pin, OUTPUT);//digitalWrite(led_pin, LOW);digitalWrite(relay_pin, LOW);delay(1000);digitalWrite(relay_pin, HIGH); // turns on the relay to let the current flow to the soldering iron heater}void loop() {if (millis() - lastupdate_max > 250){lastupdate_max = millis();// Read temperatureheaterTemp = thermocouple.readCelsius();Input = (0.779828 * heaterTemp) - 10.3427; //estimate the temperature of the iron's tip, by reading the temperature of the iron's heater//Display errorif (isnan(heaterTemp) or Input >= 432) // No TC Connection OR over-temperature{while (true) {digitalWrite(relay_pin, LOW);//cuts off the power to the soldering irondigitalWrite(11, LOW);//turns off the PID outputPORTD = B00000000; // Turns off the entire display//digitalWrite(led_pin, HIGH);}}}//Display temperatureif (millis() - lastupdate > updaterate) {lastupdate = millis();temperature = Input;}//Read setpoint and transform it into degrees celsius(minimum 150, maximum 400)double newSetpoint = analogRead(A1);newSetpoint = map(newSetpoint, 0, 1023, 150, 400);//Display setpointif (abs(newSetpoint - Setpoint) > 3) {Setpoint = newSetpoint;temperature = newSetpoint;lastupdate = millis();}double gap = abs(Setpoint - Input); //distance away from setpointif (gap < 10){ //we're close to setpoint, use conservative tuning parametersmyPID.SetTunings(consKp, consKi, consKd);}else{//we're far from setpoint, use aggressive tuning parametersmyPID.SetTunings(aggKp, aggKi, aggKd);}myPID.Compute(); // compute the pid output//Drive the outputanalogWrite(11, Output);//Display the temperatureif (temperature < 50) {show(50); //display 50 if the estimated temperature is below 50C}else{show(temperature); //display the temperature}}void show(int value) {int digits_array[] = {};boolean empty_most_significant = true;for (int z = max_digits - 1; z >= 0; z--) //Cycle through each digit{digits_array = value / pow(10, z); //We now take each digit from the numberif (digits_array != 0 ) empty_most_significant = false; //Do not display leading zerosvalue = value - digits_array * pow(10, z);if (z == current_digit){if (!empty_most_significant || z == 0) { //Check to see that we do not have leading zeros and display the current digitPORTD = digits[digits_array]; //Remove ~ for common cathode}else{PORTD = B00000000;}digitalWrite(digit_common_pins, HIGH);//Change to LOW for common cathode} else {digitalWrite(digit_common_pins, LOW);//Change to HIGH for common cathode}}current_digit--;if (current_digit < 0){current_digit = max_digits; //Start over}}I tested the code and it seems to work good...