As you know from my previous Article I got recently some nice MAX7219 8 Digit Display Modules.
Had a lot fun fun with them, looks a nice and stable solution so I’m thinking to use them as Display for one of my future projects.
Meanwhile I was also playing with ESP8266 CBDBv2 EVO and Arduino IDE and because it looks like the latest 1.6.4 version it’s becoming more stable and usable than previous releases I will give it a try for MAX7219 Driver implementation.
I still consider ESP8266 + NodeMCU LUA interpreter as the best environment for Learning/Drivers Developpment or even small projects, offering you a great flexibility that a Interpreter can give you but it’s obviously that for bigger projects you need something else, so let’s give Arduino IDE a try.
What we will need:
- CBDBv2 EVO Board ( or any other ESP8266 Board with the same capabilities you may like )
- USB adapter (take a look on Part 1 for details about the USB Adapter)
- MAX7219 – 8 Digit Display module
- Connection wires – various colors
- Bench Power Supply – for +5V and ADC Voltage divider Vin.
- For programming and uploading the driver and the software we will use the Arduino IDE.
I will not insist to much on the Arduino IDE install process, it is a quite trivial process. If anybody wants more details about please feel free to ask.
MAX 7219 – 8 digit display driver connections |
Wire MAX7219 ESP8266
Green +5Vcc
Blue GND GND
Yellow DIN 13
White CS 12
Orange CLK 14
MAX7219 Driver Implementation
For details about MAX Timing Diagram, Registers, Initialisation, etc please take a look at the detailed description from the previous MAX7219 article.
1. Init
int INTENSITYMIN = 0; // minimum brightness, valid range [0,15] int INTENSITYMAX = 1; // maximum brightness, valid range [0,15] int DIN_PIN = 13; // data in pin int CS_PIN = 12; // load (CS) pin int CLK_PIN = 14; // clock pin int dly = 50; // delay in us int adc=0; // read ADC int spr=32; // number of readings int offset=5; // input offset float nr = 1.0054; // number to be displayed // MAX7219 registers byte MAXREG_DECODEMODE = 0x09; byte MAXREG_INTENSITY = 0x0a; byte MAXREG_SCANLIMIT = 0x0b; byte MAXREG_SHUTDOWN = 0x0c; byte MAXREG_DISPTEST = 0x0f;
void putByte(byte data) { byte i = 8; byte mask; while (i > 0) { mask = 0x01 << (i - 1); // apply bitmask digitalWrite( CLK_PIN, LOW); // CLK delayMicroseconds(dly); if (data & mask) // select bit { digitalWrite(DIN_PIN, HIGH); // send 1 delayMicroseconds(dly); }else{ digitalWrite(DIN_PIN, LOW); // send 0 delayMicroseconds(dly);} digitalWrite(CLK_PIN, HIGH); // CLK delayMicroseconds(dly); --i; // move to next bit } }
void setRegistry(byte reg, byte value) { digitalWrite(CS_PIN, LOW); delayMicroseconds(dly); putByte(reg); // specify register putByte(value); // send data digitalWrite(CS_PIN, LOW); delayMicroseconds(dly); digitalWrite(CS_PIN, HIGH); }
void print_LED(float fVal, int w, int p) { int d = 1; int ch = 1; int n = 0; int nr_size = 0; char charVal[11]; //temporarily holds data from vals String stringVal = ""; //data on buff is copied to this string //dtostrf(fVal, w, p, charVal); //4 is mininum width, 3 is precision; //NOT WORKING FOR Values SMALLER THAT 0.01 !! // stringVal = charVal; // created a new function below for converting properly a pozitive xxxx.xxx float to string stringVal=ftos(fVal,3); int strl = stringVal.length()-1; for (int i=0;i<strl+1;i++) { charVal[i]=stringVal[i]; } Serial.print("Length: ");Serial.println(strl); //display string Serial.println(stringVal); //convert charVal[] to LED Display string for(int i=0;i<strl+1;i++) { if ((charVal[i] == '.') && (d==1)) { stringVal=charVal[i]; n = 0; n = (n * 10) + (charVal[i-1] - 48); setRegistry(strl-i+1, 128+n); d = 0; } else { stringVal=charVal[i]; Serial.print("d: ");Serial.print(d); //display string Serial.print(" - Increment: ");Serial.print(i); //display string Serial.print(" - INT: ");Serial.println(charVal[i]); //display string n=0; n = (n * 10) + (charVal[i] - 48); int pos = i; if (d==0) { pos = i-1; } setRegistry(strl-pos,n); } } }
String ftos(float fVal, int prec) { int mlt=10; String snr; String dp; int iprt,dprt; iprt = int(fVal); // Round fVal for proper prec printing - correctly so that print(1.999, 2) prints as "2.00" double rnd = 0.5; for(uint8_t i = 0; i < prec; ++i) rnd /= 10.0; mlt *= 100; fVal += rnd; // Check and count "0"'s proper after ZERO (0.00xx) number display dprt = 1000*(fVal-iprt); if (dprt < 10) { dp = "00" + String(dprt); }else if (dprt < 100) { dp = "0" + String(dprt); }else {dp = dprt;} snr = String(iprt) +"."+String(dp); //Serial.println(""); //Serial.print("MLT: ");Serial.println(mlt); //Serial.println(""); //Serial.print("DEC Part: ");Serial.println(dprt); //Serial.println(""); //Serial.print("Int Part: ");Serial.println(iprt); //Serial.print(" . "); //Serial.print("DP: "); Serial.print(dp); return snr; }
void zero_lcd() { for (int i=1;i<9;i++) { setRegistry(i, 0); delayMicroseconds(100); } }
void init_MAX7219() { // select allocated I/O pins pinMode(DIN_PIN, OUTPUT); pinMode(CLK_PIN, OUTPUT); pinMode(CS_PIN, OUTPUT); // initialization of the MAX7219 setRegistry(MAXREG_SCANLIMIT, 0x07); delayMicroseconds(dly); setRegistry(MAXREG_DECODEMODE, 0xFF); // full decode mode BCD 7 Seg Display delayMicroseconds(dly); setRegistry(MAXREG_SHUTDOWN, 0x01); // shutdown mode OFF delayMicroseconds(dly); setRegistry(MAXREG_DISPTEST, 0x00); // no test delayMicroseconds(dly); setRegistry(MAXREG_INTENSITY, 0); delayMicroseconds(dly); zero_lcd(); }
8. Test Display Driver – Read live ADC values and print them
float read_adc() { adc = 0; for (int i=0;i<spr;i++) { adc += analogRead(0); } nr = (float)(adc/spr-offset)*0.0009657; return nr; } void setup () { Serial.begin(9600); init_MAX7219(); } void loop () { nr = read_adc(); Serial.println((float)adc/spr); print_LED(nr,4,3); delay(5000); }