Go Down

Topic: send 8 bits over 2 arduino ports for strips leds control (Read 564 times) previous topic - next topic

gundorf

Hi everyone !
I try to control 7 leds strips (ws2812) of 2 meters each,144leds/meter with an arduino uno.

Due to the large amount of leds, I connect every strip to an output of my arduino (parallel).

I try to display text with those strips.

When I use the PORTD only, no issue !

for example, when I send this=>

{B1,B10,B11,B100,B101,B110}

the strips look like:


so far everything is fine !

I have to preserve my serial connection. (means make D0 and D1 free).
I use a spectrum waveshield to make a nice vu-meter. So I need although D4 and D5 keep  unused by strips.

So I have to use PORTB (pins D8,D9,D10,D11) and the PORTD (pins D2,D3,D6).

when I do this, here's what I get from the previous code:



which I don't understand !

here's the way I do this:

PORTB and D setup:
Code: [Select]
void setup() {
  // Serial.begin(9600);
  PIXEL_DDR = 0xCC;    // (B11001100) - pins D7,D6,D3,D2 output.
  PIXEL_DDRB = 0xF;    // (B1111)        -pins D8,D9,D10,D11 output.
}


here's the function which sends a letter to the strips:

Code: [Select]
void envoiLettre( byte col) {

  int mask = 0x01;
 
  for (int bit = 8; bit > 0; bit--) {
    if (vert& (mask << bit))envoiBitX8( col); else sendBitX8( 0x00);
  }
  for (int bit = 8; bit > 0; bit--) {
    if (rouge& (mask << bit))envoiBitX8( col); else sendBitX8( 0x00);
  }
  for (int bit = 8; bit > 0; bit--) {
    if (bleu& (mask << bit))envoiBitX8( col); else sendBitX8( 0x00);
  }
}



to send an 'A', I do:
Code: [Select]

envoiLettre(0x00, 0x7C, 0x12, 0x11, 0x12, 0x7C)


Here's the function which sends the 8BITS:

Code: [Select]
void envoiBitX8( byte bits) {
  PORTD = 0xFF; // turn on
  PORTB = 0xFF; // turn on
  PORTD = 0xFF; // delay
  PORTD = 0xFF; // delay
  PORTD = 0xFF; // delay
  PORTD = bits; // send data
  PORTB = bits; // send data
  PORTD = bits; // delay
  PORTD = bits; // delay
  PORTD = bith; // delay
  PORTD = 0x00; // turn off;
  PORTB = 0x00; // turn off;
}



Do I miss something obvious ?
I have to say I'm pretty lost with this issue... Do know how to deal with...
If some of you have any clue, It would be grandly appreciated ! :)
thanks in advance !

PaulRB

Quote
Do I miss something obvious ?
Yes, the forum guidelines in the sticky post at the top of every forum section. Please read them and fix your post above.

Grumpy_Mike

#2
May 12, 2018, 03:16 pm Last Edit: May 12, 2018, 03:17 pm by Grumpy_Mike
Quote
so far everything is fine
Is It?
Why are you not using a libiary? You can't talk to ws2812 chips like that. The timing has to be precise and you have to send three bytes for each LED.

I think you are fooling yourself in thinking you understand what is going on

gundorf

ok, I've corrected my post...

Is It?
Why are you not using a libiary? You can't talk to ws2812 chips like that. The timing has to be precise and you have to send three bytes for each LED.

I think you are fooling yourself in thinking you understand what is going on
Now you can see that I send 3 bytes fo each led...(see envoiLettre()).

here's videos of what I have so far:
all leds fading

here's the nice vu-meter...

you can see that I understand a little bit things about leds   ;)

I don't know library with parallel configuration...
if you know some library, I would love to know about it...

still do know how to make correct link between my datas and PORTB/PORTD manipulation...
if you have any clue about this ..? ;)


Grumpy_Mike

#4
May 13, 2018, 06:02 am Last Edit: May 13, 2018, 06:03 am by Grumpy_Mike
Quote
I don't know library with parallel configuration
Both the Adafruit and the FastLED libraries allow you to connect different strips to do different pins at the same time.
The strips however are sent data one at a time but this is so fast that it looks like the same time. Many beginners are obsessed with parallel operations when they are simply not needed.

The timing needs to be precise and so to that end the interrupts must be disabled when sending the data. So your code is at best unreliable with the normal tick counter interrupts going on. That is why this sort of thing is normally written In assembler.

Quote
still do know how to make correct link between my datas and PORTB/PORTD manipulation.
You do it in exactly the same way as you are doing it for the other ports. However look at the pin mapping and you will see some pins are not brought out of the chip and others are used for things you don't want to override. What type of Arduino are you using.

gundorf

thanks for your reply Grumpy_Mike.
My question would be why does it work with the only use  if PORTD, and not when I use PORTD/PORTB...
I use an arduino uno.
I disable interrupts (cli()- sei()) to make things all in time.

here's my code:

Code: [Select]
#define PIXEL_PORT  PORTD
#define PIXEL_DDR   DDRD
#define PIXEL_PORTB PORTB
#define PIXEL_DDRB DDRB
char text[] = "A";
int rouge = 1;
int vert = 1;
int bleu = 1;

void envoiBitX8( byte bits) {
  PORTD = 0xFF; // turn on
  PORTB = 0xFF; // turn on
  PORTD = 0xFF; // delay
  PORTD = 0xFF; // delay
  PORTD = 0xFF; // delay
  PORTD = bits; // send data
  PORTB = bits; // send data
  PORTD = bits; // delay
  PORTD = bits; // delay
  PORTD = bits; // delay
  PORTD = 0x00; // Turn off;
  PORTB = 0x00; // Turn off;
}

void envoiLettre( byte col)  {

  int mask = 0x01;  for (int bit = 8; bit > 0; bit--) {
    if (vert & (mask << bit))envoiBitX8( col); else envoiBitX8( 0x00);
  }
  for (int bit = 8; bit > 0; bit--) {
    if (rouge & (mask << bit))envoiBitX8( col); else envoiBitX8( 0x00);
  }
  for (int bit = 8; bit > 0; bit--) {
    if (bleu & (mask << bit))envoiBitX8( col); else envoiBitX8( 0x00);
  }
}
byte A[][6] = {0x00, 0x7C, 0x12, 0x11, 0x12, 0x7C};
void setup() {
  PIXEL_DDR = 0xCC;
  PIXEL_DDRB = 0xF;

}

void loop() {
  {
    cli();

    envoiLettre(A[text[0] ][0]);
    envoiLettre(A[text[0] ][1]);
    envoiLettre(A[text[0]][2]);
    envoiLettre(A[text[0]][3]);
    envoiLettre(A[text[0]][4]);
    envoiLettre(A[text[0]][5]);
  }
  sei();

  delay(400000);

}


However look at the pin mapping and you will see some pins are not brought out of the chip and others are used for things you don't want to override. What type of Arduino are you using.
You must be right, I have to check out pins of my uno... and what would be differences between pins...

so up to you it won't be a code issue ?
I keep searching...
thanks !

Grumpy_Mike

Quote
My question would be why does it work with the only use  if PORTD, and not when I use PORTD/PORTB...
I suspect this is because it does not actually work on PORTD, but by some fluke with the data you have used appeared to give the results you expect. I suspect if you use other data on your "working" you will not get what you expect.

From arround the web
Quote
Be wary of using PC6, this also controls the "reset button."
Quote
the pins 6 and 7 from PORTB are also the input pins for the crystal oscillator,
Quote
Port B has pins B0 to B5

Port C has pins C0 to C5

Port D has Pins D0 to D7


gundorf

ok.
the shift operation took too much time...

so, using D8-D9-D10-D11-D12-D13-D6 works like a charm !

by some fluke with the data you have used appeared to give the results you expect.
If you want to learn about fluke, you can check this sir:

https://www.amazon.fr/Arduino-LED-Strip-Projects-Addressable/dp/198519127X/ref=sr_1_7?ie=UTF8&qid=1526805773&sr=8-7&keywords=arduino+led+strip+project

sans rancune..

Go Up