Dual channels thermometer with Atmega328, MAX7219 & 8 digit 7 segment

Hello dear ALL!

I want to build something like that: http://reindeerflotilla.wordpress.com/2009/05/09/a-little-arduino-project/ but with MAX7219, without LCD display. A dual channel thermometer with Atmega328, MAX7219 and 8 digit LED display. It can be with digital temperature sensors but I have NTC’s for now (and I prefer it). I need only one decimal character and on the fourth digit of each thermometer, I want to display “C” (Celsius degrease)
Somebody can help me with a .pde code? PLEASE!!!

Thank you in advance!

Help me please!!!!

What code do you have so far? You want to display 000C to 999C?

7219 is pretty easy to use. Couple of SPI.transfers to set up the initial modes. Built in fonts support 0,1,2,3,4,5,6,7,8,9,H,E,L,P, -, and blank

For a C, you will have to use No Decode mode and define your own digits: (or cheat, use E and don't connect the wire for the middle of the E).

When no-decode is selected, data bits D7–D0 correspond to the segment lines of the MAX7219/MAX7221. Table 6 shows the one-to-one pairing of each data bit to the appropriate segment line.

Is there a datasheet for the NTC?

Thank you sir but I'm not a good programmer. Only a good technician. Maybe I can modify a schech but not to create one myself... The dysplay must be: 00.0C 00.0C (8digit)

Try starting in the playground, “Interfacing with hardware”.
Learn how to read your sensors & have the data sent to the serial monitor as the 8 digits you want.
From there will be easy to write it to the MAX7221/7219 for display.

If you don’t use a libray, then you define a few addresses:

#include <SPI.h>
// SPI uses hardware Chip Select vs having device address

// addresses for the MAX7221, and the values/ranges to write in

#define DECODE_MODE 0x09 // write data 0xFF, Code B Decode for all digits
#define INTENSITY_ADDRESS 0x0A // 0x07 to start, half intensity. valid from 0x00 (min) to 0x0F (max)
#define SCANLIMIT_ADDRESS 0x0B // 0xFF, all 8 digits on
#define SHUTDOWN_ADDRESS 0x0C  // 0x01, normal operation (0x01 = shutdown) - powers up in shutdown mode
#define DISPLAYTEST_ADDRESS 0x0F // 0x01 = all lights on full, 0x00 = normal ops

// replace these names with your digit names: left_tens, left_ones, left_tenths, left_C for example & same for the right side
#define leftscore_tens_address 0x01 // digit 0, leftscore_tens+left_yellow, fill right hand byte with data to display
// data = 0-9, A='-', B='E', C='H', D='L', E='P', F=blank
#define leftscore_ones_address 0x02 // digit 1, leftscore_ones+right_yellow
#define rightscore_tens_address 0x03 // digit 2, rightscore_tens+right_red
#define rightscore_ones_address 0x04 // digit 3, rightscore_ones+right_yellow
#define minutes_tens_address 0x05 // digit 4, minutes_tens+colon
#define minutes_ones_address 0x06 // digit 5, minutes_ones+left_priority
#define seconds_tens_address 0x07 // digit 6, seconds_tens+right_priority
#define seconds_ones_address 0x08 // digit 7, seconds_ones+swap

//write the data out to set it up
void setup() // stuff that runs once before looping forever
{
  // start up SPI to talk to the MAX7221
  SPI.begin(); // nothing in () because we are the master
  pinMode(SS, OUTPUT);  // Slave Select for SPI  <--- Need this here before any SPI writes?

  //  MAX7221: write shutdown register  
  digitalWrite(SS,LOW);  // take the SS pin low to select the chip:
  SPI.transfer(SHUTDOWN_ADDRESS);  // select the Address,
  SPI.transfer(0x00);      // select the data, 0x00 = Outputs turned off
  digitalWrite(SS,HIGH);   // take the SS pin high to de-select the chip:
  // Serial.println("shutdown register, dislays off");

  // put known values into MAX7221 so doesn't have weird display when actually turned on, repeat for all 8 digits
  // 0x0F = blank digit
  digitalWrite(SS,LOW);  // take the SS pin low to select the chip:
  SPI.transfer(leftscore_tens_address);  // select the Address, 
  SPI.transfer(0x0F);      // select the data
  digitalWrite(SS,HIGH);   // take the SS pin high to de-select the chip

  //  MAX7221, set up for normal use
  //  write intensity register
  digitalWrite(SS,LOW);  // take the SS pin low to select the chip:
  SPI.transfer(INTENSITY_ADDRESS);  // select the Address,
  SPI.transfer(intensity);      // select the data
  digitalWrite(SS,HIGH);   // take the SS pin high to de-select the chip:
  //Serial.println("intensity register ");

  // write scanlimit register
  digitalWrite(SS,LOW);  // take the SS pin low to select the chip:
  SPI.transfer(SCANLIMIT_ADDRESS);  // select the Address,
  SPI.transfer(0xFF);      // select the data - FF = all 8 digits
  digitalWrite(SS,HIGH);   // take the SS pin high to de-select the chip:
  //Serial.println("scanlimit register ");

  // write decode register
  digitalWrite(SS,LOW);  // take the SS pin low to select the chip:
  SPI.transfer(DECODE_MODE);  // select the Address,
  SPI.transfer(0xFF);      // select the data - FF = all 8 digits
  digitalWrite(SS,HIGH);   // take the SS pin high to de-select the chip:
  //Serial.println("decode register ");

  //display test
  digitalWrite(SS,LOW);  // take the SS pin low to select the chip:
  SPI.transfer(DISPLAYTEST_ADDRESS);  // select the Address,
  SPI.transfer(0x01);      // select the data
  digitalWrite(SS,HIGH);   // take the SS pin high to de-select the chip:
  //Serial.println("digit display test on ");
  delay (100);

  digitalWrite(SS,LOW);  // take the SS pin low to select the chip:
  SPI.transfer(DISPLAYTEST_ADDRESS);  // select the Address,
  SPI.transfer(0x00);      // select the data
  digitalWrite(SS,HIGH);   // take the SS pin high to de-select the chip:
  //Serial.println("digit display test off ");
  delay (100);

  // write shutdown register for normal display operations
  digitalWrite(SS,LOW);  // take the SS pin low to select the chip:
  SPI.transfer(SHUTDOWN_ADDRESS);  // select the Address,
  SPI.transfer(0x01);      // select the data, 0x01 = Normal Ops
  digitalWrite(SS,HIGH);   // take the SS pin high to de-select the chip:
  //Serial.println("shutdown register, displays on ");
} // end void setup

Now in the loop section, have your code set the flag “update_time” to 1 when your display needs changing, this part of the code will see that and write the updated data out

void loop(){
// your code that reads the temps once a second or something
// and breaks it up into 6 digits
// if a digit change, set this flag:
update_time = 1;

// loop then continues and udpates the display here if needed
//****
// Time digits display update section
//*****

if (update_time == 1) // if = 1, a change was made and we are updating time in here
// otherwise, the 7221 keeps displaying the same thing
{
  update_time = 0;  // reset for the next pass thru

  //combine minutes_tens with Decimal point: colon
  if (minutes_tens == 0) {  // for blanking - skip this if/else if want all digits displayed all the time
    number_to_display = 0x0F;
  }  
  else {
    number_to_display = minutes_tens;
  }
  number_to_display = number_to_display | colon; // OR in the decimal point
  digitalWrite(SS,LOW);  // take the SS pin low to select the chip
  SPI.transfer(minutes_tens_address);  // select the Address,
  SPI.transfer(number_to_display);      // select the data
  digitalWrite(SS,HIGH);   // take the SS pin high to de-select the chip

// repeat this for the other digits
// where you need the decimal point on, set the decimal point bit high


 }  // end Score Update section

} // end void loop

Hello and thank you very much! I will learn and I will try.

Hello again, CrossRoads!

Some suggestions with LedControl library? I find it easier to understand and I decided to use DS18B20 2 sensors (with OneWire library).

Please help me!

THANK YOU IN ADVANCE, SIR!

Don't know, I never used the LED control library, just the setup & update listings I gave provided above. I bet the library does similar, but with uncommented C code that is hard to follow.

Can someone help me with an example of displaying the temperature sensor DS18B20 , ArduinoUno, MAX7219/7221 on 7 segments display, using LedControl library? I need to show one decimal and two tens.

Thanks in advance!

Hello All!
I’m back with a simple code and fuctional, but with a problem: I don’t know to display a decimal value after the decimal point … only one!

How can I do this? What is the formula? What I need to add or modify?
Please help me!

//Inpired from  http://dave-r.posterous.com/arduino-thermometer

Many thanks for Mr. David Roberts!

#include <LedControl.h>
#include <OneWire.h>
#include <DallasTemperature.h>

// pin setups

const byte DIN = 9;
const byte CLK = 8; 
const byte LOADCS = 7;

LedControl lc=LedControl(DIN,CLK,LOADCS,0);  

int tempPin = 5;

OneWire oneWire(tempPin);
DallasTemperature sensors(&oneWire);

byte row = 0;
int val = 0;

void setup() {
  
  // init serial
  Serial.begin(9600);
  
  // init temp sensor
  sensors.begin();
  
  pinMode(DIN, OUTPUT); 
  pinMode(CLK, OUTPUT); 
  pinMode(LOADCS, OUTPUT);
  
  lc.shutdown(0,false);
  lc.setIntensity(0,8); //set the brightness 
}

void loop() {
  
  sensors.requestTemperatures();
  
  float t1 = sensors.getTempCByIndex(0);
  float t2 = sensors.getTempCByIndex(1);
  
  Serial.println(t1);
  Serial.println(t2);
  
  
   // cast to float (only have 2 digits to use on display)
  int rT1 = (int)t1;
  int rT2 = (int)t2;
  
  // get units of temp
  int units1 = rT1 % 10;
  int units2 = rT2 % 10;
  
  // get tens value of temp
  rT1 = rT1/10;
  rT2 = rT2/10;
  
  int tens1 = rT1 % 10;
  int tens2 = rT2 % 10;
  
  print_temp1(units1, tens1);
  print_temp2(units2, tens2);
}

void print_temp1(int units1, int tens1) {
  
  lc.setDigit(0,5,units1,true);
  lc.setDigit(0,6,tens1,false);
}
  
void print_temp2(int units2, int tens2) {
  
  lc.setDigit(0,1,units2,true);
  lc.setDigit(0,2,tens2,false);  
}

No sugestions? Nobody?

I'd jump in, am not familiar with the libraries you've got running tho.

Thanks to CrossRoads for answers and interest! Other opinions? Nobody has displayed digital or analog values ??through MAX7219 or Shift Registers with LedControl library? I noticed that it is a relatively simple and functional way.

Thanks in advance to all who can help me to display a decimal value after decimal point!

Driving the display is simple - so why use a bunch of code hidden behind a library? I just did it directly.

My code is a loop with several sections, if a section does something that results in the display needing update, I set a display_update flag.
When it gets to the display update section, the flag is checked and some spi.transfers are made if needed. If no udpate is needed, the section is skipped.

Looks like the LED library uses the equivalent of the slower shiftout() commands to send the data to the MAX7221.

Here’s the start of that section and the code for updating one digit:

if (update_time == 1) // if = 1, a change was made and we are updating time in here
{
  update_time = 0;  // reset for the next pass thru

  //combine minutes_tens with Decimal point: colon
  if (minutes_tens == 0) {
    number_to_display = 0x0F;
  }  // for blanking
  else {
    number_to_display = minutes_tens;
  }
  number_to_display = number_to_display | colon; // OR in the decimal point
  digitalWrite(SS,LOW);  // take the SS pin low to select the chip
  SPI.transfer(minutes_tens_address);  // select the Address,
  SPI.transfer(number_to_display);      // select the data
  digitalWrite(SS,HIGH);   // take the SS pin high to de-select the chip

Can you do something here to save the 1/10’s of the data?

   // cast to float (only have 2 digits to use on display)
  int rT1 = (int)t1;
  int rT2 = (int)t2;

maybe:

tenthsT1 = t1 - (int)t1; // so tenths = 56.7 - 56 = 0.7
// then multiply by 10 & reconvert to an int to send to the display
tenthsT1 = tenthsT1 * 10;
tenthsT1 = (int)tenthsT1;

Thank you very much! Meanwhile solved almost like you!

int rT1 = (int)t1;
  int rT2 = (int)t2;
  // get decimal of temp
  
  rT1 = 10*t1;
  rT2 = 10*t2;
   
  int dec1 = rT1%10;
  int dec2 = rT2%10;
  
  // get units of temp
  rT1 = rT1/10;
  rT2 = rT2/10;
  
  int units1 = rT1 % 10;
  int units2 = rT2 % 10;
  
  // get tens value of temp
  rT1 = rT1/10;
  rT2 = rT2/10;
  
  int tens1 = rT1 % 10;
  int tens2 = rT2 % 10;

But you are the master, anyway! Many thanks again! It must to insert the function for "-" sign under 0 and is all finished.