Yet Another 7-segment

Hello,

first of all, I already searched on the forum, but somehow I think my 7-segment display is quite exotic, so I need a bit of specific help.

So, it's a 2 and 1/2 digit display... it can show values from 0 to 199 - it has a pin that lights 2 vertical segments together (named hundred), all the other pins are for each segment of the two following digits and a common anode, 16 pins in total.

Here we go, first of all my code:

int Gx2 = 2;
int Ax2 = 3;
int Fx2 = 4;
int Bx2 = 5;
int Bx3 = 6;
int Fx3 = 7;
int Ax3 = 8;
int Gx3 = 9;
int Cx2 = 10;
int Ex2 = 11;
int Dx2 = 12;
int hundred = 13;
int COM = A0;
int Dx3 = A1;
int Ex3 = A2;
int Cx3 = A3;

void setup() {
  pinMode(Gx2, OUTPUT);
  pinMode(Ax2, OUTPUT);
  pinMode(Fx2, OUTPUT);
  pinMode(Bx2, OUTPUT);
  pinMode(Bx3, OUTPUT);
  pinMode(Fx3, OUTPUT);
  pinMode(Ax3, OUTPUT);
  pinMode(Gx3, OUTPUT);
  pinMode(Cx2, OUTPUT);
  pinMode(Ex2, OUTPUT);
  pinMode(Dx2, OUTPUT);
  pinMode(hundred, OUTPUT);
  pinMode(COM, OUTPUT);
  pinMode(Dx3, OUTPUT);
  pinMode(Ex3, OUTPUT);
  pinMode(Cx3, OUTPUT);
}

void zero() {
digitalWrite(COM, HIGH);
digitalWrite(Ax3, LOW);
digitalWrite(Bx3, LOW);
digitalWrite(Cx3, LOW);
digitalWrite(Dx3, LOW);
digitalWrite(Ex3, LOW);
digitalWrite(Fx3, LOW);
digitalWrite(Gx3, HIGH);
digitalWrite(Ax2, HIGH);
digitalWrite(Bx2, HIGH);
digitalWrite(Cx2, HIGH);
digitalWrite(Dx2, HIGH);
digitalWrite(Ex2, HIGH);
digitalWrite(Fx2, HIGH);
digitalWrite(Gx2, HIGH);
digitalWrite(hundred, HIGH);
}


void one() {
digitalWrite(COM, HIGH);
digitalWrite(Ax3, HIGH);
digitalWrite(Bx3, LOW);
digitalWrite(Cx3, LOW);
digitalWrite(Dx3, HIGH);
digitalWrite(Ex3, HIGH);
digitalWrite(Fx3, HIGH);
digitalWrite(Gx3, HIGH);
digitalWrite(Ax2, HIGH);
digitalWrite(Bx2, HIGH);
digitalWrite(Cx2, HIGH);
digitalWrite(Dx2, HIGH);
digitalWrite(Ex2, HIGH);
digitalWrite(Fx2, HIGH);
digitalWrite(Gx2, HIGH);
digitalWrite(hundred, HIGH);
}

void loop() {
  zero();
  delay(1000);
  one();
  delay(1000);
}

Now, as you can see, I can successfully light up single digits, but I'm having trouble figuring out how to translate a variable (let's say coming from the serial port, a sensor, etc..) so it displays on the display... I'm still a noob when it comes to coding, so any hints will be greatly appreciated :slight_smile:

Thanks everyone!

Seb

Thanks,

I knew arrays were the way to go, however I've never used them yet, so I don't know how to do it right.

Anyway, here's a 7 segment "map":

Digits on my display are mapped per this map. Ax2 is the A segment on the first of the two full digits (the first digit is the "1"), Ax3 is the same segment, but on the last digit. I hope you understand what I mean :smiley:

Pins are mapped as below:

D2      pin1      G2
D3      pin2      A2
D4      pin3      F2
D5      pin4      B2
D6      pin5      B3
D7      pin6      F3
D8      pin7      A3
D9      pin8      G3
D10      pin9      C2
D11      pin10      E2
D12      pin11      D2
D13      pin12      1
A0      pin13   COM
A1      pin14      D3
A2      pin15      E3
A3      pin16      C3

So to create the numbers I set LOW the following segments (add x2 for the first digit, x3 for the second to get my pin names)

1 = B + C
2 = A + B + G + E + D
3 = A + B + C + D + G
4 = F + B + G + C
5 = A + F + G + C + D
6 = A + F + E + D + C + G
7 = A + B + C
8 = All
9 = A + B + C + D + F + G
0 = A + B + C + D + E + F

I know, it's a mess, if the one that's gonna help me out will be ever close enough to me... I owe you a beer, at least :wink:

Thanks,

Seb

Thank you so much!

I'm slowly getting the grip, and I'm starting to understand what's going on in the code... I'll need a tiny bit of additional help tho... I tried to use your code by just adding:

void setup() {
pinMode(analog, INPUT);
output = map(analog, 1, 1023, 1, 199);
segments = output();
}

void loop() {
   digitalWrite(segments, output);
}

which obviously does not work :smiley: Also, as far as I can see your code doesn't use the first digit (the "1"), so the display would be only able to show values from 0 to 99... if you could help me a bit more I'll even think about sending a real Slovenian beer to the US :wink:

Thanks again,

Seb

P.S.: here's the error code I get, if it's of any use to you:
7seg.cpp: In function 'void setup()':
7seg:43: error: 'output' cannot be used as a function
7seg.cpp: In function 'void loop()':
7seg:47: error: invalid conversion from 'boolean (*)[7]' to 'uint8_t'
7seg:47: error: initializing argument 1 of 'void digitalWrite(uint8_t, uint8_t)'

I'm not getting any code errors before my own lines, so I guess yours are completely correct :slight_smile:

I'm slowly getting the grip, and I'm starting to understand what's going on in the code... I'll need a tiny bit of additional help tho... I tried to use your code by just adding:

void setup() {

pinMode(analog, INPUT);
output = map(analog, 1, 1023, 1, 199);
segments = output();
}

void loop() {
  digitalWrite(segments, output);
}

Sebastian,

I'm sorry to burst your bubble, but that piece of gibberish code will never do something useful. Whatever you imagined it should do, it doesn't. Your estimate of slowly getting the grip seems to be wildly over-optimistic.

I would love to advise you how to fix that code, but I simply can't make any sense of it what it should mean. Perhaps I don't have enough Vodka Martinis in me yet to reach illumination.

Korman

Korman,

bursting bubbles is fine, being rude is not. Not everyone is able to get illuminated by vodka martinis (no matter how many olives you put in), and I guess that's a good thing.

My code is an addendum to the code posted earlier by Richard, perhaps if you looked at it too it would make sense to you?

What I'm trying to do is use an input (analog pin #5, which I named "analog" (that's not visible, my fault, I didn't copy the whole thing so you're unable to see I added it), map it's value to a number from 0 to 199 (the highest number my 7-segment display can show), and somehow use Richard's code to display it. The last part is the one that does not work (as I stated myself), and the one I need help with.

Being a good coder doesn't license you to be an a...hole (no offense), I always thought this forum is supposed to be a place where newbies can get help from more knowledgeable members. As far as I've seen people, unlike you, tend to be friendly here... we're all learning. And if you were to ask me something you don't know about MY field of work/expertise, I'd never answer with an acid comment as you did.

S.

Thanks Richard,

both analog and output were defined at the beginning of the code, but I forgot to paste it, I just pasted what I added AFTER your code.

Anyway, THIS is the kind of answers I like. It's constructive. I know I'm very limited when it comes to coding and I have to learn a looooot, but with people like you helping out code-idiots like me, it's way easier.

Anyway, I'll go back to Arduino's reference and study the examples, hopefully I'll be able to figure out something alone :slight_smile:

Thanks again, a lot!

S.

So, it's a 2 and 1/2 digit display... it can show values from 0 to 199 - it has a pin that lights 2 vertical segments together (named hundred), all the other pins are for each segment of the two following digits and a common anode, 16 pins in total.

I said at the very beginning it's a common anode display, as I said it's somewhat exotic, and I was unable to find any schematic to publish on this thread (but I gave a detailed description).

Also, I revealed what my project is: being able to display a value on it. I already know how to use serial communication to get a value from e.g. an app running on my PC, or how to get a value from a sensor (I know, it doesn't show from my last piece of code, I've just figured out it's really a mess).

I just never used arrays yet, so I was really confused. Anyhow, I think I really got it now. What your code missed is setting all the pins to OUTPUT, and I successfully used an array to set all needed pins to OUTPUT :slight_smile: I also fixed my sensor input code, and everything is working so far.

I have to clean up the code a bit, post the complete sketch and then I'll ask more specific questions about how to parse a value to display correctly, or maybe, I'll figure it out myself. Fortunately, my IQ is high enough to learn fast. Heck, I speak fluently 6 languages, learning C(++) will not be such a problem :wink:

Yep, I already figured that 8 was actually a 7 :slight_smile:

I'll read the reference for the module and division functions and try to do it myself. I'll be able to post a complete working code soon :slight_smile:

Thanks,

Seb

Yeah, I know, I'm sorry... but I couldn't just find a datasheet or drawing of my display, and I was too lazy to draw it myself :stuck_out_tongue:

Anyway, I came up with almost the same code as you did for the parsing... guess I'm on my good way to get it to work... :wink:

Here it is, working as a charm:

  byte unSeg[7] = {3, 5, 10, 12, 11, 4, 2};   // defines pin number for segments A ~ G for units digit
  byte tnSeg[7] = {8, 6, A3, A1, A2, 7, 9};   // defines pin number for segments A ~ G for tens digit
  int hnSeg = 13; // defines pin number for first digit (hundreds)
  // the segments array defines which segments should be lighted for each digit.
  // the x-axis [0~6] is the segment numbers (as defined above)
  // the y-axis [0~9] is the number you want to display, starting with "0" and ending with "9"
  // "0" = LOW = the output pin is sinking current (segment is lit)
  // "1" = HIGH = the output pin is NOT sinking current (segment is dark)
  boolean segments[10][7] = {
   { 0, 0, 0, 0, 0, 0, 1},
   { 1, 0, 0, 1, 1, 1, 1},
   { 0, 0, 1, 0, 0, 1, 0},
   { 0, 0, 0, 0, 1, 1, 0},
   { 1, 0, 0, 1, 1, 0, 0},
   { 0, 1, 0, 0, 1, 0, 0},
   { 0, 1, 0, 0, 0, 0, 0},
   { 0, 0, 0, 1, 1, 1, 1},
   { 0, 0, 0, 0, 0, 0, 0},
   { 0, 0, 0, 0, 1, 0, 0}
  };
  
void dispUnits(byte dispDigit)
{
  for (int seg = 1; seg < 7; seg++)
  {
    digitalWrite(tnSeg[seg], segments[dispDigit][seg]);
  }
}  // end of dispTens()

  
void dispTens(byte dispDigit)
{
  for (int seg = 0; seg < 7; seg++)
  {
    digitalWrite(unSeg[seg], segments[dispDigit][seg]);
  }
}  // end of dispUnits()

void setup() 
{
  int myPins[] = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, A0, A1, A2, A3 }; // defines all pins used by the display
  int pinCount = 16; // number of pins used for the display
  int thisPin;
  for (int thisPin = 0; thisPin < pinCount; thisPin++)  
  {
    pinMode(myPins[thisPin], OUTPUT); // sets pins used for display to output
  }
  pinMode(A5, INPUT); // sets sensor pin to input
  digitalWrite(A0, HIGH); // sets common anode to high
  Serial.begin(9600); // initializes serial port at 9600bps
}

void loop() 
{
  int rawValue = analogRead(A5); // the raw sensor value
  int sensorValue = map(rawValue, 0, 1023, 0, 199); // the sensor value mapped to the displayable range (0 - 199)
  int unitsDigit = sensorValue % 10; // calculates value from 0 to 9 to be displayed
  int tensDigit = ((sensorValue - unitsDigit) % 100) / 10; // calculates the tens value
  int hundredsOne = (sensorValue > 99); // detects if the value is higher than 99

  if (hundredsOne == 1) 
  {
    digitalWrite(hnSeg, LOW);  // lights on the first digit (1) of the display if the calculated value is higher than 99
  }
  
  else 
  {
    digitalWrite(hnSeg, HIGH); // turns off the first digit (1) of the display if the value is lower than 100
  }
  
  dispTens(tensDigit); // displays the tens
  dispUnits(unitsDigit); // displays the units

  // sends the raw value along with the calculated digits to the serial port

  Serial.print(rawValue, DEC);
  Serial.print("\t");
  Serial.print(hundredsOne);
  Serial.print("\t");
  Serial.print(tensDigit);
  Serial.print("\t");
  Serial.print(unitsDigit);
  Serial.print("\n");
  
  delay(50); // 50ms delay to prevent jittering of the display
}

Not bad for someone that's just started (with A LOT of help tho), huh? :wink:

Anyway, THANK YOU again, Richard, you helped me learn a lot of new stuff, beer is guaranteed :wink:

Cheers,

Seb

Thanks for the additional tips! Any well, neither I am a beer drinker, I just happen to live in one of those "beer countries" where a beer is regarded almost like money :wink:

Last night I successfully connected a Dallas DS18B20 temperature sensor to the Arduino/Display combo and now I have a working thermometer... It doesn't show decimals, but hey, it works :slight_smile:

I also found (yay!) the datasheet of the display, so later I'll publish the complete code I'll get after implementing your tips and perhaps a schematic... you never know, maybe it'll help someone later :slight_smile:

S.