code question regarding serial 7-segment display

Hello, please excuse my noobness. I would like to use this (http://www.sparkfun.com/products/9765) 4 digital 7 segment display in a light meter project. I’ve already constructed the sensor part of the project using a photosensor as part of a voltage divider, feeding an analog input of the arduino. I used the code in the “inventor’s guide” and can view the light level data in the serial monitor of my PC using ```
Serial.print


My goal is to display that number onto the 7segment display. Can someone please point me in the right direction? I don't care about units or scale at this point, I would just like the display to show a number between 0 and 9999 that is proportional to the data being received on the analog pin. 

Thank You!

-Chris Parsons

These devices work best when you send them 4 bytes of data. If you send say, 3 bytes, the controller will remember where you left off, and the next character will go into the 4th position instead of the 1st as you’d likely intended.

So what I’ve seen done and what’s worked in my code is this. (It’s from a clock, so yyyy is the name of one of my 7-seg’s for showing the year. p.year is the real time clock’s variable for the year.

// includes
#include <NewSoftSerial.h>
// global variables
NewSoftSerial yyyy(-1,4);

//setup
yyyy.begin (9600);  //Set baud rate (default 9600)
 yyyy.print("v");      //This clears the display 

//loop
char time1[4];  //Make a 4 byte variable
sprintf(time1, "%02d", p.year);  // %02d will add a leading 0 if necessary.
yyyy.print(time1);

Now if you want, you can dim these displays too.

void backlight(){

// Read from the analog pin our resistor's value, and map it into numbers we can pass to the 7-seg.  Numbers are reversed as 0 is brightest on the display.  Technically the 200 can be 250 I think, but that's very dim.

 int brightness = map(analogRead(6),0,1023,200,0);   

 
 if (old_brightness != brightness){             // Only change the brightness if it's changed
 yyyy.print("z");                    //Tells 7-seg serial to expect the brightness command next
 yyyy.print(brightness, BYTE);
 monthday.print("z");
 monthday.print(brightness, BYTE);
 hourmin.print("z");
 hourmin.print(brightness, BYTE);
 sec.print("z");
 sec.print(brightness, BYTE);
 old_brightness = brightness;            // Set the old value to the new value so we can compare it on the next loop.
 } 
}

There are a couple of different options for displaying numbers that aren’t 4 digits. You can either pad with leading zeros (as I’ve done), or you can send “off” commands to the unused digits. Here’s the format to shut off the 3rd and 4th digits. If you do, make your variable only 2 bytes instead, and pass these after the .print command.

char time4[2];
 sprintf(time4, "%02d", p.second);
sec.print(time4);
sec.print(125,BYTE);  //Blank the last 2 digits if hundredths are not wanted
sec.print(126,BYTE);

I’m still not quite understanding. Hopefully I will be able to figure it out when my parts arrive later today but in case I can’t…please feel free to shed a little more light on the situation.

Thank You,

-Chris Parsons

Hopefully it makes more sense when you get to play with it.

This site helped me a lot in understanding how to use them.

http://www.arunet.co.uk/tkboyd/ec/ec1led4x7ser.htm

Let me know if you have any specific questions and I’ll try to help as best as I can.

Thanks for that link, it was helpful in explaining how the display operates and I was able to get the sample code working. My main confusion is passing the value of the light intensity to the display. I assume I use an array to do that but i’m just not sure how to get the display to output that array. Sorry for being such a noob but I’ve only taken one C++ class and that was years ago. I bought the arduino to improve my programming skills while having fun.

Wow, after actually getting my hands on the hardware, this ended up being a lot easier than I thought.

well…almost. With the following code I can read the value of the light intensity on the LED display perfectly until the value drops to a 3,2 or 1 digit number. If this occurs, when the value increases back to a 4 digit number the most significant digit isn’t always in the right spot. I know that Chanler pointed out that this would happen, and provided a little code to prevent it, but i’m just not sure how to implement it.

Thank You

#include <NewSoftSerial.h>

#define SerInToArdu 2
#define SerOutFrmArdu 3
#define wDelay 100
NewSoftSerial mySerialPort(SerInToArdu,SerOutFrmArdu);
int lightPin = 0;

void setup(){

pinMode(SerOutFrmArdu,OUTPUT);
pinMode(SerInToArdu,INPUT);
mySerialPort.begin(9600);
mySerialPort.print("v");//To reset display module
Serial.begin(9600);
}


void loop(){

  int lightLevel = analogRead(lightPin);
  lightLevel = map(lightLevel, 600, 1024, 0, 9999);
  lightLevel = constrain(lightLevel, 0, 9999);  
  Serial.println(lightLevel);

  
  mySerialPort.print(lightLevel);
  delay(wDelay);

}

Try this and see if it works any better. I have no idea how this works, but the effect seems to be adding leading 0’s until the 4 byte character string is full. :slight_smile:

Replace your mySerialPort.print command with these lines:

char 7seg-lightlevel[4];  
sprintf(7seg-lightlevel, "%02d%02d%02d", lightlevel);  
mySerialPort.print(7seg-lightlevel);

By monitoring with serial monitor on the PC I see that code addition outputs 14 digit numbers and it just like like a mess on the LED display. What does the “%02d” represent?

Thanks!

Actually I should have been paying more attention to the serial monitor becasue it helped me figure this out. I used the following sprintf line:

sprintf(LEVEL, "%04d", lightLevel); 

And it works! I realized that %02d kept two digits all the time so it makes perfect sense that %04d maintains 4 digits all the time. Sweet, thanks for helping me with this.

Now…what would be really nice is if I could turn off the unused digits for 1,2 and 3 digit numbers. Any ideas???

Chris Parsons:
Now…what would be really nice is if I could turn off the unused digits for 1,2 and 3 digit numbers. Any ideas???

Here’s two ideas.

The datasheet says sending the code 0x78 as part of the 4 codes to be displayed will blank the digit it’s sent in. See the example of how to display a “42” (leftmost and rightmost digits are blanked) just above Table 1 in the datasheet (pg1, top right).

[attachment=0]blanks.jpg[/attachment]

Or read section 3.5 of the datasheet. It says that you can control each digit individually and each segment of the digit can be individually turned on or off. So sending the control code for the digit you want off followed by a 0x00 should turn off all the segments and thus blank the digit.

http://www.sparkfun.com/datasheets/Comp … al-v41.pdf