Without going into a long drawn-out dissertation on the topic, I was wondering if there was someone in arduino land that had the time or desire to help an old man out with a project. For the past 2 years I have been working on getting the ICM7243 chip to do what it is supposed to do.
In that time-frame all I was able to do was getting a two 14 segment display to count from 0 to 9. That alone was exciting and gave me the desire to continue. I searched everywhere in hopes of finding something that would help me out with the binary A to F, but that required taking 2 pins (D5 & D4) from 1's to 0's skipping the @ symbol and starting with the A.
At this point I started to realize that my 72 year brain is going south and my project was going to need something to simplify this.
I found Arduino.
Unfortunately, I don't know jack squat about c++ and so.....here I go again. Another quest hoping to find something, in this case code, that I can figure out how to use. Time and time again I would find something that would look like a workable solution, but all I would end up with was more questions that would lead to a dead end.
I ended up reading enough about c++ to make a half-ass sketch that counted from 0 to F on the two 14 segment displays and that's all the farther I can get .
My dilemma is.... I am losing my sight and stumped on being able to wing any more code to get this chip to count binary 0 to F on 4 displays. Any help I can get to get this thing working would be a blessing for me before my sight deteriorates to the point that all becomes a moot issue.
Thank you all for reading this.
If not Arduino, what are you using now to drive the display? Can you post a schematic?
You have four 14 segment displays and an ICM7243 driver chip and the objective is to make a counter which runs so:
0000
0001
0002
....
....
FFFF
Is that it ?
Post your existing Arduino code which works with 2 displays.
Ok. It looks easy enough. What Arduino are you using ?
You are using the icm7243a in random access mode but your handling of the CS and WR looks rather odd. Does that part work as expected?
6v6gt:
What Arduino are you using ?
Reply #3 states Nano.
Hi,
Welcome to the forum.
Please read the first post in any forum entitled how to use this forum.
http://forum.arduino.cc/index.php/topic,148850.0.html .
Then look down to item #7 about how to post your code.
It will be formatted in a scrolling window that makes it easier to read.
Thanks.. Tom...
This should control a 4 digit Hex counter. I can't test it because I don't have the ICM7243A but i checked it gives the same output as your basic sketch.
I had difficulty reverse engineering your control of the CS and /WR pins. analogWrite() (PWM) is a rather unusual solution for managing digital pins and analogWrite() on pin 8 is anyway not supported on an Arduino Nano. I got the relative timings from the data sheet but these may require some adjustment.
I've not used the 14 segment displays before but, if I were doing this, once I'd finished playing with the timer, I'd then turn it into a clock with the time occasionally (every 30 seconds or so) replaced with a scrolling date with the month in words.
int pin2 = 2;
int pin3 = 3;
int pin4 = 4;
int pin5 = 5;
int pin6 = 6;
int pin7 = 7;
int pin8 = 8;
int pin9 = 9;
int pin10 = 10;
int pin11 = 11;
int pin12 = 12;
int waitTime = 500;
const bool DEBUG = true ; // debug mode write to serial console
uint16_t counter = 0 ;
void digitalWriteX( byte pin, bool value ) {
// just like digitalWrite but also with optional debug output
digitalWrite( pin, value ) ;
if ( DEBUG == true ) {
Serial.print( F("pin: ") ) ;
Serial.print( pin ) ;
Serial.print( F(" has value: ") ) ;
Serial.println( value == LOW ? LOW : HIGH ) ;
}
}
void writeDisplay( byte digitPosition, byte character ) {
/*
Write a character to specific position on the display
digitPosition: value range 0 to 7
character: value range 0 to 15 representing 0 to F
*/
static byte ascii6bit[ 16 ] = {
0b00001100, // '0'
0b10001100, // '1'
0b01001100, // '2'
0b11001100, // '3'
0b00101100, // '4'
0b10101100, // '5'
0b01101100, // '6'
0b11101100, // '7'
0b00011100, // '8'
0b10011100, // '9'
0b10000000, // 'A'
0b01000000, // 'B'
0b11000000, // 'C'
0b00100000, // 'D'
0b10100000, // 'E'
0b01100000 // 'F'
} ;
// write digitPosition
digitalWriteX( 12, ( digitPosition & 0x01 ) != 0 ? HIGH : LOW ) ;
digitalWriteX( 11, ( digitPosition & 0x02 ) != 0 ? HIGH : LOW ) ;
digitalWriteX( 10, ( digitPosition & 0x04 ) != 0 ? HIGH : LOW ) ;
digitalWrite( 8, HIGH ) ; // CS
// write character
digitalWrite( 9, LOW ) ; // /WR
digitalWriteX( 2, bitRead( ascii6bit[ character ] , 7 ) == 0 ? LOW : HIGH ) ;
digitalWriteX( 3, bitRead( ascii6bit[ character ] , 6 ) == 0 ? LOW : HIGH ) ;
digitalWriteX( 4, bitRead( ascii6bit[ character ] , 5 ) == 0 ? LOW : HIGH ) ;
digitalWriteX( 5, bitRead( ascii6bit[ character ] , 4 ) == 0 ? LOW : HIGH ) ;
digitalWriteX( 6, bitRead( ascii6bit[ character ] , 3 ) == 0 ? LOW : HIGH ) ;
digitalWriteX( 7, bitRead( ascii6bit[ character ] , 2 ) == 0 ? LOW : HIGH ) ;
digitalWrite( 9, HIGH ) ; // /WR
digitalWrite( 8, LOW ) ; // CS
}
void setup() {
Serial.begin( 9600 ) ;
pinMode(2, OUTPUT); // ICM7243 D0 pin 10 // segment character fonts 0-9
pinMode(3, OUTPUT); // ' D1 ' 11 // ' ' '
pinMode(4, OUTPUT); // ' D2 ' 12 // ' ' '
pinMode(5, OUTPUT); // ' D3 ' 13 // ' ' '
pinMode(6, OUTPUT); // ' D4 ' 14 // segment character fonts A-F
pinMode(7, OUTPUT); // ' D5 ' 15 // ' ' '
pinMode(8, OUTPUT); // ' CS ' 16 // timings need tweaking
pinMode(9, OUTPUT); // ' /WR ' 17 // ' ' '
pinMode(12, OUTPUT); // ' A0 ' 30 // character display 1-8, 3 bit coding
pinMode(11, OUTPUT); // ' A1 ' 29 // ' ' ' ' '
pinMode(10, OUTPUT); // ' A2 ' 28 // ' ' ' ' '
digitalWrite( 8, LOW ) ; // CS
digitalWrite( 9, HIGH ) ; // /WR (not WR)
}
void loop() {
// if( counter > 15 ) return ;
if (DEBUG ) {
Serial.print("\nCounter=") ;
Serial.println( counter ) ;
}
writeDisplay( 0 , counter % 16 ) ; // least significant hex digit
writeDisplay( 1 , ( counter/16 ) % 16 ) ;
writeDisplay( 2 , ( counter/256 ) % 16 ) ;
writeDisplay( 3 , ( counter/4096 ) % 16 ) ; // most significant hex digit
counter ++ ;
delay(waitTime);
}
Reading and understanding timing waveforms is a rather confusing exercise for me. I have no formal education in electronics so I make the connections and just wing it from there.
Pins 16 (CS) and (17 (WR) have been rather problematic because of stability. The way I have have these hooked up to the nano and using analogWrite with on duty time of 254 works almost perfectly. The only caveat that appears every now and then, is that two of the same numbers or letters appear at the same time in the alternations. Working independently, I get a stable and reliable 0-F. If I change to a lower on duty time the display becomes unstable or stops working altogether.
T
I think that maybe playing with a higher frequency on those two pins and adding some capacitance might help with consistancy. I will have to work on that.
Thank You
Wow! Your a genius. You took no time at all to solve a problem that's been plaguing me for years.
Everything is working perfect. And a debugger to boot. I had to comment that part out to get the display to stop blinking whenever the digits would change. At first I thought there was something wrong but that took care of that.
I now see where I screwed up......essentially everywhere. Most of all..... trying to write code that is beyond my comprehension. I don't think that I've ever seen a digitalWriteX before.
Oh well....You got me going in the right direction with this. I think that now, I will add two more displays and see what happens. I may need that debugger that you were so kind to provide after all.
Thank you so much for your time and expertise.
Clete
I'm glad that all worked out OK. The code used a few well known tricks to keep it compact (storing/retrieving pin maps in a byte array etc.) which makes it look quite cryptic.
I see these 14 and 16 segment displays are getting quite rare now. Also, that chip you are using, the Intersil ICM7243A would be very difficult now to replace. I'd love to get my hands on some like these (at an affordable price).
These are still easy to get on our side of the world. I use eBay and Aliexpress for most of my electronic parts and I feel that the cost is very reasonable. I get a few parts that are duds but the overall savings still makes using them a great way to go. The long wait from China can get a bit unnerving but I always end up getting my order delivered.
I had four of the ICM7243's and something didn't seem quite right with all of them. When I did get them working they didn't work the same way or would stop completely. I had no way of testing them out to come to any conclusion because of my lack of expertise.
Thanks to your fantastic code, I was able to put them side by side for a comparison. Turns out that two of them weren't up to to challenge and needless to say.....I wasted many a day with these. That made my attempt at getting a workable anything even more of a nightmare.
If you would like, I can get you a few chips, and I took notice that you posted a picture of some nixie tubes. I have twelve Iv11VFD's that I got for spares for a few clock kits that I put together. They appeared to be brand new with long leads and were cheap. I just had to get them because I wasn't sure how long these tubes would last before they became unreadable but so far, about 5 years, they still look great. I might be blind or dead before these things fade away.
You helped me with your time and abilities. The least that I can do is return the favor.
Let me know. And thanks again.
Clete
I didn't think of looking on Aliexpress for the ICM7243A. I looked on Mouser because from there, you can get the manufacturers data sheet in one single PDF file (if they stock the chip, that is). Hence, I came to the conclusion that these would be difficult to get hold of. Thanks for the offer of some of your surplus Iv11 VFD tubes. However, these have the standard "Seven Segment" type display type and I have already built a VFD clock using 6 of the seven segment IV-22 tubes so instead I am now looking at something like the 16 segment displays in the picture attached to post #10 above. I have, in the mean time, identified these as IV-4 types and found some Ebay sellers who want around $25 for a set of 6 which is reasonable enough. But thanks anyway.
This, incidentally, is the one I have built:
After you reported that the debug information caused the display to flicker, I looked again at the ICM7243A data sheet. During the time the CS pin is active, the display is suppressed. Since the debug printing is relatively slow (9600 baud) and happens during this time, it explains why the display flickered noticeably. You can, incidentally, also suppress debug printing by setting the variable DEBUG from true to false.
Again, from the datasheet, the timing requirements appear quite straightforward for random access mode and this is how I have interpreted it:
The 3 address pins have to be set 28, 29 and 30. The the CS pin has to brought High, then the /WR pin has to be brought Low, the the data (ascii code) must be set on pins 10 to 16, the /WR brought high followed by the CS pin being brought low.
Thank you for the code adjustment for using or, in this case, not using debug. After spending many hours trying to decipher your code..... I found this easy, simple change by accident. What a difference a falsie, (pun intended) makes.
When I was testing the chips that I had, I came across an ICM7243BIPL. The pin assignments were the same so I plugged it in. So far, it's running your code the same way as the A series. A Good replacement that is more readily available than the A.
Also, if you care, Renesas has a nice datasheet in the PDF format. I think that they acquired Intersil some time ago. Unfortunately the chip is listed in the EOL catagory. All good things.....sigh.
Last night, I soldered in another two displays and, (drum roll please), Thanks to you I now have four working displays. I finally have a smile on my 72 year old face.
Now I feel embolden enough to go to the limit. I want to add another four displays.
With doing that, am I correct in my thinking that another four displays will require an addition of four more counter 'writeDisplays" to the power of 16?
I checked out your clock. It looks like it was an enjoyable project indeed. Professionally done and the enclosure is a nice touch.The ones I built were from kits, but nevertheless, I still had hours of satisfaction soldering them all together, plugging them in and have them working on the first boot up.
After a few years I had one going to the weird side. It turned out to be one of the 595 shift registers went to digital heaven. Fortunately I had a bunch on hand and a quick swap fixed the problem.
That's all for now, my friend.
Take care
Clete
It is interesting that A and B version are interchangeable. There seems to be a number of differences on the data sheet. Most significantly that the CS pin is inverted on the B version to /CS (logical not CS).
If you move on to 8 hex digits, here is the code. The counter has to be 32 bits long just like the millis() counter. That rolls over every approx. 50 days counting millseconds. Depending on how quickly the sketch runs, you may have to wait some time considerable time before you see activity on the high order digits.
uint32_t counter = 0 ; // now 32 bits
This could probably work but does not scale up very well and digits are recalculated
each loop iteration even though they may change very infrequently.
Using Hex instead of decimal in the calculation makes it easier to look at.
// '%' means modulo division
// 'UL' means unsugned long (32bits)
writeDisplay( 0 , counter % 16 ) ; // least significant hex digit.
writeDisplay( 1 , ( counter/0x10UL ) % 16 ) ;
writeDisplay( 2 , ( counter/0x100UL ) % 16 ) ;
writeDisplay( 3 , ( counter/0x1000UL ) % 16 ) ;
writeDisplay( 4 , ( counter/0x10000UL ) % 16 ) ;
writeDisplay( 5 , ( counter/0x100000UL ) % 16 ) ;
writeDisplay( 6 , ( counter/0x1000000UL ) % 16 ) ;
writeDisplay( 7 , ( counter/0x10000000UL ) % 16 ) ; // most significant hex digit
Using some sort of bit manipulation may be better although the comiler
may well be able to optimise the above code into simple bit manipulation operations
Alternative code:
uint32_t counterWork = counter ;
for ( int i = 0 ; i < 8 ; i++ ) {
byte hexDigit = counterWork & 0x0F ; // we just want the last 4 bits
writeDisplay( i, hexDigit ) ;
counterWork >>= 4 ; // right shift counterWork 4 bit to drop the bits we have just read.
}
There are other possible tricks to speed it up like only writing digits 1 to 7 if digit 0 is equal to zero to reduce the number of unnecessary writes.
Have fun with it.
Oh, can you incidentally go back to your post #3 and edit it to wrap that very long sketch in code tags like below but no embedded spaces. Don't just delete it because it may help someone following in your footsteps.
[ code ]
[ /code ]