Hi I have a 128 x 16 Dot Matrix board but the code I have is only for 64 boards; therefore it is repeating the same message on both of the 64 boards.
I was wondering if anyone could help? I cannot paste the full code as it is longer than 9000 characters
#include <avr/pgmspace.h>
#include "pins_arduino.h"
// based on myMatrix Arduino Library
// by Silviu - www.openhardware.ro
// MIT License (MIT)
// Connections to board
const byte pinSTB=8;
const byte pinClock=12;
const byte pinRed=10;
const byte pinGreen=11;
const byte pinOE=2;
const byte pinRowA=3;
const byte pinRowB=4;
const byte pinRowC=5;
const byte pinRowD=6;
byte scanRow = 0;
unsigned long counter;
//Insert message here ("message ")
char message[] = " Hello ";
// ---------------------------------------------------------------------------------------------------
const byte RED = 0b10;
const byte GREEN = 0b01;
const byte YELLOW = 0b11;
const byte BLACK = 0b00;
struct Color {
byte R;
byte G;
};
#define BUFFER_INIT_128 BUFFER_INIT_100 BUFFER_INIT_10 BUFFER_INIT_10 BUFFER_INIT_8
#define BUFFER_INIT_100 BUFFER_INIT_50 BUFFER_INIT_50
#define BUFFER_INIT_50 BUFFER_INIT_10 BUFFER_INIT_10 BUFFER_INIT_10 BUFFER_INIT_10 BUFFER_INIT_10
#define BUFFER_INIT_10 BUFFER_INIT_2 BUFFER_INIT_2 BUFFER_INIT_2 BUFFER_INIT_2 BUFFER_INIT_2
#define BUFFER_INIT_8 BUFFER_INIT_2 BUFFER_INIT_2 BUFFER_INIT_2 BUFFER_INIT_2
#define BUFFER_INIT_2 BUFFER_INIT_1 BUFFER_INIT_1
#define BUFFER_INIT_1 {0x00, 0x00},
Color buffer[128] = {BUFFER_INIT_128};
// ---------------------------------------------------------------------------------------------------
(then there's font information)
// function to colorize a pixel
// color 2 Bit, (R)ed (G)reen 0b000000RG
void setPixel(uint8_t x ,uint8_t y, uint8_t color)
{
uint8_t myindex = (y*8)+x/8; // 8 segments per row
uint8_t mybitmask = 7 -(x % 8);
bitWrite(buffer[myindex].R, mybitmask, (color & 0b00000010)); // red
bitWrite(buffer[myindex].G, mybitmask, (color & 0b00000001)); // green
}
// function to print a character at column
void printChar(uint8_t x_offset, uint8_t fg_color, uint8_t bg_color, byte ch) {
if (0 != (x_offset % 8)) return; // x_offset not a multiple of 8
if ((ch>9) && (ch<32)) return; // invalid character
const uint8_t y_offset = 0;
for (uint8_t y=0; y<16; y++){
for (uint8_t i=0; i<8; i++){
if(bitRead(pgm_read_byte(&font8x16_basic[ch-32][y]),7-i)) setPixel(x_offset+i, y_offset+y, fg_color);
else setPixel(x_offset+i, y_offset+y, bg_color);
}
}
}
// function to scroll the text message to the left
void hScroll(uint8_t fg_color, uint8_t bg_color, char *mystring){
// offset starts with 0
// this means text starts in upper left corner
for (int offset=0; offset < ((lenString(mystring)-8)*8-1); offset++){
for (byte x=0; x<64; x++){
for (byte y=0; y<16; y++){
byte color=bg_color;
if (getPixelMessage(x+offset,y,mystring)) color=fg_color;
setPixel(x,y,color);
}
}
delay(40);
}
}
byte getPixelMessage(uint16_t x, uint16_t y, char *p){
p=p+x/8;
return getPixelChar(x%8, y, *p);
}
byte getPixelChar(uint8_t x, uint8_t y, char ch){
return bitRead(pgm_read_byte(&font8x16_basic[ch-32][y]),7-x);
}
// length of the message string
uint8_t lenString(char *p){
unsigned int retVal=0;
while(*p!='\0'){
retVal++;
p++;
}
return retVal;
}
void drawRectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint8_t color){
drawHLine(x1,x2,y1,color);
drawHLine(x1,x2,y2,color);
drawVLine(x1,y1,y2,color);
drawVLine(x2,y1,y2,color);
}
void drawVLine(uint16_t x, uint16_t y1, uint16_t y2, uint8_t color){
for (uint16_t y = y1; y <= y2; y++) {
setPixel(x,y,color);
}
}
void drawHLine(uint16_t x1, uint16_t x2, uint16_t y, uint8_t color){
for (uint16_t x = x1; x <= x2; x++) {
setPixel(x,y,color);
}
}
void clearScreen(){
for (uint8_t i=0; i<128; i++) // buffer size
{
buffer[i].R=0;
buffer[i].G=0;
}
}
// helper function to paint one row
void shiftOut(uint8_t row) {
const uint8_t bitRed = digitalPinToBitMask(pinRed);
volatile uint8_t *outRed = portOutputRegister(digitalPinToPort(pinRed));
const uint8_t bitGreen = digitalPinToBitMask(pinGreen);
volatile uint8_t *outGreen = portOutputRegister(digitalPinToPort(pinGreen));
const uint8_t bitClock = digitalPinToBitMask(pinClock);
volatile uint8_t *outClock = portOutputRegister(digitalPinToPort(pinClock));
const uint8_t bitRowA = digitalPinToBitMask(pinRowA);
volatile uint8_t *outRowA = portOutputRegister(digitalPinToPort(pinRowA));
const uint8_t bitRowB = digitalPinToBitMask(pinRowB);
volatile uint8_t *outRowB = portOutputRegister(digitalPinToPort(pinRowB));
const uint8_t bitRowC = digitalPinToBitMask(pinRowC);
volatile uint8_t *outRowC = portOutputRegister(digitalPinToPort(pinRowC));
const uint8_t bitRowD = digitalPinToBitMask(pinRowD);
volatile uint8_t *outRowD = portOutputRegister(digitalPinToPort(pinRowD));
const uint8_t bitOE = digitalPinToBitMask(pinOE);
volatile uint8_t *outOE = portOutputRegister(digitalPinToPort(pinOE));
const uint8_t bitSTB = digitalPinToBitMask(pinSTB);
volatile uint8_t *outSTB = portOutputRegister(digitalPinToPort(pinSTB));
*outOE |= bitOE; // Turn off display // digitalWrite(pinOE,HIGH);
// select row
if (bitRead(row, 0)) *outRowA |= bitRowA; else *outRowA &= ~bitRowA;
if (bitRead(row, 1)) *outRowB |= bitRowB; else *outRowB &= ~bitRowB;
if (bitRead(row, 2)) *outRowC |= bitRowC; else *outRowC &= ~bitRowC;
if (bitRead(row, 3)) *outRowD |= bitRowD; else *outRowD &= ~bitRowD;
for(uint8_t column=0; column<8; column++){ // 8 segments
uint8_t index = column + (row*8); // 8 segments
for(uint8_t i=0; i<8; i++) {
if (buffer[index].R & (1<<(7-i))) *outRed &= ~bitRed;
else *outRed |= bitRed;
if (buffer[index].G & (1<<(7-i))) *outGreen &= ~bitGreen;
else *outGreen |= bitGreen;
//Clock Pulse
*outClock |= bitClock; //CLK, HIGH
*outClock &= ~bitClock; //CLK, LOW
}
}
*outSTB &= ~bitSTB; // digitalWrite(pinSTB,LOW);
*outSTB |= bitSTB; // digitalWrite(pinSTB,HIGH);
*outOE &= ~bitOE; // Turn on display // digitalWrite(pinOE,LOW);
}
// interrupt routine is responsible for painting the screen
ISR(TIMER2_COMPA_vect){
cli();
shiftOut(scanRow);
if (scanRow < 15) scanRow++; else scanRow = 0;
sei();
}
void setup() {
// use timer2 as the scanning interrupt timer
cli(); // clear interrupts
TCCR2A = 0; TCCR2B = 0; TCNT2 = 0;
TCCR2B |= (1 << CS12) | (1 << CS10); // Set 1024 prescaler
// 160Hz scan rate = 10 frames/second (16 rows)
OCR2A = 97; // 97 = (16,000,000 / (1024*160)) - 1
TCCR2A |= (1 << WGM21); TIMSK2 |= (1 << OCIE2A);
pinMode(pinRed, OUTPUT);
pinMode(pinGreen, OUTPUT);
pinMode(pinClock, OUTPUT);
pinMode(pinRowA, OUTPUT);
pinMode(pinRowB, OUTPUT);
pinMode(pinRowC, OUTPUT);
pinMode(pinRowD, OUTPUT);
pinMode(pinOE, OUTPUT);
pinMode(pinSTB, OUTPUT);
digitalWrite(pinOE, LOW);
digitalWrite(pinRed, HIGH); digitalWrite(pinGreen, HIGH);
sei(); //allow interrupts
}
// main loop is responsible for updating the screen
void loop() {
// printChar(0,GREEN,BLACK,'A');
hScroll(RED,BLACK, message);
}
Thanks,
Simon