Arduino code compiles but doesn't do anything - Page 1
Forum section: electronics / general

author: raspberrypi
author_rank: Frequent Contributor
timestamp: March 08, 2017, 10:36:09 pm
content: Shouldn't it flash the numbers on the seven segment display? Or "nixie tube" as the fucking liars at sain smart call it.Code:int a=7;int b=6;int c=5;int d=11;int e=10;int f=8;int g=9;int dp=4;//display number 1void digital_1(void){unsigned char j;digitalWrite(c,LOW);// pin5 low, light up cdigitalWrite(b,LOW);//light up bfor(j=7;j<=11;j++)//go out elsedigitalWrite(j,HIGH);digitalWrite(dp,HIGH);//go out decimal point dp}//display number2void digital_2(void){unsigned char j;digitalWrite(b,LOW);digitalWrite(a,LOW);for(j=9;j<=11;j++)digitalWrite(j,LOW);digitalWrite(dp,HIGH);digitalWrite(c,HIGH);digitalWrite(f,HIGH);}// display number3void digital_3(void){unsigned char j;digitalWrite(g,LOW);digitalWrite(d,LOW);for(j=5;j<=7;j++)digitalWrite(j,LOW);digitalWrite(dp,HIGH);digitalWrite(f,HIGH);digitalWrite(e,HIGH);}// display number4void digital_4(void){digitalWrite(c,LOW);digitalWrite(b,LOW);digitalWrite(f,LOW);digitalWrite(g,LOW);digitalWrite(dp,HIGH);digitalWrite(a,HIGH);digitalWrite(e,HIGH);digitalWrite(d,HIGH);}// display number5void digital_5(void){unsigned char j;for(j=7;j<=9;j++)digitalWrite(j,LOW);digitalWrite(c,LOW);digitalWrite(d,LOW);digitalWrite(dp,HIGH);digitalWrite(b,HIGH);digitalWrite(e,HIGH);}// display number6void digital_6(void){unsigned char j;for(j=7;j<=11;j++)digitalWrite(j,LOW);digitalWrite(c,LOW);digitalWrite(dp,HIGH);digitalWrite(b,HIGH);}// display number7void digital_7(void){unsigned char j;for(j=5;j<=7;j++)digitalWrite(j,LOW);digitalWrite(dp,HIGH);for(j=8;j<=11;j++)digitalWrite(j,HIGH);}// display number8void digital_8(void){unsigned char j;for(j=5;j<=11;j++)digitalWrite(j,LOW);digitalWrite(dp,HIGH);}void setup(){int i;//define ifor(i=4;i<=11;i++)pinMode(i,OUTPUT);//set pin4~pin11 output}void loop(){while(1){digital_1();//number 1delay(2000);//delay 2sdigital_2();delay(2000);digital_3();delay(2000);digital_4();delay(2000);digital_5();delay(2000);digital_6();delay(2000);digital_7();delay(2000);digital_8();delay(2000);}}

author: Avacee
author_rank: Unknown
timestamp: March 08, 2017, 10:49:13 pm
content: What are you getting? .. absolutely nothing?If so check whether your seven segment display is common anode (CA) or common cathode (CC) and is wired up correctly. You may have it "back-to-front" depending on the type.Also the segment mappings can vary (especially if you've got a cheapo chinese one! - ie A is not always the top one)If this is the case you can knock up a sketch that just puts out a LOW(CA) or HIGH(CC) onto one pin and use that to check all the combinations to determine the correct pin layout.As you aren't multiplexing check your resistor values are sufficiently high that when you show "8." (9 pins on) you aren't exceeding the current limit for an arduino.DC per pin = 40maDC TOTAL = 200ma .. so max 20ma for each LED - preferably a lot less so you are well within the maximum and don't stress either your arduino or the LEDs.ps. Excellent tutorial here:http://www.electronics-tutorials.ws/blog/7-segment-display-tutorial.html

author: amspire
author_rank: Super Contributor
timestamp: March 08, 2017, 11:06:31 pm
content: Definitely should work.As Avacee said it could be something to do with the way the display is wired up, or it could be the Arduino is not being programmed. Do you get the "Done Uploading" message?Just set pin 13 to be an output and stickdigitalWrite(13,!digitalRead(13));in the loop so it flashes the on board LED each time round the loop. Checks the loop is running

author: raspberrypi
author_rank: Frequent Contributor
timestamp: March 09, 2017, 12:27:09 am
content: So it is lighting up a little bit. I have a 220 Ohm resistor. I thought that was to limit current like an LED. Or does it pull down/up the voltage.The segments do light up but in a strange pattern checked the wiring twice but this tutorial has been wrong on other projects. When the dot is lit up by itself it seems like a normal brightness. Should I try plugging it into the +5v pin instead? Are those rails always on? It being powered via USB like I always do. I have done multiple LEDs that were blindingly bright

author: raspberrypi
author_rank: Frequent Contributor
timestamp: March 09, 2017, 12:33:14 am
content: It doesn't come on at all on the +5 pin, and I tried two different 7seg displays from the same kit.What happens if I lower or raise the resistor? Resistor is in series with the +3.3V. Shouldnt it light up brighter on the 5V pin? Or does the arduino have to turn it on?

author: raspberrypi
author_rank: Frequent Contributor
timestamp: March 09, 2017, 12:46:16 am
content: So my math say the resistor should be 866.3.3- 2v drop/0.0015A = 866.220 ohms would be for 5V.So maybe its too low? Is the resistor pulling current or is it limiting it?

author: amspire
author_rank: Super Contributor
timestamp: March 09, 2017, 12:57:54 am
content: Not sure what sort of display you have - they can be common anode or common cathode.If it is common anode, then the common connection goes to +5v and each of the segment pins connects via a resistor (220 ohms should be plenty to make it visible) to each of the Arduino outputs - 7 resistors plus one for the decimal point if you want it.For common cathode displays, the common pin goes to 0v and you pull up each segment pin via 220 ohms and you have to invert your outputs in the code.The most common displays are the common anode.

author: raspberrypi
author_rank: Frequent Contributor
timestamp: March 09, 2017, 01:03:52 am
content: 390ohms and no change. Is my arduino tired or being lazy? I just have one resistor on the +3.3Volts like in the instructions. Is this wrong?

author: Nusa
author_rank: Super Contributor
timestamp: March 09, 2017, 01:09:39 am
content: Quote from: raspberrypi on March 09, 2017, 12:46:16 amWrong direction. If 220 Ohms is correct for 5V, then 150 Ohms would be about right for 3.3V.I suspect you converted milliAmps to Amps incorrectly. 1000mA to the A, so 15mA = 0.015AResistors always limit current. That's what they do!

author: amspire
author_rank: Super Contributor
timestamp: March 09, 2017, 01:11:18 am
content: Quote from: raspberrypi on March 09, 2017, 01:03:52 amIt would work - sort of - but it is the wrong way to do it. Each segment should have its own resistor. Using a single resistor means the brightness will change with the number of segments on, and some segments will be dimmer then other segments.The first thing is to work out if it is a common anode or common cathode display. Connect a resistor (390 ohms is fine) to a segment output. Apply 5v between the resistor and the common pin. If the segment goes on when the resistor is at 0V it is common anode. If it comes on when the resistor is connected to the 5v, it is common cathode.

author: raspberrypi
author_rank: Frequent Contributor
timestamp: March 09, 2017, 01:53:02 am
content: Quote from: amspire on March 09, 2017, 01:11:18 amCommon anode because the 3.3v goes to one pin, and the rest to the digital pins. So at 3.3v I should connect the 3.3 directly to the display and connect 180ohm resistor to each segment? It does differ in brightness with each cycle or digit its trying to display. My disdain for sainsmart grows more and more. People are supposed to learn from this stupid thing? Going to try this and hope the arduino doesnt blow up.Thats my biggest hurdle to learning this thing, I not quite sure how much abuse it can handle or even what is bad for it. So im hesitant to just start messing about with it. $35 is not alot but way more risk then blowing up a 2 cent transistor or led.

author: raspberrypi
author_rank: Frequent Contributor
timestamp: March 09, 2017, 02:18:37 am
content: I think I should smash this thing. I have a 180 resistor to each segment and 3.3v to the vcc. Why does this not work at all when I connect it to the 5v pin? Do I have to tell the arduino to turn on the 5v pin? Seems like it would always be on.EDIT:I just tried hooking one of these displays up to 3.3 volts and it didnt work, so I switched the minus to the center and the plus to the segments. Lights up nice and bright. The idiots put the wrong parts in the kit.How do I change the code to handle this? Do I plug the Vcc to ground now?I was wondering why it was lighting up all though?

author: alsetalokin4017
author_rank: Super Contributor
timestamp: March 09, 2017, 02:51:17 am
content: Quote from: raspberrypi on March 09, 2017, 12:46:16 amOK, let's back up a little here. You've misplaced your decimal point in your current value. If you want 15 mA at 3.3v, your math should be 3.3-2 = 1.3, and 1.3/0.015=87ohmsand for 5 v, you have 5-2=3, and 3/0.015=200ohms.So if you are using 866 you are definitely using too high a resistor value. How did you get 220 ohms for 5V using your math? It should work OK with 220 ohms and 5V, but definitely NOT with 866 ohms and 3V. Sanity check time! How could you need a smaller resistor value with 5V than you get for 3.3V?Next, please tell us the exact part number of your 7-segment display. I just happen to have in front of me a "random number generator" using an Arduino and a 7 segment display, of the common cathode type. It is wired like this: Arduino digital output pin > 220R resistor > one segment of display. Repeat for each segment. Common of display to GROUND.No, you do not have to tell the Arduino to turn on the 5V pin, it is always connected to the output of the built-in voltage regulator. You should be able to confirm that there is always 5V present on this pin using your DMM. There is something else going on here. We need to confirm whether your display is common cathode or common anode, and I'm not sure your testing has actually determined that yet. So please report the part number of your 7-segment display. If you don't have a part number or we can't find a data sheet, then we need to test the display to see if it is CC or CA.To test if it is CC or CA, you should be able to use the DIODE CHECK function of your DMM just as if you were checking an LED or diode. Connect the BLACK lead (-) of the DMM to the Common pin of the 7-seg display. Connect the RED lead (+) of the DMM to one of the segment leads. Do you see an indication on the DMM, or does it indicate open? If you get a voltage reading or see the segment light up, then you have a common CATHODE display.

author: alsetalokin4017
author_rank: Super Contributor
timestamp: March 09, 2017, 03:00:49 am
content: I just tried your code on my setup, and it works fine. (My pin assignments to segments are different than yours so I don't get the 8 numbers, I get different segments lighting up, but that's not a problem.)You do not need to change anything in your code.Wire the segments like I said above, using 220 or 200 ohm resistors for each segment and the common to GROUND, and it should work.(Sorry, I think you will need to change your code a little bit, instead of writing LOW to a pin to turn a segment on , you need to write HIGH to the pin to turn it on.)Here's my random number generator code if you want to play with it. Note that my pin assignments > segments are different than yours, and also see how I've implemented the different numbers using "if" statements rather than functions.Code:// TKsNew7Seg Random Number Generatorint randno = 0;void setup() {pinMode(7, OUTPUT); // segment apinMode(6, OUTPUT); // segment bpinMode(12, OUTPUT); // segment cpinMode(11, OUTPUT); // segment dpinMode(10, OUTPUT); // segment epinMode(8, OUTPUT); // segment fpinMode(9, OUTPUT); // segment gpinMode(A0, OUTPUT); // segment dotdigitalWrite(A0, 0); // start with the "dot" offrandomSeed(analogRead(A4));}void loop() {randno = random(0,10);// write '9'if (randno == 9) {digitalWrite(7, 1);digitalWrite(6, 1);digitalWrite(12, 1);digitalWrite(11, 0);digitalWrite(10, 0);digitalWrite(8, 1);digitalWrite(9, 1);delay(1000);}if (randno == 8) {// write '8'digitalWrite(7, 1);digitalWrite(6, 1);digitalWrite(12, 1);digitalWrite(11, 1);digitalWrite(10, 1);digitalWrite(8, 1);digitalWrite(9, 1);delay(1000);}if (randno == 7) {// write '7'digitalWrite(7, 1);digitalWrite(6, 1);digitalWrite(12, 1);digitalWrite(11, 0);digitalWrite(10, 0);digitalWrite(8, 0);digitalWrite(9, 0);delay(1000);}if (randno == 6) {// write '6'digitalWrite(7, 1);digitalWrite(6, 0);digitalWrite(12, 1);digitalWrite(11, 1);digitalWrite(10, 1);digitalWrite(8, 1);digitalWrite(9, 1);delay(1000);}if (randno == 5) {// write '5'digitalWrite(7, 1);digitalWrite(6, 0);digitalWrite(12, 1);digitalWrite(11, 1);digitalWrite(10, 0);digitalWrite(8, 1);digitalWrite(9, 1);delay(1000);}if (randno == 4) {// write '4'digitalWrite(7, 0);digitalWrite(6, 1);digitalWrite(12, 1);digitalWrite(11, 0);digitalWrite(10, 0);digitalWrite(8, 1);digitalWrite(9, 1);delay(1000);}if (randno == 3) {// write '3'digitalWrite(7, 1);digitalWrite(6, 1);digitalWrite(12, 1);digitalWrite(11, 1);digitalWrite(10, 0);digitalWrite(8, 0);digitalWrite(9, 1);delay(1000);}if (randno == 2) {// write '2'digitalWrite(7, 1);digitalWrite(6, 1);digitalWrite(12, 0);digitalWrite(11, 1);digitalWrite(10, 1);digitalWrite(8, 0);digitalWrite(9, 1);delay(1000);}if (randno == 1) {// write '1'digitalWrite(7, 0);digitalWrite(6, 1);digitalWrite(12, 1);digitalWrite(11, 0);digitalWrite(10, 0);digitalWrite(8, 0);digitalWrite(9, 0);delay(1000);}if (randno == 0) {// write '0'digitalWrite(7, 1);digitalWrite(6, 1);digitalWrite(12, 1);digitalWrite(11, 1);digitalWrite(10, 1);digitalWrite(8, 1);digitalWrite(9, 0);delay(1000);}digitalWrite(7, 0);digitalWrite(6, 0);digitalWrite(12, 0);digitalWrite(11, 0);digitalWrite(10, 0);digitalWrite(8, 0);digitalWrite(9, 0);delay(100);while (randno > 0, randno--) {digitalWrite (A0, HIGH);delay (100);digitalWrite (A0, LOW);delay(100);}}

author: alsetalokin4017
author_rank: Super Contributor
timestamp: March 09, 2017, 04:10:11 am
content: Here, I've taken the liberty of fixing your code so it should work for you with Common Cathode display. Use a 220 or 200 ohm resistor for each segment:Arduino pin > 220R > display segment, and display Common to GROUND.All I really did was to change the "HIGH"s to "LOW"s and vice-versa. And I added a line of code to fix one segment that wasn't turning on right for one of the numbers. Something to do with the "for" loops that are rather confusing. See my code above for a somewhat clearer way of turning segments on/off for each number.Code:/*RaspberryPi's Arduino Sketch modified for Common Cathode 7-segmentdisplayfor Common Anode, write LOW to turn a segment ON, HIGH for OFFfor Common Cathode write HIGH to turn a segment ON, LOW for OFF*//* Al's pin mappings:int a=7;int b=6;int c=12;int d=11;int e=10;int f=8;int g=9;int dp=A0;*/// raspberrypi's pin mappings:int a=7;int b=6;int c=5;int d=11;int e=10;int f=8;int g=9;int dp=4;// for Common Anode, write LOW to turn a segment ON, HIGH for OFF// for Common Cathode write HIGH to turn a segment ON, LOW for OFF//display number 1void digital_1(void){unsigned char j;// digitalWrite(c,LOW);// pin5 low, light up cdigitalWrite(c,HIGH);// pin5 high, light up c// digitalWrite(b,LOW);//light up bdigitalWrite(b,HIGH);//light up bfor(j=7;j<=11;j++)//go out else// digitalWrite(j,HIGH);digitalWrite(j,LOW);// digitalWrite(dp,HIGH);//go out decimal point dpdigitalWrite(dp,LOW);//go out decimal point dp}//display number2void digital_2(void){unsigned char j;digitalWrite(b,HIGH);digitalWrite(a,HIGH);for(j=9;j<=12;j++)digitalWrite(j,HIGH);digitalWrite(dp,LOW);digitalWrite(c,LOW);digitalWrite(f,LOW);}// display number3void digital_3(void){unsigned char j;digitalWrite(g,HIGH);digitalWrite(d,HIGH);for(j=5;j<=7;j++)digitalWrite(j,HIGH);digitalWrite(dp,LOW);digitalWrite(f,LOW);digitalWrite(e,LOW);digitalWrite(c,HIGH);}// display number4void digital_4(void){digitalWrite(c,HIGH);digitalWrite(b,HIGH);digitalWrite(f,HIGH);digitalWrite(g,HIGH);digitalWrite(dp,LOW);digitalWrite(a,LOW);digitalWrite(e,LOW);digitalWrite(d,LOW);}// display number5void digital_5(void){unsigned char j;for(j=7;j<=9;j++)digitalWrite(j,HIGH);digitalWrite(c,HIGH);digitalWrite(d,HIGH);digitalWrite(dp,LOW);digitalWrite(b,LOW);digitalWrite(e,LOW);}// display number6void digital_6(void){unsigned char j;for(j=7;j<=11;j++)digitalWrite(j,HIGH);digitalWrite(c,HIGH);digitalWrite(dp,LOW);digitalWrite(b,LOW);}// display number7void digital_7(void){unsigned char j;for(j=5;j<=7;j++)digitalWrite(j,HIGH);digitalWrite(dp,LOW);for(j=8;j<=11;j++)digitalWrite(j,LOW);}// display number8void digital_8(void){unsigned char j;for(j=5;j<=11;j++)digitalWrite(j,HIGH);digitalWrite(dp,LOW);}void setup(){int i;//define ifor(i=4;i<=12;i++)pinMode(i,OUTPUT);//set pin4~pin12 output}void loop(){while(1){digital_1();//number 1delay(2000);//delay 2sdigital_2();delay(2000);digital_3();delay(2000);digital_4();delay(2000);digital_5();delay(2000);digital_6();delay(2000);digital_7();delay(2000);digital_8();delay(2000);}}

author: Ian.M
author_rank: Super Contributor
timestamp: March 09, 2017, 04:43:25 am
content: One shouldn't 'bake' the pin levels into your code for stuff you want to reuse with different types of LED or possibly with external inverting drivers.If you #define the levels you only have to change them in one place in the code.e.g.:Code:// Common Anode#define SEG_ON LOW#define SEG_OFF HIGH#define DIG_ON HIGH#define DIG_OFF LOWorCode://Common Cathode#define SEG_ON HIGH#define SEG_OFF LOW#define DIG_ON LOW#define DIG_OFF HIGHCode:// Common Anode with high side inverting drivers#define SEG_ON LOW#define SEG_OFF HIGH#define DIG_ON LOW#define DIG_OFF HIGHand then use DIG_.... for the levels in the multiplexing routine and SEG_.... for the levels when outputting the segment pattern, it becomes absolutely trivial to swap display types.Also for %DEITY%'s sake name the pins by #defining SEG_A through SEG_G and SEG_DP as the pin numbers for each, and (assuming one I/O per digit for the multiplexing) the digit pins DIG_1through however many digits you have. For now with only a single non-multiplexed digit simply connect the common to the appropriate rail and dont boither with #defining anu DIG_.... symbols.N.B. #defines apply to the rest of the file (unless explicitly undefined) so they *MUST* be on a line somewhere above where you need to use them. Its usual to gather the #defines for your project's hardware configuration together into a header file called something like "project.h" then #include it as required.

author: alsetalokin4017
author_rank: Super Contributor
timestamp: March 09, 2017, 05:00:47 am
content: You are of course correct, but let's not try to make an omelet before we've learned how to break eggs.

author: raspberrypi
author_rank: Frequent Contributor
timestamp: March 09, 2017, 05:50:09 am
content: Quote from: alsetalokin4017 on March 09, 2017, 02:51:17 amI think you missed this part:Quote

author: Ian.M
author_rank: Super Contributor
timestamp: March 09, 2017, 05:53:11 am
content: Quote from: alsetalokin4017 on March 09, 2017, 05:00:47 amTrue, but its actually easier to understand once you get in the habit of using #defined names.Code:digitalWrite(SEG_G,SEG_ON);is self-documenting.Code:digitalWrite(9,0);is not and is a PITA to understand what it does if you come back to it a couple of weeks later.

author: raspberrypi
author_rank: Frequent Contributor
timestamp: March 09, 2017, 09:16:32 pm
content: So turn all the lows to highs and vice versa in the code to get it to work and switch the 3.3v pin to gnd ? I really appreciate the effort in the replies, but I copied and pasted this code as I'm still not at the point to write it. I almost understand the code but I'm missing something. Basically I just do trial and error as I till haven't found a good resource that explains these codes line by line.

author: Avacee
author_rank: Unknown
timestamp: March 09, 2017, 11:46:17 pm
content: What's the state on this - did you get it working?

author: alsetalokin4017
author_rank: Super Contributor
timestamp: March 10, 2017, 01:00:28 am
content: Quote from: raspberrypi on March 09, 2017, 09:16:32 pmMostly. There is some complication in your originally posted code due to the use of the "for" loops in the digit function definitions, but don't worry about that right now.First, wire your 7-segment Common Cathode display as mentioned above: Each Arduino output pin > 220R resistor > corresponding display segment, and the display Common to GROUND. So you will need 8 resistors, one for each segment and one for the dot.Next, copy-paste the altered code I listed above into your Arduino IDE and upload it to the Arduino. Observe and report what happens. Compare the original sketch with my alterations to see just exactly what I've changed, which is _mostly_ just replacing "HIGH" with "LOW" and vice versa.The thing is the code sketch was originally written for Common Anode display, so turning an output pin LOW is how it turns the segment ON, using the 3.3 or 5 V supply to source the current and sinking into the Arduino pin when it is LOW.But since you have a Common Cathode display, you need to turn an output pin HIGH to turn the segment on, and the pin sources the necessary current and sinks to the Arduino Ground.Now, if something doesn't work right, like a wrong segment lighting or one failing to light, you can go through the code and use your trial-and-error to correct the problem.If you have some code that you don't understand, ask here! Or look up specific commands on the Arduino.cc website reference pages (type "Arduino xxxx" into Google, where "xxxx" is the command or statement or function you need help with). You can start with the simplest sketch examples in the "Basic" section of the IDE examples, and change a little bit here and there to see what the effect is. By the time you've worked through the examples you will have a much greater understanding of how to write your own sketch and get it to perform as desired. (An old programming joke is that every new program starts from the old basic "Hello World" and is just copy-pasted bits and pieces from other programs until yours does what you need it to do.)The suggestions about using #define statements and more descriptive variable names made by Ian.M are (slightly) more sophisticated and would make your code more portable and easier to change pin assignments and to switch from CC to CA displays and illustrate good programming techniques.But the simplest way to alter your original sketch to work with the display you are using is to start by wiring the display correctly and changing the "HIGH"s to "LOW"s and vice-versa.

author: raspberrypi
author_rank: Frequent Contributor
timestamp: March 10, 2017, 03:22:40 am
content: I made another thread in case someone else need to search this site. With some more questions in it.So I added a "nine" to the code and it worked but I don't think it was done properly.Oops I deleted the link to the new thread, but anyway its in this same sub forum.

author: Ian.M
author_rank: Super Contributor
timestamp: March 10, 2017, 03:33:53 am
content: Quote from: raspberrypi on March 09, 2017, 09:16:32 pmGood code shouldn't need explaining line by line - one comment every five or ten lines should be sufficient, + a block comment explaining the parameters and purpose for each function.OTOH crap code can still be difficult for an experienced programmer to understand with a comment on each line. The comments frequently add to the confusion, as if a programmer is too stupid and lazy to learn how to write better code, they are usually also too lazy to keep the comments up to date when they change the code. You *CANNOT* learn to program effectively by copying a stupid+lazy programmer.Also, I believe that beginners should be introduced to good coding patterns like named constants in place of'magic numbers'and abstraction and looping in place of repetition ('Rule of three') as soon as possible - certainly by the time they've played with the basic example sketches and learnt about the C for loop.One of the things I dislike about the Arduino libraries is that they hide the fact that the MCU's I/O pins are actually grouped into ports. If you are using another MCU the first step would be to find 7 pins for your segment lines, ideally all in sequence on the same port. Then you'd code a bit pattern for each digit you need to display, and write code to transfer that bit pattern from an array, directly to the port the segment lines are on. It would be possible to split the lines across more than one port, but there is a strong disincentive to do so, because separating out the bits from the segment pattern and rearranging them to match the port bits the segment lines are actually hooked to, wastes code space and processing time.Another thing I don't like about Arduinos is the tendency to use integer variables for named numeric constants. If your widgit is on pin 7, the name you refer to it by should be a constant, as the pin cant be changed without rewiring, and ideally it should be a literal constant (#define or enum) so the compiler can better optimise it.Given the limitations of the Arduino HAL, here's how I'd code it to maximise the amount of it I can reuse if I want to add more digits with multiplexing, or use a starburst display to support text.Edit: Fixed stupid bug that killed it dead.See reply#30. Many thanks to alsetalokin4017 for testing it on real hardware and the bug report.Code://Pin mappings for segments in order: abcdefg dpconst char SegPin[]={7,6,5,11,10,8,9,4};//Display type, (uncomment one only)enum {SEG_OFF=0,SEG_ON}; // Common Cathode//enum {SEG_ON=0,SEG_OFF}; // Common Anode//Map segment names to position in SegPinenum {SEG_A=0,SEG_B,SEG_C,SEG_D,SEG_E,SEG_F,SEG_G,SEG_DP};typedef unsigned char segbit_t; //Change this for displays// with more than 8 segments, and provide a new font array.// C source for 7 segment HEX font// Bit patterns entered in normal// segment order: abcdefgconst segbit_t Seg7font[]={0b1111110, // '0'0b0110000, // '1'0b1101101, // '2'0b1111001, // '3'0b0110011, // '4'0b1011011, // '5'0b1011111, // '6'0b1110000, // '7'0b1111111, // '8'0b1110011, // '9'0b1110111, // 'A'0b0011111, // 'B'0b1001110, // 'C'0b0111101, // 'D'0b1001111, // 'E'0b1000111, // 'F'0b0000000 // blank};// End Fontenum {NSEGS=sizeof(SegPin)/sizeof(SegPin)}; // Because the// Arduino IDE mangles sizeof() if I use it directly in a functionenum {SEGAMASK=0b1000000}; // mask for first segment bitenum {BLANK=16}; // Must match index of blank in font array/********************************** init7seg: Set all segment pins ** as outputs and turn them off. **********************************/void init7seg(void){for(char i=0; i<NSEGS; i++) {digitalWrite(SegPin,SEG_OFF);pinMode(SegPin,OUTPUT);}}/************************************* write7seg(n): Outputs the segment ** pattern for n to the display. n's ** range is 0 to 15, for 0-9, A-F ** or BLANK for display off. *************************************/// Hardcoded unrolled 7 segment versionvoid write7seg(char n){// Bitwise black magic to extract a segment bit from// a font pattern to simplify the unrolled loop.// 0x40 is the bitmask for segment a, b is 1 bit lower etc.#define SEGBIT(pattern,bn) ((pattern&(SEGAMASK>>bn))?SEG_ON:SEG_OFF)// and to simplify outputting the bits#define OUTSEG(s) digitalWrite(SegPin,SEGBIT(Seg7font,s))// Finally output segments a-gOUTSEG(SEG_A);OUTSEG(SEG_B);OUTSEG(SEG_C);OUTSEG(SEG_D);OUTSEG(SEG_E);OUTSEG(SEG_F);OUTSEG(SEG_G);}// Finished with the macros#undef SEGBIT#undef OUTSEG/* --- commented out ---// Slow but easier to understand loop versionvoid write7seg(char n){segbit_t mask=SEGAMASK;for(char s=SEG_A; s<=SEG_G; s++){// Extract a segment bit from the font for character nif(Seg7font&mask){// and output it to the corresponding pindigitalWrite(SegPin,SEG_ON);}else{digitalWrite(SegPin,SEG_OFF);}mask>>=1; // Shift to next segment position}}--- end comment out --- */// No main() we are in Arduino-land :(/***************** Arduino setup ******************/void setup(void){init7seg();}/**************** Arduino loop *****************/void loop(void){// Display numbers 1-8for(char i=1; i<=8; i++){write7seg(i);delay(2000); // for two seconds each.}}I've checked it compiles OKbut haven'tand have nowtested it on actual hardware.I'm using enums where I would normally use #defines, because I need a lot of consecutive numeric constants. The two #defines in the unrolled version of write7seg() are to give the compiler the best possible chance of optimising the segment output routine to a simple sequence of calls to digitalWrite()a single bit (SEG_ON or SEG_OFF) to a fixed pin.N.B. I am a C programmer. not a C++ one though I can 'hum the tune' if I have to. On a small 8 bit MCU, you have to be very aware of how much work the processor is going to have to do to execute a particular line of code or how much space a definition will use up.An experienced desktop C++ programmer would think my code stinks, but when considered as embedded C its actually fairly clean.

author: Ian.M
author_rank: Super Contributor
timestamp: March 10, 2017, 03:47:54 am
content: Quote from: raspberrypi on March 10, 2017, 03:22:40 amThat actually makes it worse for anyone searching the site because they are unlikely to find all the topics you have made about different pieces of the same problem. IMHO its best not to start a new topic unless you have started a new project or there is some other clear and total break from the subject of the previous topic.Your new topic is:https://www.eevblog.com/forum/microcontrollers/seven-seg-disp-program-for-arduino-how-to/The code I just posted should handle adding '9' (or even 'A'-'F') easily - just edit the for loop in loop() to let it count higher.e.g.Code:for(char i=1; i<=9; i++){Its probably easier to continue the discussion here . . .

author: raspberrypi
author_rank: Frequent Contributor
timestamp: March 10, 2017, 04:27:45 am
content: Quote from: Ian.M on March 10, 2017, 03:47:54 amIt seems like you guys think I know more then I actually do. I had no idea what "C" was (other then it was computer programing language) until the day before yesterday, so when I read your posts I have to have google and wikipedia open to figure out what you are talking about, incredibly challenging which is good, but almost to the point where its seems overwhelming. I thought the arduino IDE code was something just for playing with the arduino. I learn fast but not that fast! So I have no idea what that syntax means besides ; is like a period.

author: Ian.M
author_rank: Super Contributor
timestamp: March 10, 2017, 04:41:39 am
content: Let me throw a link at you: A free online book introducing C. It assumes you have *some* programming experience in another high level procedural language.'The C Book'(2nd ed.) by Mike Banahan, Declan Brady and Mark DoranIt covers C89 which is fairly close to C99 which is for most purposes a subset of C++ which underlies the Arduino programming language. The only C99'ism I have used above is declaring loop variables at point of use inside the for() statement. Everything else is covered in 'The C Book' or in thereference sectionof the official Arduino site.Subject to time constraints, I am quite happy to answer questions about my code, line by line or even expression by expression.

author: alsetalokin4017
author_rank: Super Contributor
timestamp: March 10, 2017, 06:01:21 am
content: Quote from: Ian.M on March 10, 2017, 03:33:53 amSorry... but your code doesn't actually work (for me). I've got the hardware setup as described using Arduino ProMini and CC display, and both the OP's original code (modified for CC display and my own pin mappings) and the random number generator code I posted earlier DO work on my hardware, but your code doesn't. Yes, I've inserted my own pin mappings. Your code very very dimly lights up two segments of the display (e and f I think) and just sits there for several seconds, then goes out for a brief time then relights, very very dimly, the same two segments.Let's face it: your code shows some sophisticated programming, but it is pitched way higher than the OP is ready to absorb. Plus... it doesn't work. And from my own rudimentary level of programming (I did get the joke about the best FORTRAN programs written after dropping the stack of cards) I can't figure out why it doesn't or how to change it so that it does.Some people might take the position that "crap" code that works is actually better than sophisticated "proper" code that doesn't work.

author: Ian.M
author_rank: Super Contributor
timestamp: March 10, 2017, 06:22:45 am
content: Quote from: alsetalokin4017 on March 10, 2017, 06:01:21 amThanks for running it on real hardware. You are right that working code is better than apparently elegant but broken code. It looks like I'll have to grab an Arduino and a breadboard and dig into it and fix it nowWhile you've got it set up, if you've got the time, please try commenting out the hardcoded unrolled version of write7seg() and uncommenting the slow loop version as the odds are fairly high I've FUBARed the unrolled version.

author: alsetalokin4017
author_rank: Super Contributor
timestamp: March 10, 2017, 07:34:02 am
content: I'll try, but it's past my bedtime so I may not get to it until tomorrow.Thanks for your advice and patience; I'm "not a programmer" nor do I play one on TV. I learned that I am not a programmer when my computer science teacher way back in the IBM 360 day took a 150 card FORTRAN program I had written and wrote a one-line APL function that did the same thing.

author: Ian.M
author_rank: Super Contributor
timestamp: March 10, 2017, 08:45:24 am
content: Scrap that request. It was a bad use of PROGMEM. Delete the whole line:Code:#include <avr/pgmspace.h> // for PROGMEMand the keywordPROGMEMfrom the pinmapping line:Code:const PROGMEM char SegPin[]={7,6,5,11,10,8,9,4};and also from the 'font' line:Code:const PROGMEM segbit_t Seg7font[]={I'm too used to Microchip's C18 where the ROM qualifier works the way I thought PROGMEM did, and XC8 where const is overloaded to mean ROM.Apparently you have to use special macros under AVR GCC to fetch data from PROGMEM so my code was using garbage pin numbers and segment patterns.After the above fix, I've tested it on a genuine Uno with the O.P.s original pin mapping to a LTS7760R single digit common cathode display (with 330R resistors in each segment line) and it now works flawlessly. I also tested the commented out loop version.I'm correcting the original post to avoid confusion.Edit: Replaced attached sketch. Removed some debug printf() statements from the commented out loop version of write7seg(). Changed to use #if 1 or #if 0 instead of commenting out code.--'Air Code' is the programmer's equivalent of 'Air Guitar' but is a *LOT* more embarrassing;-)

author: alsetalokin4017
author_rank: Super Contributor
timestamp: March 10, 2017, 03:15:08 pm
content: Yes, that fixed it here too (Chinese ProMini clone w/ optiboot). Thanks for revising!

author: rstofer
author_rank: Super Contributor
timestamp: March 10, 2017, 04:08:52 pm
content: Quote from: alsetalokin4017 on March 10, 2017, 07:34:02 amAPL was amazing for those who could wrap their head around it. OTOH, Fortran is still alive and well!

author: Ian.M
author_rank: Super Contributor
timestamp: March 10, 2017, 05:10:52 pm
content: AAgHH!!! the pain of using Arduino Serial.print(whatever) for debuggingIt takes FOUR statements to display two labelled variables on the same line!Code:Serial.print("A="); Serial.print(a,DEC); Serial.print(" B="); Serial.println(b,BIN);WTF were the Arduino software guys thinking when they left out printf()?To find the above bug, I ended up wrapping the header for the raw AVR serial stdio stream code I wrote a few days ago inextern "C" {....};just so I could use printf() for debugging.

author: bingo600
author_rank: Super Contributor
timestamp: March 10, 2017, 06:26:14 pm
content: Quote from: Ian.M on March 10, 2017, 05:10:52 pmJust use sprintf , and "Arduino print" the resulting string/Bingo

author: sleemanj
author_rank: Super Contributor
timestamp: March 11, 2017, 08:57:38 am
content: Quote from: Ian.M on March 10, 2017, 05:10:52 pmThey were thinking that bringing in printf means an absolute ton of code on a flash and ram limited device so it's better not to promote it's use :-)As above, sprintf (or better snprintf) is in the standard avr libc (as is printf for that matter, but what they define as "stdout" I have no idea), so feel free to use it to format your string, if you have the room to spare.

author: Ian.M
author_rank: Super Contributor
timestamp: March 11, 2017, 10:10:41 am
content: Quote from: sleemanj on March 11, 2017, 08:57:38 amThe lightweightstream.print() andstream.println() methods are of course the preferred option for your application code, - and explicitly managing the buffer for snprintf() if you use it is the sane thing to do, - but rather than discouraging use by making it incredibly difficult to add a printf() method cleanly to the serial class, IMHO they should have provided it but tagged with __attribute__((deprecated)) so it raises a warning if used.Quote from: sleemanj on March 11, 2017, 08:57:38 amAvr libc doesn't initialise the stdio streams - fair enough on an embedded system as there's no knowing what peripheral they should be connected to - so you have to set them up yourself. That was fairly easy to my quick&dirty blocking UART putchar() and getchar(), but getting them hooked cleanly to an Arduino I/O stream class is a little trickier.