Show Posts
Pages: [1]
1  Using Arduino / Programming Questions / dataconversion to slow for multiplexing led matrix on: April 13, 2012, 12:52:28 pm
I want to build a big rgb Led matrix. I also want it to be easy to write new functions for animations, games etc. Therefore I choose to use a array of byte with each byte representing a pixel in the led matrix. This way a function can easily write in this array using coordinates without worrying about the hardware design.

The hardware consists of shift registers. The first byte is for the rows, the next three bytes are for blue, red and green of the first 8x8x3 matrix, the next three bytes for the next display etc.

To display the image, the array needs to be translated into something the hardware can work with. This is basically copying the bits in a different order. When testing this on a 24x8x3 display it worked well, but i was in doubt about it being fast enough for bigger displays. therefore i tested the code for a 24x24x3 display. The code is to slow for a multiplexing display of this size.

Is there an easy way to get my code faster or do i need a different processor?

Code:
//this first line, was last edited on 2012-04-13
//author: peertje

//Hardware
//Number of horizontal 8x8 matrixes (Directly connected to each other)
const int hDisp = 3;
//Number of Vertical 8x8 matixes (Connected with some kind of special connector)
const int vDisp = 1;
//the total number of displays
const int numberOfDisplays = hDisp * vDisp;

// Interfacing with the hardware
//Pin connected to ST_CP of 74HC595
int latchPin = 8;
//Pin connected to SH_CP of 74HC595
int clockPin = 10;
//Pin connected to DS of 74HC595
int dataPin = 9;

//declaring the necesarry video memory
const int Heigth = 8 * vDisp;
const int Width = 8 * hDisp;
byte VideoMem [Heigth][Width]; // the value of a byte contains the color
// for now, only 3bit color is supported
// 0 = black
// 1 = Red
// 2 = Green
// 3 = Yellow (Red + Green)
// 4 = Blue
// 5 = Violet (Red + Blue)
// 6 = navy (Green + Blue)
// 7 = White (Red + Green + Blue)

//the low bit in this byte is the active hLine
byte hLine = B00000000; //During reset we want a low current, so all rows are off


void setup() {
  //start serialcommunication for debugging
  //Serial.begin(57600);
  //Serial.print("This display is ");
  //Serial.print(Heigth,DEC);
  //Serial.print(" x ");
  //Serial.println(Width,DEC);
  
  //Setting the used pins to Output
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);

  //empty the shiftregisters  
  digitalWrite(latchPin, LOW);
  for(int i=0; i<(numberOfDisplays *3); i++){
    shiftOut(dataPin, clockPin,LSBFIRST, 0);
  }
  shiftOut(dataPin, clockPin, MSBFIRST, hLine);
  digitalWrite(latchPin, HIGH);
  
  //draw something for a nice test screen
  cross();
  square();
}

void loop() {
  
  //the array containing the outputdata
  byte SerialOutput [numberOfDisplays*3];
  boolean buffer;
  
  //Show one row at the time
  for (int iRow = 0; iRow<8; iRow++)
  {
    hLine = 0;
    bitWrite(hLine,iRow,true);
    
    //filling the ouputdata array
    int bytenr = 0;
    //Read some of the video memory and define the outputdata
    for (int y = vDisp; y>0; y--)
    {
      for (int x = hDisp; x>0; x--)
      {
        for (int col = 3; col>0; col--)
        {
          //first the outputbyte is empty
          SerialOutput[bytenr] = B00000000;
          for(int pixel = 0; pixel<8; pixel++){
            //get output bit from videomemory. due to electronic design, the bit needs to be inverted
            buffer = not bitRead(VideoMem[iRow+(y-1)*8][pixel+(x-1)*8],col-1);
            if (col==3){
              //green works the other way around, due to electronic design
              bitWrite(SerialOutput[bytenr],(7 - pixel),buffer);
            }
            else
            {
              //this one is for blue and red
              bitWrite(SerialOutput[bytenr],pixel,buffer);
            }
          }
          //all pixels in this byte are handeld, lets go to the next byte
          bytenr++;
        }
      }
    }
      
      //Set the latchPin low to start sending the output data
       digitalWrite(latchPin, LOW);
      
      for (bytenr=0; bytenr< (numberOfDisplays *3); bytenr++){
        shiftOut(dataPin, clockPin, LSBFIRST, SerialOutput[bytenr]);
        //Serial.println(SerialOutput[bytenr],BIN);
      }
      
      //output row
      shiftOut(dataPin, clockPin,MSBFIRST, hLine);
      //This is the end of the outputdata, set the latchpin high again
      digitalWrite(latchPin, HIGH);
      
      //If the Code runs to fast :S, we can have little coffee break now
      //delay(1);
      
      //Do some code to write in the video memory
      //animation(iRow);
  }
}

void cross()
{
  //write some data to the videomemory
  VideoMem [3][2]= B00000111;
  VideoMem [4][2]= B00000111;
  VideoMem [2][3]= B00000111;
  VideoMem [3][3]= B00000111;
  VideoMem [4][3]= B00000111;
  VideoMem [5][3]= B00000111;
  VideoMem [2][4]= B00000111;
  VideoMem [3][4]= B00000111;
  VideoMem [4][4]= B00000111;
  VideoMem [5][4]= B00000111;
  VideoMem [3][5]= B00000111;
  VideoMem [4][5]= B00000111;
}

void square()
{
  //write some data to the videomemory
  VideoMem [2][18]= B00000011;
  VideoMem [3][18]= B00000011;
  VideoMem [4][18]= B00000001;
  VideoMem [5][18]= B00000001;
  VideoMem [2][19]= B00000110;
  VideoMem [5][19]= B00000100;
  VideoMem [2][20]= B00000110;
  VideoMem [5][20]= B00000100;
  VideoMem [2][21]= B00000010;
  VideoMem [3][21]= B00000010;
  VideoMem [4][21]= B00000101;
  VideoMem [5][21]= B00000101;
}
2  Community / Exhibition / Gallery / Re: control current with paralell resistor to 5v motor on: August 10, 2011, 11:53:33 am
some recommendations:
use switch case instead of if if if
use transistors and diodes
control the current in a binary way wit R1 = 50 ohm; r2 = 100 ohm; r3 = 200 ohm etc.
or better, use PWM.
Use a H-bridge to control the motor in both directions
3  Community / Exhibition / Gallery / Re: Juissi's Tanganyika Aquarium on: May 30, 2011, 02:13:47 pm
Good idea: "Doggy Server". The biggest challenge would be to get electricity to the Arduino (Mini)...

In my project, the next step would be to add more interactivity. How to implement a sensor that senses a fish poking it or swimming nearby? Ideas?

-Juissi

maybe an antenna connected to a switch or sensor
4  Topics / Robotics / Re: Will atmega8 handle 6 servos and PWM ? on: May 22, 2011, 09:07:58 am
the ATmega 8 has 3 pwm outputs.
You'll need something like a TLC5940NT to control all servos independently.
5  Forum 2005-2010 (read only) / Exhibition / Re: A Sensitive DIY Ultrasonic Range Sensor on: January 23, 2011, 04:03:24 am
nice work,
I have two pairs of transducers laying around, so I probably need to do the same thing some day.
6  Forum 2005-2010 (read only) / Exhibition / 72 led shiftregister on: January 23, 2011, 08:51:09 am
I made a 72 bit shiftregister with 12 595's.


I do not use the shiftout function. Sometimes is don't want to shift out a byte, but just 3 bits (RGB). Therefore I made my function for shifting out the bits.

Code:
const int latchPin = 11; //Pin connected to latch pin (ST_CP) of 74HC595
const int clockPin = 10; //Pin connected to clock pin (SH_CP) of 74HC595
const int dataPin = 9; //Pin connected to Data in (DS) of 74HC595
boolean aan[] = {
  true};
boolean uit[] = {
  false};
boolean groen[] = {
  0,1,0};
boolean rood[] = {
  0,0,1};
boolean blauw[] = {
  1,0,0};
boolean violet[] = {
  1,0,1};
boolean turk[] = {
  1,1,0};
boolean oranje[] = {
  0,1,1};
boolean wit[] = {
  1,1,1};
boolean zwart[] = {
  0,0,0};

int pauze = 70;
int mode = 0;
long lasttime = 0;
const int lengte = 72;

boolean bar[lengte +1] = {
  0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0};



void setup() {
  //set pins to output because they are addressed in the main loop
  pinMode(latchPin, OUTPUT);
  pinMode(dataPin, OUTPUT);  
  pinMode(clockPin, OUTPUT);
  shiftdata(lengte, bar);

  Serial.begin(9600);
  Serial.println("start, debug");
}

void loop() {

  switch (mode){
  case 0:
  drop();
  break;
  case 1:
  sinnu1();
  break;
  case 2:
    willekeurig();
    break;
  case 3:
    sinnu3();
    break;
  case 4:
    sinnu4();
    break;
  default:
    mode = 0;
  }
if (millis() >= lasttime + 10000){
  mode ++;
  lasttime = millis();
}


}

void shiftdata(int lengte, boolean data[]){
  digitalWrite(latchPin, LOW);

  for (int i=0; i<lengte; i++){
    digitalWrite(dataPin, data[i]);//bit klaarzetten
    digitalWrite(clockPin, HIGH);//bit shiften
    digitalWrite(clockPin, LOW);
  }
  digitalWrite(latchPin, HIGH);// toon data
}

void sinnu1(){
  int positie = 36 * sin(millis()/250.0) + 36;
  int positie2 = 36 * cos(millis()/250.0) + 36;
  for (int j=0; j<=lengte; j++){
    if (((j <= positie) && (j >= positie2)) || ((j >= positie) && (j <= positie2))){
      bar[j] = 1;
    }
    else
    {
      bar[j] = 0;
    }
  }
  shiftdata(lengte, bar);
}

void sinnu3(){
  int positie = 3*int(12 * sin(millis()/250.0) + 12);
  for (int j=0; j<=lengte; j++){
    if (j== positie){
      bar[j] = 1;
    }
    else
    {
      bar[j] = 0;
    }
  }

  positie = 3*int(12 * sin(millis()/250.0 + 0.2) + 12)+1;
  for (int j=0; j<=lengte; j++){
    if (j== positie){
      bar[j] = 1;
    }
  }

  positie = 3*int(12 * sin(millis()/250.0 + 0.4) + 12)+2;
  for (int j=0; j<=lengte; j++){
    if (j== positie){
      bar[j] = 1;
    }
  }
  shiftdata(lengte, bar);
}



void sinnu4(){
  int positie = 36 * sin(millis()/200.0) + 36;
  for (int j=0; j<=lengte; j++){
    if (j== positie){
      bar[j] = 1;
    }
    else
    {
      bar[j] = 0;
    }
  }
  shiftdata(lengte, bar);

  positie = 36 * sin(millis()/225.0) + 36;
  for (int j=0; j<=lengte; j++){
    if (j== positie){
      bar[j] = 1;
    }
  }
  shiftdata(lengte, bar);

  positie = 36 * sin(millis()/250.0) + 36;
  for (int j=0; j<=lengte; j++){
    if (j== positie){
      bar[j] = 1;
    }
  }
  shiftdata(lengte, bar);

  positie = 36 * sin(millis()/275.0) + 36;
  for (int j=0; j<=lengte; j++){
    if (j== positie){
      bar[j] = 1;
    }
  }
  shiftdata(lengte, bar);
}



void willekeurig(){
  bar[random(lengte+1)] = random(2);
  shiftdata(lengte, bar);
  //delay(pauze);
}



void drop(){
  int kleur = random(3);
  switch (kleur){
  case 0:
    shiftdata(3,rood);

    delay(pauze);
    shiftdata(3,rood);
    break;
  case 1:
    shiftdata(3,groen);

    delay(pauze);
    shiftdata(3,groen);
    break;
  case 2:
    shiftdata(3,blauw);

    delay(pauze);
    shiftdata(3,blauw);
    break;
  default:
    shiftdata(3,zwart);
  }
  delay(pauze);
}




Pages: [1]