Arduino programming?

Advert

Arduino programming?

Home Forums General Questions Arduino programming?

Viewing 21 posts - 26 through 46 (of 46 total)
  • Author
    Posts
  • #510048
    duncan webster 1
    Participant
      @duncanwebster1

      This is probably rubbish but here goes:

      Has Malc actually told us what display he's using? It appears from the code that all 4 digits light up with the same character by just setting the pins 2-9. Is it perhaps a display which has 4 inputs to select which digit is to be driven? If it is then what you have to light up the digits in turn with 25% mark space ratio. There may well be a library to do this for you, when I last did it on a PIC I used someone else's code, but I think the flicker rate is too fast and the brightness is not what it could be.

      Advert
      #510050
      Malc
      Participant
        @malc

        Hi Duncan, the display I am using is a 4×7 segment common cathode type (Proto-pic part No. COM-10145). The Arduino pins 10,11, 12, 13 are connected to the D1, D2, D3, D4 cathodes of the 4 digits. The remaining 8 segments are connected to the Arduino pins 2, 3, 4, 5, 6, 7, 8 & 9. All 4 segments do light up at once in the sequence 0000, 1111, 2222, 3333……..etc. and then continually repeat. This is exactly what I wanted but in the interests of learning more about programming I am trying to improve the sketch

        #510059
        duncan webster 1
        Participant
          @duncanwebster1

          I can't find that part on proto pic website. I can't see in the code where you set the level of 10, 11, 12, 13. The default state is LOW, so I'm presuming that the display is common anode. Your potentially driving 28 LEDs (8888) off the Arduino all at once, which might be close to the limit for output pins (100mA total).

          I think this library will do it for you 7 seg but I've not fully read it yet. What you then do is turn pins 10, 11, 12, 13 on and off in sequence to flash the individual characters, do it fast enough and they appear to be all on at the same time.

          If you want to do the heavy lifting yourself, as long as you are not using serial comms, you can use pins 0 to 7 (actually 0 to 6 in this case), which makes life easier as pins 0 – 7 are PORTD, and you can set all these pins with one command. PORTD = 0B00111111 will set pins 0 to 6 HIGH and pins 6&7 LOW. This displays '0'. All described at port manip

          #510061
          Malc
          Participant
            @malc

            Thanks Duncan, that looks like a quest for tomorrow.

            #510064
            duncan webster 1
            Participant
              @duncanwebster1

              I think I meant common cathode!

              #510067
              SillyOldDuffer
              Moderator
                @sillyoldduffer

                Congratulations to Malc:

                • For getting his program to drive the LEDs correctly (a major milestone!)
                • For writing code that's easy to understand. (Rule 1 of programming: Don't leave the reader in the dust!)
                • For recognising 200 lines can probably be compressed and asking advice

                I've not tested my version on a real LED so the code is probably buggy, but as an example of a couple of reducing techniques I offer this.

                segs1.jpg

                seg2.jpg

                First trick is to use names rather than numbers in hope the code will be easy to understand in two weeks time, or if some other poor S.O.D. has to debug it.

                Second, use a loop. In this example a for loop in setup() sets all the output pins one after the other. The pin numbers happen to be in sequence making a loop easy to apply in this example, but variations of the the same technique can handle non-contiguous pin numbers (Slightly more advanced topic.)

                Third, put repeat operations into generalised functions. In this example, setSegments() turns all the LED segments on or off in any combination based on the coded number it's given, and then executes a delay() My example takes advantage of a 7 segment + dp display having 8 control states, which can all be contained in a single integer of type uint8_t (ie an unsigned 8 bit integer.) Also available if more bits are needed: uint16_t, uint32_t and uint64_t)

                The encoded command can be written in binary

                ABCDEFG.
                00000000 // All off
                11111111 // All on
                11111010 // All on apart from segment E and the decimal point

                So a bit set to zero, means 'turn the corresponding segment OFF' and the same bit set to 1 turns it on, (In the Arduino documentation, its explained LOW = 0 and HIGH = 1.) The bits are extracted, or decoded, from group by masking them with a logical and ( & ) , obeying this rule:

                0 & 0 = 0
                0 & 1 = 0
                1 & 0 = 0
                1 & 1 = 1

                So SEG_A & 0b1000000 = 1, ie HIGH while SEG_A & 0b01111111 = 0, ie LOW

                Fourth trick is to overload (technical term) the setSegment() function with a default delay. If 1000mS is wrong, the programmer can override it. So

                setSegment( 0xff, 10000 ); // turn all segments and DP ON and wait for 10 seconds

                Hope that makes some sense!

                Duncan makes a good point about libraries. The very best way to get results in programming is to let someone else to do the hard work! Typically an LED display library would handle several digits by chatting to a control chip, provide dimming, and fonts etc. But it's very educational to start as Malc has done by rolling your own.

                Dave

                Edit Pesky smileys.

                 

                Edited By SillyOldDuffer on 26/11/2020 21:10:53

                #510073
                Malc
                Participant
                  @malc

                  Many thanks to the two of you for all the effort. I’m going to work my way through all your info and see if my brain is up to it. You should have a bit of peace – it could take me a while. Thanks again, Malc.

                  #510097
                  duncan webster 1
                  Participant
                    @duncanwebster1

                    from the time on this posting you can tell it might be insomniac ramblings:

                    A somewhat more understandable way of doing what SOD suggests would be to define a set of one dimensional arrays

                    //int Ch_n[] = {a, b, c, d, e, f, g, dp}

                    int Ch_0[] = {1, 1, 1, 1, 1, 1, 0, 0};
                    int CH_1[] = {0, 1, 1, 0, 0, 0, 0, 0};

                    and so on to

                    int CH_dp[] = {0, 0, 0, 0, 0, 0, 0, 1};

                    int Ch_clear[] = {0, 0, 0, 0, 0 , 0, 0, 0}

                    and then

                    void setSegments(int Ch_n)
                    {
                    digitalWrite(seg_A, Ch_n[0];
                    digitalWrite(seg_B, Ch_n[1];

                    and so on to

                    digitalWrite(seg_dp, Ch_n[7];

                    and then in loop() call

                    setSegments(Ch_0);

                    or whichever you want to send

                     

                    don't forget you can also display A, b, C, d, E, F, H, J, L, S (same as 5), Y

                    No doubt SOD will put this right if I've erred.

                    Edited By duncan webster on 27/11/2020 03:51:40

                    Edited By duncan webster on 27/11/2020 03:52:33

                    Edited By duncan webster on 27/11/2020 03:55:12

                    Edited By duncan webster on 27/11/2020 03:55:46

                    Edited By duncan webster on 27/11/2020 03:56:13

                    #510098
                    duncan webster 1
                    Participant
                      @duncanwebster1

                      And does anyone know what the optimum flash rate would be? if working at 50 hZ it would be 20ms for all 4 digits, 5 ms on, 15ms off for each one.

                      #510108
                      Malc
                      Participant
                        @malc

                        Blimey Duncan, sorry if I kept you awake! Looks like I have a busy day ahead, thanks again.Malc.

                        #510110
                        Roger Hart
                        Participant
                          @rogerhart88496

                          Here is the approach I used. not original, pinched off the WEB. Can't remember where.

                          First a mapping from logical to hardware pin numbers. Then convert a number into an 8 bit wide pattern then bit bang the bit pattern. The convert number part gets around logical anding and testing a 32 bit integer.

                          // define pin Logical pin / Hardware pin
                          int pin0 = 0;
                          int pin1 = 1;
                          int pin2 = 2;
                          int pin3 = 3;
                          int pin4 = 5;
                          int pin5 = 6;
                          int pin6 = 7;
                          int pin7 = 8;

                          void Send_8_bit(int byt)
                          {
                          int d=0;
                          int binary[8] = {0,0,0,0,0,0,0,0};
                          {
                          //convert byt to bit pattern
                          while (byt>0)
                          {
                          binary[d] = byt%2;
                          byt = byt/2;
                          d++;
                          }
                          // write 8 bits to port pins
                          if (binary[0]==1) digitalWrite(pin0,HIGH);
                          else digitalWrite(pin0,LOW);
                          if (binary[1]==1) digitalWrite(pin1,HIGH);
                          else digitalWrite(pin1,LOW);
                          if (binary[2]==1) digitalWrite(pin2,HIGH);
                          else digitalWrite(pin2,LOW);
                          if (binary[3]==1) digitalWrite(pin3,HIGH);
                          else digitalWrite(pin3,LOW);
                          if (binary[4]==1) digitalWrite(pin4,HIGH);
                          else digitalWrite(pin4,LOW);
                          if (binary[5]==1) digitalWrite(pin5,HIGH);
                          else digitalWrite(pin5,LOW);
                          if (binary[6]==1) digitalWrite(pin6,HIGH);
                          else digitalWrite(pin6,LOW);
                          if (binary[7]==1) digitalWrite(pin7,HIGH);
                          else digitalWrite(pin7,LOW);
                          }
                          }

                          void setup() {
                          // set up 8 bit port
                          pinMode(pin0, OUTPUT);
                          pinMode(pin1, OUTPUT);
                          pinMode(pin2, OUTPUT);
                          pinMode(pin3, OUTPUT);
                          pinMode(pin4, OUTPUT);
                          pinMode(pin5, OUTPUT);
                          pinMode(pin6, OUTPUT);
                          pinMode(pin7, OUTPUT);
                          }

                          void loop() {
                          // put your main code here, to run repeatedly:

                          int byt;

                          byt = 0;

                          while (byt < 256)
                          {
                          Send_8_bit(byt);
                          byt++;
                          delay(50);
                          }
                          }

                          #510113
                          Malc
                          Participant
                            @malc

                            Looks like my days are getting busier. I intend to print out all the replies and code and then see if any of it sinks in, so it could be a while before you hear from me again. Thanks Roger and every one else. Malc.

                            #510130
                            SillyOldDuffer
                            Moderator
                              @sillyoldduffer

                              A few comments on Roger's version, not criticisms.

                              A disadvantage of using an array to hold the segment bits is the amount of memory used and the extra compute power needed to process it. Doesn't matter two hoots on a big computer or a small microcontroller program, but squeezing big programs on to a tiny microcontroller often demands economies.

                              In Roger's code the statement int binary[8] = {0,0,0,0,0,0,0,0}; allocates 16 bytes of memory, most of which isn't used, whereas

                              char binary[8] = {0,0,0,0,0,0,0,0}; // allocates 8 bytes of memory

                              Also, later compilers allow the shorthand:

                              int binary[8] = {0}; // Zero all 8 elements

                              Another common compression, Roger uses the form:

                              if (binary[0]==1) digitalWrite(pin0,HIGH);
                              else digitalWrite(pin0,LOW);

                              which can be simplified to:

                              digitalWrite( pin0, binary[0] ); // Saves a comparison and decision branch.

                              Malc's version takes up most space but is the easiest to understand. Roger's version saves space, but requires more effort to grasp. Mine may be the most efficient, but it's also the hardest to understand. This is why programming can be hard to learn: fairly clear what Roger's

                              if (binary[0]==1) digitalWrite(pin0,HIGH);
                              else digitalWrite(pin0,LOW);

                              does, whereas digitalWrite( pin0, binary[0] ); is less obvious!

                              Problem is experienced programmers tend to write harder to understand code because they value machine efficiency and terse expression above basic clarity. In the worst case, they take to writing deliberately obscure code to show how smart they are, which is bad.

                              Anyway, don't be disheartened if learning to program seems hard. Difficult not because you're stupid, it's because breaking in isn't easy, and early misunderstandings lead to much confusion. It's another riding a bicycle experience; at first impossible, then away you go. Doesn't help that computers and computer languages change much faster than the mechanical world: last year's book may not align properly with this year's compiler, and today's book won't match cleanly with yesterday's computer. Not like a 1930 Adept vs Ketan's latest, where the basic design and operating principles of both lathes are almost identical.

                              Dave

                              #510144
                              Ivan Winters
                              Participant
                                @ivanwinters22691

                                Sorry to be slightly OTS.

                                I thought there was a version of Arduino that accepted programming in the Python script. Anyone know anything more.

                                #510169
                                SillyOldDuffer
                                Moderator
                                  @sillyoldduffer
                                  Posted by Ivan Winters on 27/11/2020 11:08:35:

                                  Sorry to be slightly OTS.

                                  I thought there was a version of Arduino that accepted programming in the Python script. Anyone know anything more.

                                  Two things you may be remembering:

                                  • There's a protocol called firmata that allows a Python program running on a PC to control a small Arduino (Uno, Nano etc.). It requires the two computers to be permanently connected, but full Python on the PC can work the Arduino's inputs and outputs as needed for many electronic projects. Basically the big computer makes programming easy while the little one does the dangerous circuit interfacing. RaspberryPi runs firmata, so a permanent pairing could be done relatively cheaply. I guess firmata can't be as fast as a native Arduino C program when speed matters.
                                  • The more powerful Arduino 32-bit Boards like the Due can run MicroPython, which is a sawn-off subset of grown-up Python. Not tried it myself, though Python and C++ are my favourite languages. There was also a board that ran Linux, but I think is discontinued.

                                  Python can also be installed on the Nucleo / STM range, and other high-end microcontrollers, bigger the better. Also possible to buy microcontrollers pre-loaded with Python or Basic. I've no of experience of them. The problem with Basic and Python is they use a lot of computer resources before the user adds his program. Sluggish and constrained compared with C or C++ too, though that may not matter. Python is heftier than BASIC because it's more advanced, and squeezing it on to a small chip is more of a challenge.

                                  The RaspberryPi runs full Python easily and exposes GPIO pins for electronic projects, but it's electrically delicate compared with most Arduinos, and – being a real computer – rather expensive to build into simple electronic projects.

                                  Dave

                                  #510199
                                  Roger Hart
                                  Participant
                                    @rogerhart88496

                                    I am a pretty dim programmer and I prefer simple and obvious with just a dash of elegance. Back in the day 'an instruction saved was an instruction earned' when you mapped your program round a disk to keep the speed up.

                                    Those days are gone thankfully, the SAMD21 I usually use has around 32K of data space and some 256K of code space all for a few quid. You can afford to be a bit profligate unless you are trying to squeeze a quart into a pint pot. You can afford obvious, let the machine take the strain. Mercifully the Arduino platform hides the nasty business of handling the ARM peripheral port multiplexer. Other platforms make you see the gory details and strong men/women are known to take fright at the sight.

                                    I like the code improvements from SoD, he points out the tradeoff between obvious/fairly obvious/terse code. Except that I would be tempted to (kindly and respectfully) strangle terse programmers (not really).

                                    Right now I am wrestling with a Python written by some academics who seem to believe writing comments and clear indenting is a mortal sin. Perhaps in academe tab characters and comments cost money – who knows…. Its so bad I even drew a flowchart, not done that for many a year. Snag was I flogged my templates on fleabay years back.

                                    #510212
                                    SillyOldDuffer
                                    Moderator
                                      @sillyoldduffer

                                      Posted by Roger Hart on 27/11/2020 13:51:31:…

                                      Except that I would be tempted to (kindly and respectfully) strangle terse programmers (not really).

                                      Right now I am wrestling with a Python …

                                      Excellent Python joke; not heard that one before!

                                      Terse programming I can only ask forgiveness for. I know I've gone too far when I can't understand my own code. And it's deeply shocking to come back to a year old program and immediately see the work of pure genius I believed it to be is actually clumsy, obscure and inefficient.

                                      Anyway, in defence of my terse example above, I thought I should test it. Found a 7 segment display and breadboarded it with a Nano. Of course it didn't work! However the mistake was my 7-segment display happens to be a common anode type rather than the common cathode display used by Malc. Common cathode LEDS are earthed and lit up by putting positive volts on the segments. Common anode are the other way round, ie the Common Anode is made positive and the segments are pulled down to earth to light them. The displays are inverts of each other. Oh dear.

                                      Rather than needing a major re-write, my code is fixed by adding a single statement.

                                      void setSegments( uint8_t group, int delaymS = 1000 ) {
                                      // A function that
                                      // Turn the segments on or off depending on bits set in group and a bit mask
                                      // group = 0, sets everything on
                                      // group = 0b00111101 turns segs C,D,E.F and decimal ON

                                      group =~ group; // Inverts group for common Anode
                                      digitalWrite( SEG_A, group & 0b10000000 ); // Only turns on A if first bit of group is 1
                                      digitalWrite( SEG_B, group & 0b01000000 );
                                      digitalWrite( SEG_C, group & 0b00100000 );

                                      The tilde is the 'bitwise NOT operator'. It flips binary bits so 1010 becomes 0101 and vice versa. I claim brownie points for an example than does LEDs with either positive or negative logic.

                                      Apologies to Malc, we should be keeping his thread simple!

                                      Dave

                                      #510229
                                      Malc
                                      Participant
                                        @malc

                                        Hi Dave, Thanks for your amendment to the sketch, I hadn't got that far. I typed in your sketch but it refuses to compile. It complains at the line: void setSegments (uint8 t group, int delaymS = 1000){ and gives an error message: variable or field 'setSegments' declared void. I was thinking that I may have typed the line incorrectly as your setSegments is in black and uint8 t is in blue Whereas my typed version has the setSegments in red and the uint8 t in black. I know these text colours in the sketches have some significance so I am just looking into it. Malc.

                                        #533998
                                        Derek Scott
                                        Participant
                                          @derekscott74280

                                          Am I able to place a post in here for some assistance with an Arduino code?

                                          #534074
                                          duncan webster 1
                                          Participant
                                            @duncanwebster1

                                            Ask the question and see what happens, I'm sure plenty of people will reply

                                            #534084
                                            Alan Charleston
                                            Participant
                                              @alancharleston78882

                                              Hi Malc,

                                              I can't get my head around Arduino programming either. The closest I got before I lost interest was this guy on YouTube:

                                              He has the gift of clearly and simply explaining how to programme in Arduino – something which is incredibly rare amongst the programming fraternity.

                                              Regards,

                                              Alan

                                            Viewing 21 posts - 26 through 46 (of 46 total)
                                            • Please log in to reply to this topic. Registering is free and easy using the links on the menu at the top of this page.

                                            Advert

                                            Latest Replies

                                            Home Forums General Questions Topics

                                            Viewing 25 topics - 1 through 25 (of 25 total)
                                            Viewing 25 topics - 1 through 25 (of 25 total)

                                            View full reply list.

                                            Advert

                                            Newsletter Sign-up