As a part of learning purpose, I tried to show 2 on the DP0-position of the display unit of the following circuit driven by MAX7219 Controller. I tried first with Library Function, but I failed. Now, I have written low level codes which are also not working. Any help will be highly appreciated.
int x;
void setup()
{
pinMode(8, OUTPUT); //LOAD Pin
pinMode(11, OUTPUT); //DIN Pin
pinMode(13, OUTPUT); //CLK Pin
PORTB = 0x00; //all pins low
x = 0x0C01; //normal Mode xxxx 1100 00000001
clkIn();
x = 0x0900; //no-decode mode xxxx 1001 00000000
clkIn();
x= 0x0AFF; //max intensity xxxx 1010 11111111
clkIn();
x= 0x0B07; //scan limit //8-digit : xxxx 1011 00001111
clkIn();
x = 0x015B; //xxxx 0001 01011011 ; digit 2 at DP0 position
clkIn();
}
void loop()
{
}
void clkIn()
{
for (int i = 15; i>=0; i--)
{
digitalWrite(11, bitRead(x, i)); //D15 is shifted first
//------
digitalWrite(13, HIGH);//generating clock signal
// delayMicroseconds(1);
digitalWrite(13, LOW);
}
digitalWrite(8, HIGH); //LOAD is made High and then Low
//delayMicroseconds(1);
digitalWrite(8, LOW);
}
Passing arguments via globals was old-hat in Noah's time.
void clkIn(int x)
{
for (int i = 15; i>=0; i--)
{
digitalWrite(11, bitRead(x, i)); //D15 is shifted first
//------
digitalWrite(13, HIGH);//generating clock signal
// delayMicroseconds(1);
digitalWrite(13, LOW);
}
digitalWrite(8, HIGH); //LOAD is made High and then Low
//delayMicroseconds(1);
digitalWrite(8, LOW);
}
(as were un-named pins)
I have written low level codes which are also not working
You have over 1000 posts, and you think that is an acceptable statement? :o
That's the indication of participation for about 430 days. Normalize the posts by the karma (karma/total_posts) and then multiply by the inverse of days_spent -- that tells the qualitative measure of the posts although many will not agree with this simplistic evaluation criterion.
A minor aside, your comments specify displaying a 2, but your bit structure is for a 5. Pattern for 2 is 0110 1101.
Is your 7 segment display common cathode and do you have the required resistor between pin 18 (ISET) and +5?
Sorry if the questions seem dumb, but all you have told us "...but I failed" and "...also not working."
MAX7219 is only compatible with cc(common cathode type) 7-segment display devices.
The 8-bit cc-code for digit 2 is : 0101 1011 = 5B?
I have installed the current setting resistor which is 9.9k (recommended value is 9.53 k).
Pattern for 2 is 0110 1101.
How have you got this pattern? It is for 2 or 5? It is for cc- or ca-device? Which bit is the MS-bit?
Now, I see, you have got it from the following table of the data sheets. I could not even think that the bit pattern could be so reversed! Thanks+.
The normal cc-code for 2 : 101 1011 (without point)
Reverse the order (no-decode mode), we get: 1101 101 (without point)
Now, place the point (1=ON, 0= OFF), we get: 01101101 ---> 0110 1101 = 0x6D
Table 5 and 6 on page 8 of the MAX7219 data sheet. Table 6 shows the bit assignments to the seven segment structure. Decimal point is bit 7, segment A (top bar) is bit 6, continue clockwise to segment F (top left) - bit 1, finally the center bar, segment G, is bit 0.
That would make the code for digit 2 0x6D.
Are you using one of those 8 digit display modules mounted with the MAX7219 from eBay or Amazon or your own build?
Now, 2 has appeared; but, the codes are in the loop() function.
When the MAX7219 is containing all the scanning circuitry, why should we put the codes in the loop() function. In the case of 8279 controller, we just write the data, whenever needed, into the data register of the controller; the controller just keeps driving the multiplexed display unit by virtue of its own scanning circuitry. I am using my own-made display array.
//int x;
void setup()
{
pinMode(8, OUTPUT); //LOAD Pin
pinMode(11, OUTPUT); //DIN Pin
pinMode(13, OUTPUT); //CLK Pin
PORTB = 0x00; //all pins low
}
void loop()
{
int x = 0x0C01; //normal Mode xxxx 1100 00000001
clkIn(x);
x = 0x0900; //no-decode mode xxxx 1001 00000000
clkIn(x);
x= 0x0AFF; //max intensity xxxx 1010 11111111
clkIn(x);
x= 0x0B07; //scan limit //8-digit : xxxx 1011 00001111
clkIn(x);
x = 0x016D; //xxxx 0001 01011011 ; digit 2 at DP0 position
clkIn(x);
}
void clkIn(int x)
{
for (int i = 15; i>=0; i--)
{
digitalWrite(11, bitRead(x, i)); //D15 is shifted first
//------
digitalWrite(13, HIGH);//generating clock signal
// delayMicroseconds(1);
digitalWrite(13, LOW);
}
digitalWrite(8, HIGH); //LOAD is made High and then Low
//delayMicroseconds(1);
digitalWrite(8, LOW);
}
For the last 39 years I was paid by the companies and institutions to write instructions as many lines as possible; because, those lines were meant for learning purposes and not for selling. It is very very difficult to get rid of the years' old tradition.
Now, come to the MAX7219 Business:
Perhaps, you have read the post of Due_unto; that's the mistake I made to find/arrange the cc-codes for the digits.
LOAD/CS: For MAX7219, it is LOAD. According to data sheets, during the clocking phase of the data, the state of LOAD is irrelevant. At the end of the clocking of the last data bit, the data must be latched into the chip by asserting a rising edge on the LOAD signal. That's why, I did like this: LH--->LOAD, microdelay (optional) LL--->LOAD. In one post, you have removed LL ---> LOAD instruction?
In one post, you have removed LL ---> LOAD instruction?
No, I moved it.
If I'd removed it, then the line would never toggle - even a noob like you should have realised that.
For the last 39 years I was paid by the companies and institutions to write instructions as many lines as possible; because, those lines were meant for learning purposes and not for selling. It is very very difficult to get rid of the years' old tradition
And yet, somehow, you couldn't find it in yourself to go that extra furlong, and name the pins.(three more lines of code).
I wonder what instructional value you found in that.
For MAX7219, it is LOAD. According to data sheets, during the clocking phase of the data, the state of LOAD is irrelevant
I'm looking at Maxim's 7219/7221 datasheet, (Figure 1, page 6) and the /CS line most definitely goes LOW before CLK goes HIGH, with a minimum of 25ns (ICSS)
Nothing at all irrelevant that I can see.
TolpuddleSartre:
I'm looking at Maxim's 7219/7221 datasheet,
Then look at this:
❝ For the MAX7219, serial data at DIN, sent in 16-bit packets, is shifted into the internal 16-bit shift register with each rising edge of CLK regardless of the state of LOAD. For the MAX7221, /CS must be low to clock data in or out. The data is then latched into either the digit or control registers on the rising edge of LOAD/CS. ❞
If I were the OP and a noob, with the very strong possibility that I'd misidentified my device, I'd be coding defensively, and using the catch-all case.
clk8In(0x0C01); //normal Mode xxxx 1100 00000001 - shorten the function to match
clk8In(0x0900); //no-decode mode xxxx 1001 00000000
clk8In(0x0AFF); //max intensity xxxx 1010 11111111
clk8In(0x0B07); //scan limit //8-digit : xxxx 1011 00001111 <<< this is BF
loop() only needs to contain the stuff that changes, like sending digits:
//global
byte fontArray[] = {
0b00111111, // 0 assuming dp-g-f-e-d-c-b-a, which I think needs some adjusting in this case
0b00111001, // 1
0b01011011, // 2
etc this 9
};
void loop(){
clkIn(0x01); //xxxx 0001 ; digit DP0 position
clkIn (fontArray[2]); // look up segments for a 2 and sends it out
clkIn(0x02); //xxxx 0010 ; digit DP1 position
clkIn (fontArray[5]);
delay(1000);
clkIn(0x01); //xxxx 0001 ; digit DP0 position
clkIn (fontArray[6]); // look up segments for a x and sends it out
clkIn(0x02); //xxxx 0010 ; digit DP1 position
clkIn (fontArray[3]);
delay(1000);
}
Don't forget the chip select Low & High if that wasn't added already.
I normally use SPI.transfer myself
//make this a function
digitalWrite (ssPin, LOW);
SPI.transfer (address);
SPI.transfer (fontArray[dataToSend]);
digitalWrite (ssPin, HIGH);
where address is 1 to 8, and higher for the control registers.
Run at 4 MHz default speed.
Don't forget 0.1uF and 10uF caps on the Vcc pin.
The following circuit and the associated SPI-based codes have appeared as working. The program codes given below add two 8-bit binary numbers (0x12 ans 0x13) (in the setup() function) and show the result on DP0-DP1 positions of the display. Anyway, it works for any combinations of numbers. However, something is there, which has gone against the very feature of the MAX7219 Controller.
When the initialization codes (also the result transfer codes) are moved from the loop() function into the the setup() function, the circuit/code is not working (no display!). But, the MAX7219, according to data sheets, contains 8x8 RAM for the digits' data and also the scanning circuitry. Therefore, there is no need for continuous delivery of data into the controller; the user will just update new data as they arrive. The refreshing will be taken care of by the controller.
#include<SPI.h>
byte registerAddress[] = {0x0C, 0x09, 0x0A, 0x0B};
byte registerData[] = {0x01, 0x00, 0x01, 0x07};
//normal mdeo; no-decode;intensity;8-digit scan
byte dataArray[50]; //to hold cc-codes (no-decode format)
byte digitAddress[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};//DP)-DP7
byte lupTable[] = {0x7E, 0x30, 0x6D, 0x79, 0x33, 0x5B, 0x5F, 0x70,
0x7F, 0x7B, 0x77, 0x1F, 0x4E, 0x3D, 0x4F, 0x47}; //0, 1, ...., E, F
void setup()
{
pinMode(10, OUTPUT); //LOAD Pin of MAX7219
//-------------------
SPI.begin();
bitSet(SPCR, 4); //UNO is Master SPI
SPI.setBitOrder(MSBFIRST); //MSB_bit will be transferred first
SPI.setClockDivider(SPI_CLOCK_DIV128); //TX rate = 16MHz/128 = 125 kbit
SPI.setDataMode(SPI_MODE0);//MOSI is sampled at the rising edge of CLK
//------------------------------------------------
digitalWrite(10, LOW); //Low at LOAD pin
//---- computation----------------------------------
byte z = 0x12 + 0x13; //[s]z = 3C[/s] z = 25
dataArray[0] = lupTable[z>>4];
dataArray[1] = lupTable[z&0x0F];
//-------------------------------------------------
}
void loop()
{
//---keep intializing the Mode of Operation------------
for(int i=0; i<4; i++)
{
SPI.transfer(registerAddress[i]);
SPI.transfer(registerData[i]);
digitalWrite(10, HIGH); //assert LH/LL on LOAD pin
digitalWrite(10, LOW);
}
//--keep transferring the result/data----------------------
for(int i=0; i<2; i++)
{
SPI.transfer(digitAddress[i]); //DPX position
SPI.transfer(dataArray[i]); //shows 2 on DP0-position
digitalWrite(10, HIGH); //assert LH/LL on LOAD pin
digitalWrite(10, LOW);
}
}