Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

(Solved)Again problem with matrix, this time 8x32

Status
Not open for further replies.
Doggy, I used serial port to debug on where in fontmap is it reading for fontmap: this is from working matrix and indeed it reads like should for character 5:
C:
void charput(unsigned char ch, signed char x, signed char y)
{
  signed char x1, y1;
  unsigned char disp;
  unsigned char disp2;
  for ( x1 = 0; x1 < 8; x1++) // eight rows
  {
  disp = font[x1 + (ch * 8)];
  Serial.println(disp, HEX);
  for (y1 = 0; y1 < 8; y1++) // eight pixels
  {
  disp2 = disp & power[y1];
  if (disp2 > 0)
  {
  pixel(x + x1, y + y1, 0); // OR the pixel to the display buffer
  }
  }

  }
}
and output with hex values (as fontmap used also hex so easier to compare)
matrix fontmap debug.png

now then, this new one, it READS from current place from fontmap, but draws 0 on all values between 0-9, but find correct value on fontmap according to serial monitor o_O? so halfway it works, like reading english but talking japanese lol
C:
void charput(unsigned char ch, signed char x, signed char y)
{
  signed char y1;
  unsigned char disp;
  unsigned char disp2;
  //for ( x1 = 0; x1 < 8; x1++)  // eight rows, still eight bits to load so no changes
  //{
  //  disp = font[x1 + (ch * 8)];

  disp = font[ch];
  Serial.println(disp,BIN);  //display as BINARY format (Bxxxxxxxx) as fontmap is in binary format
  for (y1 = 0; y1 < 8; y1++)  // eight pixels
  {
  disp2 = disp & power[y1];
  if (disp2 > 0)
  {
  //pixel(x + x1, y + y1, 0);  // OR the pixel to the display buffer

  pixel(x, y + y1, 0); // OR the pixel to the display buffer
  }
  }
  //}
}
and here's reading:
7segment fontmap debug.png
and full code:
C:
#include "FontMap7Segment.h"

int dataPin = 2; // ic: 14, ser_in Define which pins will be used for the Shift Register control
int latchPin = 3; // ic:12 silkscreen numbers!
int clockPin = 4;


unsigned char displayPointer = 0; // for interrupt use...
unsigned char buffer1[4]; // buffer for screen, was 32 for matrix (4x8=32 and each character is built from 8x8 block, due 8x8 matrix) but for 7 segments, each character is 1x8 and screen is 4 digits so buffers are 4
unsigned char backbuffer[4]; // Spare screen for drawing on
unsigned char power[4] = {1, 2, 4, 8}; //B00000001,B00000010,B00000100,B00001000 for digits
// was: unsigned char power[8] = {128, 64, 32, 16, 8, 4, 2, 1};




ISR(TIMER1_COMPA_vect) // timer compare interrupt service routine, called every now and then, outside of loop
{
  if (TIFR2) // Make sure its the timer interrupt.
  {
  setcolumn(displayPointer);  //column scanning
  setdata(buffer1[displayPointer]);
  PORTD = (1 << PORTD3);
  PORTD = (0 << PORTD3);

  //digitalWrite(latchPin ,HIGH);
  //digitalWrite(latchPin , LOW ); // STORECLOCK

  if (++displayPointer == 4)  //was 32, now 4 as buffer sizes changed too
  { displayPointer = 0;
  } // 32 LED row sections in total
  }
  TIFR2 = 0; // Clear timer 2 interrupt flag
}



void setcolumn(unsigned char col)  //loop that takes care of column scanning
{
  signed char pos;
  for (pos = 4; pos > -1; pos--)  //was pos=32, but again, only 4 columns now so pos=4
  {
  if (col == pos)
  {
  PORTD = (1 << PORTD2);  //digitalWrite(dataPin ,HIGH);  //swapping these reversed unlit-lit digits
  }
  else
  {
  PORTD = (0 << PORTD2);  //digitalWrite(dataPin ,LOW);
  }
  digitalWrite(clockPin , HIGH);
  digitalWrite(clockPin , LOW);
  }
}



void setdata(unsigned char dat) {
  unsigned char pos;
  for (pos = 0; pos < 8; pos++)
  {
  if (dat & 128)  //these dat were 128, but changed them to 16 as 16=128/8
  {
  dat -= 128;
  PORTD = (1 << PORTD2);  //digitalWrite(dataPin ,HIGH);  //swapping these caused whole screen to be reversed for lit-unlit segments
  }
  else
  {
  PORTD = (0 << PORTD2);  //digitalWrite(dataPin ,LOW);} // PIN1 DATA pin
  }
  dat = dat * 2;
  digitalWrite(clockPin , HIGH);
  digitalWrite(clockPin , LOW);
  }
}



void clr() //clear
{
  int addr;
  for (addr = 0; addr < 4; addr++)  // Empty display buffer, reduced from 32 to 4
  backbuffer[addr] = 0;
}




void Blit()  //transfers data between display buffer to screen buffer
{
  int addr = 0;
  noInterrupts();  // disable all interrupts during setup
  for (addr = 0; addr < 4; addr ++)  //here also changed 32 to 4
  {
  buffer1[addr] = backbuffer[addr];  // put all data from display buffer to screen buffer
  }
  interrupts();  // enable all interrupts
}


void pixel(signed char x, signed char y, int cond)
{
  unsigned char pix, msk;
  if (x < 0 || y < 0) return;  // outside drawing limits negative
  if (x > 3 || y > 7) return;  // outside drawing limits positive, changed x>31 to x>3
  pix = power[y];
  msk = backbuffer[x];  // get exsisting data
  if (cond == 2)
  pix ^= msk;  // XOR data to screen
  if (cond == 1)
  {
  pix = ~pix;
  pix &= msk;  // AND data to screen
  }
  if (cond == 0)
  pix |= msk;  // OR data to screen
  backbuffer[x] = pix;  // apply changes
}



void charput(unsigned char ch, signed char x, signed char y)
{
  signed char y1;
  unsigned char disp;
  unsigned char disp2;
  //for ( x1 = 0; x1 < 8; x1++)  // eight rows, still eight bits to load so no changes
  //{
  //  disp = font[x1 + (ch * 8)];

  disp = font[ch];
  Serial.println(disp,BIN);  //display as BINARY format (Bxxxxxxxx) as fontmap is in binary format
  for (y1 = 0; y1 < 8; y1++)  // eight pixels
  {
  disp2 = disp & power[y1];
  if (disp2 > 0)
  {
  //pixel(x + x1, y + y1, 0);  // OR the pixel to the display buffer

  pixel(x, y + y1, 0); // OR the pixel to the display buffer
  }
  }
  //}
}



void strput(const char* ch, signed char x, signed char y)
{
  int addr;
  while (*ch )
  {
  charput(*ch++, x, y);  // write a string to the display buffer
  x += 7;
  }
}



void setup() //setup runs once
{
  Serial.begin(9600);
  signed char cntr;
  noInterrupts();  // disable all interrupts during setup
  DDRD = DDRD | B11111100;  //port registers used to set pin directions
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1 = 0;
  OCR1A = 260;  // compare match register value, was 31 for matrix (1920hz= 60hzx*32) but for now there's only 4 columns so: 4*60hz=240hz; 16mhz/256/240=260
  TCCR1B |= (1 << WGM12);  // CTC mode, free-running, clear on match
  TCCR1B |= (0 << CS10);  // 256 prescaler
  TCCR1B |= (0 << CS11);  // 256 prescaler
  TCCR1B |= (1 << CS12);  // 256 prescaler
  TIMSK1 |= (1 << OCIE1A);  // enable timer compare interrupt
  interrupts();  // enable all interrupts

} // End main



void loop()  //main loop
{
  clr();
  charput(5, 0, 0);  //test string to draw on segments //should show character 5 on hundreds digit
  Blit();
}
 
Here's most up-date code, segments a and c are lit on digit 0, changed, all power[] stuff that tries to exceed array size:
C:
#include "FontMap7Segment.h"

int dataPin = 2; // ic: 14, ser_in Define which pins will be used for the Shift Register control
int latchPin = 3; // ic:12 silkscreen numbers!
int clockPin = 4;


unsigned char displayPointer = 0; // for interrupt use...
unsigned char buffer1[4]; // buffer for screen
unsigned char backbuffer[4]; // Spare screen for drawing on
unsigned char power[4] = {8, 4, 2, 1};

ISR(TIMER1_COMPA_vect) // timer compare interrupt service routine, called every now and then, outside of loop
{
  if (TIFR2) // Make sure its the timer interrupt.
  {
  setcolumn(displayPointer);  //column scanning
  setdata(buffer1[displayPointer]);
  PORTD = (1 << PORTD3);
  PORTD = (0 << PORTD3);

  //digitalWrite(latchPin ,HIGH);
  //digitalWrite(latchPin , LOW ); // STORECLOCK

  if (++displayPointer == 4)
  { displayPointer = 0;
  } // 32 LED row sections in total
  }
  TIFR2 = 0; // Clear timer 2 interrupt flag
}

void setcolumn(unsigned char col)  //loop that takes care of column scanning
{
  signed char pos;
  for (pos = 8; pos > -1; pos--)
  {
  if (col == pos)
  {
  PORTD = (1 << PORTD2);
  //digitalWrite(dataPin ,HIGH);
  }
  else
  {
  PORTD = (0 << PORTD2);
  //digitalWrite(dataPin ,LOW);
  } // PIN1 DATA pin
  //PORTD=(1<<PORTD4);
  //PORTD=(0<<PORTD4);

  digitalWrite(clockPin , HIGH);
  digitalWrite(clockPin , LOW);
  }
}



void setdata(unsigned char dat) {
  unsigned char pos;
  for (pos = 0; pos < 8; pos++)
  {
  if (dat & 128)
  {
  dat -= 128;
  PORTD = (1 << PORTD2);
  //digitalWrite(dataPin ,HIGH);
  }
  else
  {
  PORTD = (0 << PORTD2);
  }
  //digitalWrite(dataPin ,LOW);} // PIN1 DATA pin
  dat = dat * 2;
  digitalWrite(clockPin , HIGH);
  digitalWrite(clockPin , LOW);
  }
}
void clr() //clear
{
  int addr;
  for (addr = 0; addr < 4; addr++) // Empty display buffer
  backbuffer[addr] = 0;
}

void Blit() //transfers data between display buffer to screen buffer
{
  int addr = 0;
  noInterrupts(); // disable all interrupts during setup
  for (addr = 0; addr < 4; addr ++)
  {
  buffer1[addr] = backbuffer[addr]; // put all data from display buffer
  } // to screen buffer
  interrupts(); // enable all interrupts
}

void pixel(signed char x, signed char y, int cond)
{
  unsigned char pix, msk;
  if (x < 0 || y < 0) return; // outside drawing limits negative
  if (x > 3 || y > 3) return; // outside drawing limits positive
  pix = power[y];
  msk = backbuffer[x]; // get exsisting data


  if (cond == 2)
  pix ^= msk; // XOR data to screen
  if (cond == 1)
  {
  pix = ~pix;
  pix &= msk; // AND data to screen
  }
  if (cond == 0)
  pix |= msk; // OR data to screen
  backbuffer[x] = pix; // apply changes
}





void charput(unsigned char ch, signed char x, signed char y)
{
  signed char x1, y1;
  unsigned char disp;
  unsigned char disp2;
  //for ( x1 = 0; x1 < 8; x1++) // eight rows
  //{
  disp = font[ch];
  // Serial.println(disp,BIN);
  for (y1 = 0; y1 < 4; y1++) // eight pixels
  {
  disp2 = disp & power[y1];
  if (disp2 > 0)
  {
  pixel(x, y + y1, 0); // OR the pixel to the display buffer
  }
  }
  //}
}








/*
  void strput(const char* ch, signed char x,signed char y)
  {
  int addr;
  while (*ch )
  {
  charput(*ch++,x,y); // write a string to the display buffer
  x+=7;
  }
  }*/



void setup() //setup runs once
{
  signed char cntr;
  Serial.begin(9600);
  noInterrupts(); // disable all interrupts during setup
  DDRD = DDRD | B11111100; //port registers used to set pin directions
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1 = 0;
  OCR1A = 31; // compare match register 16MHz/256/2Hz -----------------------------------> delay time (lcd flicker/brightness)
  TCCR1B |= (1 << WGM12); // CTC mode, free-running, clear on match
  TCCR1B |= (0 << CS10); // 256 prescaler
  TCCR1B |= (0 << CS11); // 256 prescaler
  TCCR1B |= (1 << CS12); // 256 prescaler
  TIMSK1 |= (1 << OCIE1A); // enable timer compare interrupt
  interrupts(); // enable all interrupts

} // End main

void loop() //just sitting here
{

  clr();
  charput(5, 0, 0);
  Blit();



}
 
same with the power variable, it should remain 128
oops, didn't read this one, which was THE reason it didn't work! wohoo! Thanks again! A lot!
 
Last edited:
Only now I can't figure out why only one segment is lit?
C:
#include "FontMap7Segment.h"

int dataPin = 2; // ic: 14, ser_in Define which pins will be used for the Shift Register control
int latchPin = 3; // ic:12 silkscreen numbers!
int clockPin = 4;


unsigned char displayPointer = 0; // for interrupt use...
unsigned char buffer1[4]; // buffer for screen, was 32 for matrix (4x8=32 and each character is built from 8x8 block, due 8x8 matrix) but for 7 segments, each character is 1x8 and screen is 4 digits so buffers are 4
unsigned char backbuffer[4]; // Spare screen for drawing on
//unsigned char power[8] = {1, 2, 4, 8,16,32,64,128}; //B00000001,B00000010,B00000100,B00001000 for digits
unsigned char power[8] = {128, 64, 32, 16, 8, 4, 2, 1};




ISR(TIMER1_COMPA_vect) // timer compare interrupt service routine, called every now and then, outside of loop
{
  if (TIFR2) // Make sure its the timer interrupt.
  {
  setcolumn(displayPointer);  //column scanning
  setdata(buffer1[displayPointer]);
  PORTD = (1 << PORTD3);
  PORTD = (0 << PORTD3);

  //digitalWrite(latchPin ,HIGH);
  //digitalWrite(latchPin , LOW ); // STORECLOCK

  if (++displayPointer == 4)  //was 32, now 4 as buffer sizes changed too
  { displayPointer = 0;
  } // 32 LED row sections in total
  }
  TIFR2 = 0; // Clear timer 2 interrupt flag
}



void setcolumn(unsigned char col)  //loop that takes care of column scanning
{
  signed char pos;
  for (pos = 4; pos > -1; pos--)  //was pos=32, but again, only 4 columns now so pos=4
  {
  if (col == pos)
  {
  PORTD = (1 << PORTD2);  //digitalWrite(dataPin ,HIGH);  //swapping these reversed unlit-lit digits
  }
  else
  {
  PORTD = (0 << PORTD2);  //digitalWrite(dataPin ,LOW);
  }
  digitalWrite(clockPin , HIGH);
  digitalWrite(clockPin , LOW);
  }
}



void setdata(unsigned char dat) {
  unsigned char pos;
  for (pos = 0; pos < 8; pos++)
  {
  if (dat & 128)  //these dat were 128, but changed them to 16 as 16=128/8
  {
  dat -= 128;
  PORTD = (1 << PORTD2);  //digitalWrite(dataPin ,HIGH);  //swapping these caused whole screen to be reversed for lit-unlit segments
  }
  else
  {
  PORTD = (0 << PORTD2);  //digitalWrite(dataPin ,LOW);} // PIN1 DATA pin
  }
  dat = dat * 2;
  digitalWrite(clockPin , HIGH);
  digitalWrite(clockPin , LOW);
  }
}



void clr() //clear
{
  int addr;
  for (addr = 0; addr < 4; addr++)  // Empty display buffer, reduced from 32 to 4
  backbuffer[addr] = 0;
}




void Blit()  //transfers data between display buffer to screen buffer
{
  int addr = 0;
  noInterrupts();  // disable all interrupts during setup
  for (addr = 0; addr < 4; addr ++)  //here also changed 32 to 4
  {
  buffer1[addr] = backbuffer[addr];  // put all data from display buffer to screen buffer
  }
  interrupts();  // enable all interrupts
}


void pixel(signed char x, signed char y, int cond)
{
  unsigned char pix, msk;
  if (x < 0 || y < 0) return;  // outside drawing limits negative
  if (x > 3 || y > 7) return;  // outside drawing limits positive, changed x>31 to x>3
  pix = power[y];
  msk = backbuffer[x];  // get exsisting data
  if (cond == 2)
  pix ^= msk;  // XOR data to screen
  if (cond == 1)
  {
  pix = ~pix;
  pix &= msk;  // AND data to screen
  }
  if (cond == 0)
  pix |= msk;  // OR data to screen
  backbuffer[x] = pix;  // apply changes
}



void charput(unsigned char ch, signed char x, signed char y)
{
  signed char y1;
  unsigned char disp;
  unsigned char disp2;

  disp = font[ch];

  for (y1 = 0; y1 < 7; y1++)  // eight pixels
  {
  disp2 = disp & power[y1];
  if (disp2 > 0)
  {
  pixel(x, y + y1, 0);  // OR the pixel to the display buffer

  }
  }

}



void strput(const char* ch, signed char x, signed char y)
{
  int addr;
  while (*ch )
  {
  charput(*ch++, x, y);  // write a string to the display buffer
  x += 7;
  }
}



void setup() //setup runs once
{
  Serial.begin(9600);
  signed char cntr;
  noInterrupts();  // disable all interrupts during setup
  DDRD = DDRD | B11111100;  //port registers used to set pin directions
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1 = 0;
  OCR1A = 260;  // compare match register value, was 31 for matrix (1920hz= 60hzx*32) but for now there's only 4 columns so: 4*60hz=240hz; 16mhz/256/240=260
  TCCR1B |= (1 << WGM12);  // CTC mode, free-running, clear on match
  TCCR1B |= (0 << CS10);  // 256 prescaler
  TCCR1B |= (0 << CS11);  // 256 prescaler
  TCCR1B |= (1 << CS12);  // 256 prescaler
  TIMSK1 |= (1 << OCIE1A);  // enable timer compare interrupt
  interrupts();  // enable all interrupts

} // End main



void loop()  //main loop
{
  int val = millis() / 1000 % 10;
  clr();
  charput(val, 2, 0);  //test string to draw on segments //should show character 5 on hundreds digit
  Blit();
}
 
setcolumn need to be changed back as well, because the shift register is 8bit
for (pos = 8; pos > -1; pos--)
 
also try testing with this:


void loop() //just sitting here
{

clr();
charput(0, 0, 0);
charput(1, 1, 0);
charput(2, 2, 0);
charput(3, 3, 0);
Blit();
}
 
hehe, seems that millis() thing i tried earlier worked as intended, I told it to draw only one digit....so this works:
C:
void loop() //just sitting here
{

clr();
charput(0, 0, 0);
charput(1, 1, 0);
charput(2, 2, 0);
charput(3, 3, 0);
Blit();
}
this works (just counter):
C:
void loop() //just sitting here
{
 int val = millis();
  clr();
  charput(val % 10, 0, 0);
  charput(val / 10 % 10, 1, 0);
  charput(val / 100 % 10, 2, 0);
  charput(val / 1000 % 10, 3, 0);
  Blit();
}
but this won't work:
C:
void loop() //just sitting here
{
  clr();
  strput("0123", 0, 0);  //neither works, no string seen, only 0 on selected start digit
  //strput("0123",3,0);
  Blit();
}
again, full code:
C:
#include "FontMap7Segment.h"

int dataPin = 2; // ic: 14, ser_in Define which pins will be used for the Shift Register control
int latchPin = 3; // ic:12 silkscreen numbers!
int clockPin = 4;


unsigned char displayPointer = 0; // for interrupt use...
unsigned char buffer1[4]; // buffer for screen, was 32 for matrix (4x8=32 and each character is built from 8x8 block, due 8x8 matrix) but for 7 segments, each character is 1x8 and screen is 4 digits so buffers are 4
unsigned char backbuffer[4]; // Spare screen for drawing on
//unsigned char power[8] = {1, 2, 4, 8,16,32,64,128}; //B00000001,B00000010,B00000100,B00001000 for digits
unsigned char power[8] = {128, 64, 32, 16, 8, 4, 2, 1};




ISR(TIMER1_COMPA_vect) // timer compare interrupt service routine, called every now and then, outside of loop
{
  if (TIFR2) // Make sure its the timer interrupt.
  {
  setcolumn(displayPointer);  //column scanning
  setdata(buffer1[displayPointer]);
  PORTD = (1 << PORTD3);
  PORTD = (0 << PORTD3);

  //digitalWrite(latchPin ,HIGH);
  //digitalWrite(latchPin , LOW ); // STORECLOCK

  if (++displayPointer == 4)  //was 32, now 4 as buffer sizes changed too
  { displayPointer = 0;
  } // 32 LED row sections in total
  }
  TIFR2 = 0; // Clear timer 2 interrupt flag
}



void setcolumn(unsigned char col)  //loop that takes care of column scanning
{
  signed char pos;
  for (pos = 8; pos > -1; pos--)  //was pos=32, but again, only 4 columns now so pos=4
  {
  if (col == pos)
  {
  PORTD = (1 << PORTD2);  //digitalWrite(dataPin ,HIGH);  //swapping these reversed unlit-lit digits
  }
  else
  {
  PORTD = (0 << PORTD2);  //digitalWrite(dataPin ,LOW);
  }
  digitalWrite(clockPin , HIGH);
  digitalWrite(clockPin , LOW);
  }
}



void setdata(unsigned char dat) {
  unsigned char pos;
  for (pos = 0; pos < 8; pos++)
  {
  if (dat & 128)  //these dat were 128, but changed them to 16 as 16=128/8
  {
  dat -= 128;
  PORTD = (1 << PORTD2);  //digitalWrite(dataPin ,HIGH);  //swapping these caused whole screen to be reversed for lit-unlit segments
  }
  else
  {
  PORTD = (0 << PORTD2);  //digitalWrite(dataPin ,LOW);} // PIN1 DATA pin
  }
  dat = dat * 2;
  digitalWrite(clockPin , HIGH);
  digitalWrite(clockPin , LOW);
  }
}



void clr() //clear
{
  int addr;
  for (addr = 0; addr < 4; addr++)  // Empty display buffer, reduced from 32 to 4
  backbuffer[addr] = 0;
}




void Blit()  //transfers data between display buffer to screen buffer
{
  int addr = 0;
  noInterrupts();  // disable all interrupts during setup
  for (addr = 0; addr < 4; addr ++)  //here also changed 32 to 4
  {
  buffer1[addr] = backbuffer[addr];  // put all data from display buffer to screen buffer
  }
  interrupts();  // enable all interrupts
}


void pixel(signed char x, signed char y, int cond)
{
  unsigned char pix, msk;
  if (x < 0 || y < 0) return;  // outside drawing limits negative
  if (x > 3 || y > 7) return;  // outside drawing limits positive, changed x>31 to x>3
  pix = power[y];
  msk = backbuffer[x];  // get exsisting data
  if (cond == 2)
  pix ^= msk;  // XOR data to screen
  if (cond == 1)
  {
  pix = ~pix;
  pix &= msk;  // AND data to screen
  }
  if (cond == 0)
  pix |= msk;  // OR data to screen
  backbuffer[x] = pix;  // apply changes
}



void charput(unsigned char ch, signed char x, signed char y)
{
  signed char y1;
  unsigned char disp;
  unsigned char disp2;

  disp = font[ch];

  for (y1 = 0; y1 < 7; y1++)  // eight pixels
  {
  disp2 = disp & power[y1];
  if (disp2 > 0)
  {
  pixel(x, y + y1, 0);  // OR the pixel to the display buffer

  }
  }

}



void strput(const char* ch, signed char x, signed char y)
{
  int addr;
  while (*ch )
  {
  charput(*ch++, x, y);  // write a string to the display buffer
  x += 7;
  }
}



void setup() //setup runs once
{
  Serial.begin(9600);
  signed char cntr;
  noInterrupts();  // disable all interrupts during setup
  DDRD = DDRD | B11111100;  //port registers used to set pin directions
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1 = 0;
  OCR1A = 260;  // compare match register value, was 31 for matrix (1920hz= 60hzx*32) but for now there's only 4 columns so: 4*60hz=240hz; 16mhz/256/240=260
  TCCR1B |= (1 << WGM12);  // CTC mode, free-running, clear on match
  TCCR1B |= (0 << CS10);  // 256 prescaler
  TCCR1B |= (0 << CS11);  // 256 prescaler
  TCCR1B |= (1 << CS12);  // 256 prescaler
  TIMSK1 |= (1 << OCIE1A);  // enable timer compare interrupt
  interrupts();  // enable all interrupts

} // End main



void loop() //just sitting here
{
  clr();
  strput("0123", 0, 0);  //neither works, no string seen, only 0 on selected start digit
  //strput("0123",3,0);
  Blit();
}
 
Thanks again doggy, it was close, in fact yet again you made my day, it showed 8, but I tried:
C:
  x += 1;
and that did trick, now it accepts strings, wee! :)
 
Started similar chore for 14-segment displays, not sure if it's even possible since we were dealing with 8-rows but now there's 14.....then again, matrix worked also (this 14 segments seems to be another chore, but I don't feel like putting 8x8 matrix for my car...(after this I'll drop this subject hopefully....)
C:
#include "FontMap14Segment.h"

int dataPin = 2; // ic: 14, ser_in Define which pins will be used for the Shift Register control
int latchPin = 3; // ic:12 silkscreen numbers!
int clockPin = 4;


unsigned char displayPointer = 0; // for interrupt use...
unsigned char buffer1[4]; //2x8 bits
unsigned char backbuffer[4]; // Spare screen for drawing on
//unsigned char power[8] = {1, 2, 4, 8,16,32,64,128}; //B00000001,B00000010,B00000100,B00001000 for digits
unsigned char power[8] = {128, 64, 32, 16, 8, 4, 2, 1};



ISR(TIMER1_COMPA_vect) // timer compare interrupt service routine, called every now and then, outside of loop
{
  if (TIFR2) // Make sure its the timer interrupt.
  {
  setcolumn(displayPointer);  //column scanning
  setdata(buffer1[displayPointer]);
  PORTD = (1 << PORTD3);
  PORTD = (0 << PORTD3);

  //digitalWrite(latchPin ,HIGH);
  //digitalWrite(latchPin , LOW ); // STORECLOCK

  if (++displayPointer == 4)  //4 because there are two digits, each need 2x8 bits
  { displayPointer = 0;
  } // 32 LED row sections in total
  }
  TIFR2 = 0; // Clear timer 2 interrupt flag
}



void setcolumn(unsigned char col)  //loop that takes care of column scanning
{
  signed char pos;
  for (pos =8; pos > -1; pos--)  //was pos=32, but again, only 4 columns now so pos=4
  {
  if (col == pos)
  {
  PORTD = (1 << PORTD2);  //digitalWrite(dataPin ,HIGH);  //swapping these reversed unlit-lit digits
  }
  else
  {
  PORTD = (0 << PORTD2);  //digitalWrite(dataPin ,LOW);
  }
  digitalWrite(clockPin , HIGH);
  digitalWrite(clockPin , LOW);
  }
}



void setdata(unsigned char dat) {
  unsigned char pos;
  for (pos = 0; pos < 8; pos++)
  {
  if (dat & 128)  //these dat were 128, but changed them to 16 as 16=128/8
  {
  dat -= 128;
  PORTD = (1 << PORTD2);  //digitalWrite(dataPin ,HIGH);  //swapping these caused whole screen to be reversed for lit-unlit segments
  }
  else
  {
  PORTD = (0 << PORTD2);  //digitalWrite(dataPin ,LOW);} // PIN1 DATA pin
  }
  dat = dat * 2;
  digitalWrite(clockPin , HIGH);
  digitalWrite(clockPin , LOW);
  }
}



void clr() //clear
{
  int addr;
  for (addr = 0; addr < 4; addr++)  // Empty display buffer, reduced from 32 to 4
  backbuffer[addr] = 0;
}




void Blit()  //transfers data between display buffer to screen buffer
{
  int addr = 0;
  noInterrupts();  // disable all interrupts during setup
  for (addr = 0; addr < 4; addr ++)  //here also changed 32 to 4
  {
  buffer1[addr] = backbuffer[addr];  // put all data from display buffer to screen buffer
  }
  interrupts();  // enable all interrupts
}


void pixel(signed char x, signed char y, int cond)
{
  unsigned char pix, msk;
  if (x < 0 || y < 0) return;  // outside drawing limits negative
  if (x > 1 || y > 15) return;  // outside drawing limits positive
  pix = power[y];
  msk = backbuffer[x];  // get exsisting data
  if (cond == 2)
  pix ^= msk;  // XOR data to screen
  if (cond == 1)
  {
  pix = ~pix;
  pix &= msk;  // AND data to screen
  }
  if (cond == 0)
  pix |= msk;  // OR data to screen
  backbuffer[x] = pix;  // apply changes
}



void charput(unsigned char ch, signed char x, signed char y)
{
  signed char x1, y1;
  unsigned char disp;
  unsigned char disp2;
  for (int x1 = 0; x1 < 2; x++)
  {
  disp = font[x1 + (ch + 2)]; //look data from fontmap,
  Serial.println(disp, BIN);
  for (y1 = 0; y1 < 7; y1++)  // eight pixels
  {
  disp2 = disp & power[y1];
  if (disp2 > 0)
  {
  pixel(x + x1, y + y1, 0); // OR the pixel to the display buffer
  }
  }
  }

}


/*
  void strput(const char* ch, signed char x, signed char y)
  {
  int addr;
  while (*ch )
  {
  charput(*ch++, x, y);  // write a string to the display buffer
  x += 1;
  }
  }*/






void setup() //setup runs once
{
  Serial.begin(9600);

  noInterrupts();  // disable all interrupts during setup
  DDRD = DDRD | B11111100;  //port registers used to set pin directions
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1 = 0;
  OCR1A = 520;  // compare match register value, was 31 for matrix (1920hz= 60hzx*32) but for now there's only 4 columns so: 4*60hz=240hz; 16mhz/256/240=260
  TCCR1B |= (1 << WGM12);  // CTC mode, free-running, clear on match
  TCCR1B |= (0 << CS10);  // 256 prescaler
  TCCR1B |= (0 << CS11);  // 256 prescaler
  TCCR1B |= (1 << CS12);  // 256 prescaler
  TIMSK1 |= (1 << OCIE1A);  // enable timer compare interrupt
  interrupts();  // enable all interrupts

} // End main



void loop() //just sitting here
{
  clr();
  charput(5,  0, 0);
  Blit();
}
Also, font map isn't read at right position either yet, only one value and wrong one:
14  segment.png
It's late here, I'm off, tell if you see any obvious :)...
 

Attachments

  • FontMap14Segment.h
    4.9 KB · Views: 242
no worry, its fun messing round with these little things,
disp = font[x1 + (ch + 2)]; //look data from fontmap,
should be
disp = font[x1 + (ch * 2)]; //look data from fontmap,
its always something small.....

as for other question , all that really matters is that you have enough pins available in shift register, if you had 4x4 matrix you could put 4 pins on anode and other 4 on cathode, using only 1 register, for simplicity its better to keep all anodes together, and all cathodes together, in case of common cathode, it also makes simpler to keep cathode pins in order.....

Having said that, you could wire it to go anode,cathode, anode,cathode...ect.... BUt then code needs to reflect that, which is why grouping simplifies.....

have you looked at shift register data sheet, all that happens is that when you pulse the shift clock it takes info from datapin and puts it to buffer1, and moves buffer1 data to buffer2... and Shifts everything once down the line! so if you put 1 at output, after 15-16 shift pulses it will wind up at the end of second register
 
I tend to use same wiring for all these displays that use shifters, first from micro handles rows and rest columns with darlingtons, easier than bunch of transistors and resistors. And having one habit of wiring makes things easier to memorize. I know how sifters work, thanks for telling what code does that! This code is much easier method IMO than to use shiftout method.
 
Ok, that fixed fontmap problem now it looks font at right position, so again halfway there.
14  segmentfontmap_ok.png
But, now issue is that wrong digit is lit, and wrong segment, even thought wirings are correct. To be specific, right digit should be lit, but left is lit, and segment that is wrongly lit is H instead of G1 and if i place 0 in H's place, nothing is lit at all...then I noticed that 5 there is thing in common between 5 and 7 in this case; both have B0000000 as their leftmost value in fontmap, as well as 0 o_O? But, when I place B00000001 asevery numbers first value from left, they all work, EXCEPT for #1 again connfusing....
also, when using this:
C:
int val=millis()/1000 % 10;
  clr();
charput(val,0,0);
  Blit();
numbers 0 and seven aren't drawn at all, blank.
C:
#include "FontMap14Segment.h"

int dataPin = 2;  //ic: 14, ser_in Define which pins will be used for the Shift Register control
int latchPin = 3;  // ic:12 silkscreen numbers!
int clockPin = 4;  //ic: 11


unsigned char displayPointer = 0;  //for interrupt use...
unsigned char buffer1[4];  // buffer for screen,4x8=32
unsigned char backbuffer[4];  //Spare screen for drawing on, 4x8=32
//unsigned char power[8] = {128, 64, 32, 16, 8, 4, 2, 1}; //for each column B10000000->B00000001
unsigned char power[8] = {1, 2, 4, 8, 16, 32, 64, 128}; //for each column B10000000->B00000001

ISR(TIMER1_COMPA_vect)  //timer compare interrupt service routine, called every now and then, outside of loop
{
  if (TIFR2)  //Make sure its the timer interrupt.
  {
  setcolumn(displayPointer);  //column scanning
  setdata(buffer1[displayPointer]);
  PORTD = (1 << PORTD3);  //digitalWrite(latchPin ,HIGH);
  PORTD = (0 << PORTD3);  //digitalWrite(latchPin , LOW )


  if (++displayPointer == 4)  //32 LED row sections in total
  { displayPointer = 0;
  }
  }
  TIFR2 = 0;  // Clear timer 2 interrupt flag
}



void setcolumn(unsigned char col)  //loop that takes care of column scanning
{
  signed char pos;
  for (pos = 8; pos > -1; pos--)
  {
  if (col == pos)
  {
  PORTD = (1 << PORTD2);  //digitalWrite(dataPin ,HIGH);
  }
  else
  {
  PORTD = (0 << PORTD2);  //digitalWrite(dataPin ,LOW);
  }
  digitalWrite(clockPin , HIGH);  //PORTD=(1<<PORTD4);
  digitalWrite(clockPin , LOW);  //PORTD=(0<<PORTD4);
  }
}



void setdata(unsigned char dat)
{
  unsigned char pos;
  for (pos = 0; pos < 8; pos++)
  {
  if (dat & 128)
  {
  dat -= 128;
  PORTD = (1 << PORTD2);//digitalWrite(dataPin ,HIGH);
  }
  else
  {
  PORTD = (0 << PORTD2);//digitalWrite(dataPin ,LOW);} // PIN1 DATA pin
  }
  dat = dat * 2;
  digitalWrite(clockPin , HIGH);
  digitalWrite(clockPin , LOW);
  }
}




void clr()  //clear display buffer
{
  int addr;
  for (addr = 0; addr < 4; addr++) // Empty display buffer
  backbuffer[addr] = 0;
}





void Blit()  //transfers data between display buffer to screen buffer
{
  int addr = 0;  //addr is counter integer for buffer swapping
  noInterrupts();  //disable all interrupts buffer swap
  for (addr = 0; addr < 4; addr ++)
  {
  buffer1[addr] = backbuffer[addr]; //put all data from display buffer to screen buffer
  }
  interrupts();  //enable all interrupts, buffers swapped
}





void pixel(signed char x, signed char y, int cond)
{
  unsigned char pix, msk;
  if (x < 0 || y < 0) return; // outside drawing limits negative
  if (x > 1 || y > 15) return; // outside drawing limits positive, x=32, y=8
  pix = power[y];
  msk = backbuffer[x]; // get exsisting data


  if (cond == 2)
  pix ^= msk; //XOR data to screen
  if (cond == 1)
  {
  pix = ~pix;
  pix &= msk; // AND data to screen
  }
  if (cond == 0)
  pix |= msk; // OR data to screen
  backbuffer[x] = pix; // apply changes
}




void charput(unsigned char ch, signed char x, signed char y)
{
  signed char x1, y1;
  unsigned char disp;
  unsigned char disp2;
  for ( x1 = 0; x1 < 2; x1++) // eight rows
  {
  disp = font[x1 + (ch * 2)]; //look data from fontmap,
  Serial.println(disp, BIN);
  for (y1 = 0; y1 < 8; y1++) // eight pixels
  {
  disp2 = disp & power[y1];
  if (disp2 > 0)
  {
  pixel(x + x1, y + y1, 0); // OR the pixel to the display buffer
  }
  }

  }
}

void strput(const char* ch, signed char x, signed char y)
{
  int addr;
  while (*ch )
  {
  charput(*ch++, x, y); //write a string to the display buffer
  x += 1;
  }
}



void setup() //setup runs once
{
  Serial.begin(9600);
  noInterrupts(); // disable all interrupts during setup
  DDRD = DDRD | B11111100; //port registers used to set pin directions
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1 = 0;
  OCR1A = 260; // for 14 segment display this speed must be 2x normal speed, since there are two sets / digit
  TCCR1B |= (1 << WGM12); // CTC mode, free-running, clear on match
  TCCR1B |= (0 << CS10); // 256 prescaler
  TCCR1B |= (0 << CS11); // 256 prescaler
  TCCR1B |= (1 << CS12); // 256 prescaler
  TIMSK1 |= (1 << OCIE1A); // enable timer compare interrupt
  interrupts(); // enable all interrupts

} // End main

void loop() //just sitting here
{


int val=millis()/1000 % 10;
  clr();
charput(val,0,0);
  Blit();



}
 
ya, confusing, got a photo to compare with codes sent? and data for 14seg wiring, problem is alignment in what you are shifting out, ie setdata,setcolumn need to be changed up a bit to reflect pinout config
 
Here's video with that counter (can't draw 7 even with strput())
 
I'm working on diagram, forgot it.....no, I can't affect second digit at all, even with x=1 or x=-1 values at charput().
 
Here's schematic(bit messy perhaps....):
14_segment.jpg
 
void setcolumn(unsigned char col) //loop that takes care of column scanning
{
signed char pos;
for (pos = 0; pos < 8; pos++)
{
if (col == pos)
{
PORTD = (1 << PORTD2); //digitalWrite(dataPin ,HIGH);
}
else
{
PORTD = (0 << PORTD2); //digitalWrite(dataPin ,LOW);
}
digitalWrite(clockPin , HIGH); //PORTD=(1<<PORTD4);
digitalWrite(clockPin , LOW); //PORTD=(0<<PORTD4);
}
}



void setdata(unsigned char dat)
{
unsigned char pos;
for (pos = 0; pos < 16; pos++)
{
if (dat & 32768)
{
dat -= 32768;
PORTD = (1 << PORTD2);//digitalWrite(dataPin ,HIGH);
}
else
{
PORTD = (0 << PORTD2);//digitalWrite(dataPin ,LOW);} // PIN1 DATA pin
}
dat = dat * 2;
digitalWrite(clockPin , HIGH);
digitalWrite(clockPin , LOW);
}
}
 
Last edited:
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top