Go Down

Topic: Unexpected delays with precise operations (Read 64 times) previous topic - next topic

yclee126

Hello everyone.

I've been doing a project about a mini gaming keyboard with Pro Micro, and now I stuck on this problem.
The keyboard uses a WS2812B led stripe for effects and there is a library called "FastLED" for controlling it.
But then I discovered that the library is wasting many extra cycles(meaning high latency), so I've started to build my own transmission code.

Currently I achieved 300us of transmit time with 6 leds.(1500us with the library)
And this is the test code:

Code: [Select]
#define LED_PIN     10
#define NUM_LEDS 6

byte leds[6][3] = {0,};// R G B

void setup() {
  pinMode(LED_PIN, OUTPUT);
  pinMode(A3, OUTPUT);
  digitalWrite(A3, LOW);
}

void loop() {
  for(int i; i < NUM_LEDS; i ++){
    leds[i][0] = i;
    leds[i][1] = NUM_LEDS + i;
    leds[i][2] = NUM_LEDS - i;
  }
  PORTF ^= B00010000; //for time measurement
  showled();
  PORTF ^= B00010000;
}

#define NOP __asm__ __volatile__ ("nop\n\t")
#define TGLEDPIN PORTB ^= B01000000 //Pin 10

void showled(){
  for(byte j = 0; j != NUM_LEDS; j++){
   
    //G
    (leds[j][1] & B10000000) ? hp() : lp();
    (leds[j][1] & B01000000) ? hp() : lp();
    (leds[j][1] & B00100000) ? hp() : lp();
    (leds[j][1] & B00010000) ? hp() : lp();
    (leds[j][1] & B00001000) ? hp() : lp();
    (leds[j][1] & B00000100) ? hp() : lp();
    (leds[j][1] & B00000010) ? hp() : lp();
    (leds[j][1] & B00000001) ? hp() : lp();

    //R
    (leds[j][0] & B10000000) ? hp() : lp();
    (leds[j][0] & B01000000) ? hp() : lp();
    (leds[j][0] & B00100000) ? hp() : lp();
    (leds[j][0] & B00010000) ? hp() : lp();
    (leds[j][0] & B00001000) ? hp() : lp();
    (leds[j][0] & B00000100) ? hp() : lp();
    (leds[j][0] & B00000010) ? hp() : lp();
    (leds[j][0] & B00000001) ? hp() : lp();

    //B
    (leds[j][2] & B10000000) ? hp() : lp();
    (leds[j][2] & B01000000) ? hp() : lp();
    (leds[j][2] & B00100000) ? hp() : lp();
    (leds[j][2] & B00010000) ? hp() : lp();
    (leds[j][2] & B00001000) ? hp() : lp();
    (leds[j][2] & B00000100) ? hp() : lp();
    (leds[j][2] & B00000010) ? hp() : lp();
    (leds[j][2] & B00000001) ? hp() : lp();
   
  }
  delayMicroseconds(50);
}

void hp(){
  TGLEDPIN;
  NOP;
  NOP;
  NOP;
  NOP;
  NOP;
  NOP;
  NOP;
  NOP;
  NOP;
  TGLEDPIN;
}

void lp(){
  TGLEDPIN;
  NOP;
  NOP;
  NOP;
  TGLEDPIN;
  NOP;
  NOP;
  NOP;
  NOP;
  NOP;
  NOP;
}


According to this manual here, the code supposed to work perfectly.
However, there was some short random flashes on leds whilst FastLED doesn't.

My scope shows that there are random 7us delays between those NOP codes, and I can't figure it why it's happening.
Should I really get into assembly programming? I have no idea..

Whandall

showled should run with disabled interrupts.
Ah, this is obviously some strange usage of the word 'safe' that I wasn't previously aware of. (D.Adams)

yclee126


Go Up