Arduino Mega 2560 and 7 segment LED displays (74HC595) with PWM
hi everyone,
i using arduino mega 2560 control 72 high-powered led 7 segment displays 72 shift register (74hc595) driving transistors.
the setup:
- 4 rows of 18 digits (consisting 3 blocks of 6 digits)
- every row uses 4 pins on arduino mega 2560 (data, clock, latch, master reset). used pins: 22 37 4 rows
- each block of 6 digits has pwm signal in order change luminosity of screens. used pins: 2 13 12 blocks
- numbers displayed on screens generated in realtime using max msp , transmitted serial port arduino.
serial communication structured follow:
there 2 types of messages:
- control message, 2 bytes
- content message, 18 bytes (depending on how many digits active in row)
the control message sends index next row updated , number of digits consisting content message. arduino adjust serial buffer needed size of next content message , sending ready-message max msp. max msp sends content message 18 bytes fill digits of row. when shift register filled arduino returns 255 indicate action has been executed , setting serial buffer 2 bytes. , way iterating through 4 rows. working @ highest speed can get, @ 15 milliseconds updating 1 row.
everything working fine until point. problem need change luminosity on runtime. luminosity uses control message type of 2 bytes. first byte index of block , second byte pwm-value. if pwm-change needed max msp wait until the actual row finished , send pwm control-message before continuing next row.
at point getting out of control: either segments of digits lightened more or less randomly or entire row flickering , jumping around.
i can't explain how happening, seems pwm signal affecting pins shift register. when setting pwm signal on setup of arduino (not chaining on runtime) working fine.
any ideas on whats happening?
here arduino-code:
i hope more or less understandable, please ask if need further informations.
thanks in advance,
wunjeld
i using arduino mega 2560 control 72 high-powered led 7 segment displays 72 shift register (74hc595) driving transistors.
the setup:
- 4 rows of 18 digits (consisting 3 blocks of 6 digits)
- every row uses 4 pins on arduino mega 2560 (data, clock, latch, master reset). used pins: 22 37 4 rows
- each block of 6 digits has pwm signal in order change luminosity of screens. used pins: 2 13 12 blocks
- numbers displayed on screens generated in realtime using max msp , transmitted serial port arduino.
serial communication structured follow:
there 2 types of messages:
- control message, 2 bytes
- content message, 18 bytes (depending on how many digits active in row)
the control message sends index next row updated , number of digits consisting content message. arduino adjust serial buffer needed size of next content message , sending ready-message max msp. max msp sends content message 18 bytes fill digits of row. when shift register filled arduino returns 255 indicate action has been executed , setting serial buffer 2 bytes. , way iterating through 4 rows. working @ highest speed can get, @ 15 milliseconds updating 1 row.
everything working fine until point. problem need change luminosity on runtime. luminosity uses control message type of 2 bytes. first byte index of block , second byte pwm-value. if pwm-change needed max msp wait until the actual row finished , send pwm control-message before continuing next row.
at point getting out of control: either segments of digits lightened more or less randomly or entire row flickering , jumping around.
i can't explain how happening, seems pwm signal affecting pins shift register. when setting pwm signal on setup of arduino (not chaining on runtime) working fine.
any ideas on whats happening?
here arduino-code:
code: [select]
const int row_count = 4; //count of rows
const int blk_count = 3; //count of block per row
const int dpb_count = 6; //count of digits per block
const int pin_count = 8; //count of pins used per row
int actual_row;
int binary_pins[row_count][4] = {
/*porta*/{0, 1, 2, 3},
/*porta*/{4, 5, 6, 7},
/*portc*/{7, 6, 5, 4},
/*portc*/{3, 2, 1, 0}
};
int digit_pins[row_count][pin_count] = {
{22, 23, 24, 25, 2, 3, 4, 40}, //row 0 [0]data , [1]clock, [2]latch, [3]master reset, [4]pwm_b1, [5]pwm_b2, [6]pwm_b3, [7]control in
{26, 27, 28, 29, 5, 6, 7, 41}, //row 1 [0]data , [1]clock, [2]latch, [3]master reset, [4]pwm_b1, [5]pwm_b2, [6]pwm_b3, [7]control in
{30, 31, 32, 33, 8, 9, 10, 42}, //row 2 [0]data , [1]clock, [2]latch, [3]master reset, [4]pwm_b1, [5]pwm_b2, [6]pwm_b3, [7]control in
{34, 35, 36, 37, 11, 12, 13, 43} //row 3 [0]data , [1]clock, [2]latch, [3]master reset, [4]pwm_b1, [5]pwm_b2, [6]pwm_b3, [7]control in
};
/* digit_pins
[row][data, clock, latch, masterreset, pwm_b1, pwm_b2, pwm_b3, control in]
*/
boolean phrase_check[row_count]; //[rows] array verifie if register filled bits 0 or 1 [4]
int serial_length;
char serial_from_max[blk_count*dpb_count];
/*serial_from_max
------------------------------------------------------------------
1. message set digits
[row][block]
row = 0-3 (row index) byte 1 (0-3)
block = 1-3 (block count) byte 2 (1-3)
2. message
[digit]*count
array digits
------------------------------------------------------------------
[row/block][pwm] set luminosity
row = 1x-4x (row index) byte 1 (10-42)
block = x0-x2 (block index) byte 1
pwm = 0-255 (pwm luminosity) byte 2 (0-255) (0,1 = activity)
*/
void setup(){
serial.begin(115200);
serial_length = 2;
for(int _row=0; _row<row_count; _row++){
phrase_check[_row] = 0; //set rows unverified
for(int _pin=0; _pin<pin_count; _pin++){
if(_pin<pin_count-1){ pinmode(digit_pins[_row][_pin], output); } //declare outputs
else{ pinmode(digit_pins[_row][_pin], input); } //declare inputs
}
}
resetallrows();
}
void loop(){
while(serial.available() > serial_length-1){
serial.readbytes(serial_from_max, serial_length);
if(serial_length == 2){
byte index = byte(serial_from_max[0]); byte val = byte(serial_from_max[1]);
if(index < 4){
serial_length = val*dpb_count;
actual_row = index;
serial.write((index*10)+val);
}
else{
setluminosity(index, val);
serial.write(255);
}
}
else{
shiftrow(actual_row, serial_length);
serial_length = 2;
serial.write(255);
}
}
}
void setluminosity(int _index, int _val){
analogwrite(digit_pins[int(floor((_index-10)/10))][(_index%10)+4], _val);
}
void shiftrow(int _row, int _length){
resetrow(_row);
writebit(1,0);
for(int _digit=_length-1; _digit>=0; _digit--){
for(int _bit=0; _bit<8; _bit++){
writebit((serial_from_max[_digit] >> _bit) & 1, _row); //read bit per bit serial message
}
}
porta |= (1 << binary_pins[_row][2]); //latch 1 causes display register
}
void writebit(boolean _bit, int _row){
if(_row < 2){ //porta (pin 22-29)
porta = (_bit) ? porta | (1 << binary_pins[_row][0]) : porta & ~(1 << binary_pins[_row][0]); //data
porta |= (1 << binary_pins[_row][1]); //clock 1
porta &= ~(1 << binary_pins[_row][1]); //clock 0
}
else{ //portc (pin 26-33)
portc = (_bit) ? portc | (1 << binary_pins[_row][0]) : portc & ~(1 << binary_pins[_row][0]); //data
portc |= (1 << binary_pins[_row][1]); //clock 1
portc &= ~(1 << binary_pins[_row][1]); //clock 0
}
}
void resetrow(int _row){
if(_row < 2){
porta &= ~(1 << binary_pins[_row][2]); //latch 0 bevor filling memory
porta &= ~(1 << binary_pins[_row][3]); //master reset 0
porta |= (1 << binary_pins[_row][3]); //master reset 1
}
else{
portc &= ~(1 << binary_pins[_row][2]); //latch low bevor filling memory
portc &= ~(1 << binary_pins[_row][3]); //master reset
portc |= (1 << binary_pins[_row][3]); //master reset
}
}
void resetallrows(){
for(int _row=0; _row<row_count; _row++){
digitalwrite(digit_pins[_row][2], low); //latch low fill memory
digitalwrite(digit_pins[_row][3], low); //master reset
digitalwrite(digit_pins[_row][3], high); //master reset
digitalwrite(digit_pins[_row][2], high); //latch high execute memory
}
}
i hope more or less understandable, please ask if need further informations.
thanks in advance,
wunjeld
quote
i can't explain how happening, seems pwm signal affecting pins shift register.of course is! sending 1 bit @ time bit register, , pwm bit "randomly" turned on & off. (it's not random, there no logical relationship shift-clock.)
pwm doesn't work matrixing, since rows & columns "sharing" pwm outputs.
Arduino Forum > Using Arduino > Project Guidance > Arduino Mega 2560 and 7 segment LED displays (74HC595) with PWM
arduino
Comments
Post a Comment