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;
2. Write serialised data
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
}
}
3. Set Register
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);
}
4. Convert anf Print float value in xxxx.xxx format
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);
}
}
}
5. Convert float value to a string
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;
}
5. Create a Display 'ZERO' init stage
void zero_lcd()
{
for (int i=1;i<9;i++)
{
setRegistry(i, 0);
delayMicroseconds(100);
}
}
6. MAX7219 Initialisation
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();
}
7. 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);
}
No comments:
Post a Comment