Malc | 26/11/2020 17:26:32 |
100 forum posts 5 photos | Since my last post on this subject I have had some success with the programming. I have now got the sketch to light all the 4x7 segments in turn and their decimal points. The only trouble is that the sketch is over 200 lines long and I'm sure that there must be a better way of doing this. I have been trying to use arrays to group the "digital write" lines into 0, 1, 2, etc arrays to replace these lines and so shorten the sketch. Am I on the right lines? I will try to post he code here. I think the Arduino forum have grown a little impatient with me so I would be grateful for any suggestions. NB. It seems the post is too long so I will post the sketch in another post.
|
Malc | 26/11/2020 17:29:27 |
100 forum posts 5 photos | Code part 1 // tests a 4x7 seg. disp. with modified blink sketch. displays 0000 1111 2222 3333 etc. with decimal points after all digits. #define seg //output pins to 7 segment display
{ digitalWrite(3, HIGH); // turn the following LEDs (segnments)on to display the number 1. digitalWrite(2, HIGH); // turn the following LEDs (segnments)on to display the number 2. digitalWrite(2, HIGH); // turn the following LEDs (segnments)on to display the number 3. digitalWrite(3, HIGH); // turn the following LEDs (segnments)on to display the number 4. digitalWrite(3,LOW); //turn the following LEDs (segments)off. digitalWrite(2, HIGH); // turn the following LEDs (segnments)on to display the number 5. delay(Don); // wait for a second
|
Malc | 26/11/2020 17:30:58 |
100 forum posts 5 photos | code part 2 delay(Don); // wait for a second digitalWrite(2,LOW); //turn the following LEDs (segments)off. //delay(Doff); // wait for a second digitalWrite(2, HIGH); // turn the following LEDs (segments) on to display the number 6. delay(Don); // wait for a second digitalWrite(2, LOW); //turn the following LEDs (segments)off. //delay(Doff); // wait for a second digitalWrite(2, HIGH); // turn the following LEDs (segments) on to display the number 7. delay(Don); // wait for a second digitalWrite(2, LOW); //turn the following LEDs (segments)off. //delay(Doff); // wait for a second digitalWrite(2, HIGH); // turn the following LEDs (segments) on to display the number 8. delay(Don); // wait for a second digitalWrite(2, LOW); //turn the following LEDs (segments)off. //delay(Doff); // wait for a second digitalWrite(2, HIGH); // turn the following LEDs (segments) on to display the number 9. delay(Don); // wait for a second digitalWrite(2, LOW); //turn the following LEDs (segments)off. //delay(Doff); // wait for a second |
Frances IoM | 26/11/2020 17:42:28 |
945 forum posts 27 photos | whenever some 40yrs ago I saw code like that I would immediately look at what I then called table driven code - ie a specialised interpreter + a highly compact bit oriented tables Edited By Frances IoM on 26/11/2020 17:43:19 |
duncan webster | 26/11/2020 18:06:31 |
![]() 2946 forum posts 34 photos | 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. |
Malc | 26/11/2020 18:27:46 |
100 forum posts 5 photos | Hi Duncan, the display I am using is a 4x7 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 |
duncan webster | 26/11/2020 19:47:47 |
![]() 2946 forum posts 34 photos | 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 |
Malc | 26/11/2020 20:23:42 |
100 forum posts 5 photos | Thanks Duncan, that looks like a quest for tomorrow. |
duncan webster | 26/11/2020 20:50:25 |
![]() 2946 forum posts 34 photos | I think I meant common cathode! |
SillyOldDuffer | 26/11/2020 21:06:31 |
Moderator 6682 forum posts 1501 photos | Congratulations to Malc:
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. 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. 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 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 |
Malc | 26/11/2020 21:39:24 |
100 forum posts 5 photos | 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. |
duncan webster | 27/11/2020 03:41:47 |
![]() 2946 forum posts 34 photos | 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}; 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) 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 |
duncan webster | 27/11/2020 04:12:29 |
![]() 2946 forum posts 34 photos | 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. |
Malc | 27/11/2020 08:45:56 |
100 forum posts 5 photos | Blimey Duncan, sorry if I kept you awake! Looks like I have a busy day ahead, thanks again.Malc. |
Roger Hart | 27/11/2020 09:06:48 |
135 forum posts 30 photos | 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
void loop() { int byt; byt = 0; while (byt < 256) |
Malc | 27/11/2020 09:38:39 |
100 forum posts 5 photos | 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. |
SillyOldDuffer | 27/11/2020 10:39:12 |
Moderator 6682 forum posts 1501 photos | 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); 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); 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
|
Ivan Winters | 27/11/2020 11:08:35 |
10 forum posts 1 photos | Sorry to be slightly OTS.
I thought there was a version of Arduino that accepted programming in the Python script. Anyone know anything more. |
SillyOldDuffer | 27/11/2020 11:54:56 |
Moderator 6682 forum posts 1501 photos | 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:
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 |
Roger Hart | 27/11/2020 13:51:31 |
135 forum posts 30 photos | 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. |
Please login to post a reply.
Want the latest issue of Model Engineer or Model Engineers' Workshop? Use our magazine locator links to find your nearest stockist!
You can contact us by phone, mail or email about the magazines including becoming a contributor, submitting reader's letters or making queries about articles. You can also get in touch about this website, advertising or other general issues.
Click THIS LINK for full contact details.
For subscription issues please see THIS LINK.