[BEGINNER] (??) Still cannot serial read bytes !

Hello, to cure my total frustration, please,

I need to transmit 24 bytes on 1 wire (+GND; Sharing PSU), unidirectional, the fastest.
I can never get my array with right values on the right slot !
I tried with TEENSY LC & 3.2 as master and with LC & NANO as slave, noway to make it.

I tried many forums/tutos/pieces of codes* … I tried “Serial.read”, SPI.h, wire.h**, … I have been close to give up many times…

I can paste the simplest MASTER CODE from the µC which SENDS the data, … I have no ridiculous SLAVE CODE to share as i can paste here around 2 tons of this non-working S$%T nobody cares.
If i can’t make it work with help, i promise i will paste 2 or 3 tons of non-working SLAVE CODE.

Master’s output looks great and reliable according to my oscilloscope…

#include <LXTeensy3DMX2.h>  //  Lib DMX // uses UART2 & UART0 for Dmx In & Out.

char array[] = {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255};

void setup() {

    Serial.begin(250000);
    Serial1.begin(9600);


    Teensy3DMX2.setDataReceivedCallback(&gotDMXCallback);  // DMX Lib work
    Teensy3DMX2.startInput();                               // DMX Lib work
    
}

void loop() {

    if ( got_dmx ) {

        for (int i = 0; i < 24; i=i+1) {
            int j = i + 2;
            array[i] = Teensy3DMX2.getSlot(j);
        }                                           // Uses 24 inputed bytes through DMX standard, make it an array of bytes.
                                                    // array[0] takes Channel 2 value, array[1] takes channel 3 value, and so on...

    }
    Serial1.write(array, 24); delay(100);          
 // Outputs my array on 1 wire, with big 100ms break between frames.
}

→ ANY WAY OF MAKING A SLAVE CODE WORKING ??

    if (Serial3.available() > 0) {
        
        digitalWrite(TP, HIGH);
        
        /*array[] = Serial3.read();*/    //Also useless
        
        
        for (int i = 0; i < 24; i=i+1) {
        int j = i + 1;
        array[j] = Serial3.read();;
        }
    }
    
    
    analogWrite(XP, array[3]);

[CODE\]

Pyro74:
I have no ridiculous SLAVE CODE to share as i can paste here around 2 tons of this non-working S$%T nobody cares.

That sort of comment is not likely to make people want to help you.

Have a look at the examples in Serial Input Basics - simple reliable non-blocking ways to receive data. There is also a parse example to illustrate how to extract numbers from the received text.

The technique in the 3rd example will be the most reliable. It is what I use for Arduino to Arduino and Arduino to PC communication.

You can send data in a compatible format with code like this (or the equivalent in any other programming language)

Serial.print('<'); // start marker
Serial.print(value1);
Serial.print(','); // comma separator
Serial.print(value2);
Serial.println('>'); // end marker

…R

Pyro74: PWM output and IDE monitor are flat ...

I don't know what that means but I do know you are not using the code from my Tutorial - of course you are perfectly free to ignore it.

...R

:confused:

Okay, please forgive, … Back on again and try to stay clean :

Flat for an analog output … means i get nothing out.

Just pasting your code as is will give nothing viewable as my board is soldered now.

→ My in puts for serial must be set under Serial3.whatever
→ I added outputs to fast read any result… An dmy monitor still gives nothing.

Is that much different from you code ?

// Example 2 - Receive with an end-marker

#define LED1 16
#define LED2 17
#define XP 3

const byte numChars = 24;
char receivedChars[numChars];   // an array to store the received data

boolean newData = false;

void setup() {
    pinMode(LED1, OUTPUT);
    pinMode(LED2, OUTPUT);
    pinMode(XP, OUTPUT);
    
    Serial.begin(9600);
    Serial1.begin(9600);    
    Serial.println("<Arduino is ready>");
}

void loop() {
    recvWithEndMarker();
    showNewData();
}

void recvWithEndMarker() {
    static byte ndx = 0;
    char endMarker = '\n';
    char rc;
   
    while (Serial1.available() > 0 && newData == false) {
        rc = Serial1.read();

        if (rc != endMarker) {
            receivedChars[ndx] = rc;
            ndx++;
            if (ndx >= numChars) {
                ndx = numChars - 1;
            }
        }
        else {
            receivedChars[ndx] = '\0'; // terminate the string
            ndx = 0;
            newData = true;
        }
    }
}

void showNewData() {
    if (newData == true) {
        Serial.print("This just in ... ");
        Serial.println(receivedChars);
        analogWrite(LED1, receivedChars);
        analogWrite(LED2, receivedChars);
        analogWrite(XP, receivedChars);    
        newData = false;
    }
}

MANY THANKS !!

New try…
I remember this page / your tuto … was where i lost time the most … cetainly because how it looks like made me care a lot.

I made some soldering again… Now my serial input is linked under Serial1.whatever … Du to TEENSY LC, UART pin

// Example 6 - Receiving binary data


#define LED1 16
#define LED2 17
#define TP 13
#define XP 3

#define inp1 0
#define inp2 7

const byte numBytes = 24;
byte receivedBytes[numBytes];
byte numReceived = 0;

boolean newData = false;

void setup() {
    
pinMode(LED1, OUTPUT);
pinMode(LED2, OUTPUT);
pinMode(TP, OUTPUT);
pinMode(XP, OUTPUT);

pinMode(inp1, INPUT);
pinMode(inp2, INPUT);
    
    Serial1.begin(9600);
    Serial.begin(9600);
    Serial.println("<Arduino is ready>");
}

void loop() {
    
    recvBytesWithStartEndMarkers();
    showNewData();
}

void recvBytesWithStartEndMarkers() {
    static boolean recvInProgress = false;
    static byte ndx = 0;
    byte startMarker = 0x3C;
    byte endMarker = 0x3E;
    byte rb;
   
    
    while (Serial1.available() > 0 && newData == false) {
        rb = Serial1.read();

        if (recvInProgress == true) {
                            
            if (rb != endMarker) {
                receivedBytes[ndx] = rb;
                ndx++;
                if (ndx >= numBytes) {
                    ndx = numBytes - 1;
                }
            }
            else {
                receivedBytes[ndx] = '\0'; // terminate the string
                recvInProgress = false;
                numReceived = ndx;  // save the number for use when printing
                ndx = 0;
                newData = true;
            }
        }

        else if (rb == startMarker) {
            recvInProgress = true;
        }
    }
}

void showNewData() {
    if (newData == true) {
        Serial.print("This just in (HEX values)... ");
        for (byte n = 0; n < numReceived; n++) {
            Serial.print(receivedBytes[n], HEX);
            Serial.print(' ');
        }
        Serial.println();
        newData = false;
    }
}

All outpus are flat.

I know i look like a dumb .. Anyway, every tutos and forums only shows serial.print(" and sprintf( ..... As one more exemple i oftenly see while statement ..... While never worked for me on arduino, the only condition statement icould make working have always been if, even a for loop doesn't work.

... Also i don't play for computer only fun mode.... i need to do electronics dev which is not the same .... maybe is that key for my issues ?

Pyro74: Is that much different from you code ?

If you made changes to my code you should know what they were and I would appreciate it if you would tell me.

Just pasting your code as is will give nothing viewable as my board is soldered now.

You need to explain how your board is soldered and how it is incompatible with my code. I can't see your workbench.

Please give an example of the message that you actually want to send? Also tell us if you have any flexibility to change the content of the message.

...R

PS ... it's much easier to help you if you post a question and then wait for an answer rather than making more posts about other variations that just cause confusion.

Many thanks for your understanding. Excuse my english… Many sentences may be latin variations…

The project is to build a classic “stage lighting” item, Controlled by a “DMX512” controller.

A standard DMX controller send up to 512 bytes under its strict protocol, must be more than 25 frames per second, cannot be more than 44 FPS (maximum du to protocol limits).
This controller allows you to set each of the 512 value by hand, live, using faders (you can find a various set of programmable controllers and USB software setup).

Items working as slave of the serial line (wired as I2C) will all have their own range of bytes to refer to, programmed Addr 017 into a RGB simplest machine means slot 17 will control its RED, 18 for GREEN and 19 for BLUE, you then add another on Addr 020 and so on if you wish. Machines are able to need dozens of controlling slots (bytes) depending on their complexity and features.

The mechanics of my project needs to use 2 MCUs. 1 on main PCB controlling base features, and a 2nd one on a distant part (30cm) for other features.

Then for now main PCB works almost perfectly and completely.

Standard DMX512 controller → Serial line driver (SN75176) → TEENSY 3.2 (UART2-RX3-Pin7)

All this works well with my UI, i can display any test to validate values are caught and buttons work well.
DMX input works under LXTeensy3DMX2.h 2018 release as i couldn’t make the last one to work properly. “2” for UART number 2.

[…

…]

Now the range set to select some values into the frame is basic programming. then to by-pass this part which gives no interest, let say we start controlling from Addr 001.
We use 28 bytes from the DMX (the 28 firsts, from 1 to 28 in the frame), 4 of them are for BASE features then directly used for MAIN PCB, the 24 others are needed into the SLAVE PCB.
→ Teensy3DMX2.getSlot(slotNumber) with SlotNumber from 1 to 24 → Stored into an ARRAY.

We want to send this bytes array out from the MAIN PCB to the slave TEENSY LC.
Then to Send all 24 bytes to the slave MCU, as 1 frame :
Serial1.write(array, 24); does a wonderful, easy, fast and oscilloscope validated job ! ^^
I add pictures, one shows frame, the other shows the first byte set at 85 (10101010) for easy identification. No picture but works as well for the 24th. All others at 0.

I really though break length (pause between frames) could give a very easy processing of each frames, slot position, byte identification.

Anyway, now i need to receive my frame and store it into an array.
On TEENSY LC (UART0-RX1-Pin0)
GND and 5V are shared between those 2 TEENSY.

I though the easiest would be looking like :

void loop() {
while (Serial1.available() << 24) {
        digitalWrite(TP, HIGH);
            
        for (int i = 0; i < 24; i=i+1) {
        int j = i + 1;
        array[j] = (char)Serial3.read();;
        }

    }
    analogWrite(PWM1, array[3]);
}

PWM1 is wired to Oscillo’s channel 2 , array[3] is supposed to get the equal value of a certain fader of the controller. The controller displays me the slot’s value (DMX channel’s value, from 0 to 255 of course).

This way of doing give me some buggy trace (monitoring PWM) depending of the whole frame values… main time flat, sometime with no real interpretation.

I'm afraid I know nothing about DMX however I have seen other Threads about it so there are probably other Forum people who could help you. I suggest you edit your Original Post and edit the Title so it makes clear that you want help with DMX - perhaps something like "Problem reading serial bytes for DMX system"

Because I know nothing about DMX I can't make sense of your Replies #9 and #10 or understand whether what I suggested earlier is even relevant. If you think it is and can answer the simple questions in my Reply #8 I will see if I can help further.

...R

:smiley: Relax Rob, DMX is a serial data bus… Also i have mastered my DMX datas now…

My issue comes when using bytes to be transferred from 1 Teensy3.2 master to a TeensyLC as a 24 bytes frame… At this point the DMX is already treated.

Of course you can !! ^^

Pyro74: Of course you can !! ^^

Not without answers to the questions in Reply #8

...R

Sorry, which one is reply #8 ? or which is the question ?

Pyro74: Sorry, which one is reply #8 ?

The Reply with the #8 at the top right - this is very frustrating.

...R

The message i wan to send, okay ...

Actually i am sending a 24 bytes array, 24 times a variable which value is coded under 8 bits with value from 0 to 255, All this into 1 array is sent, should looks like :

char array[24] = {255, 0, 128, 64, 32, 16, 8, 4, 2, 1, 255, 255, 255, 0, 128, 64, 32, 16, 8, 4, 2, 1, 255, 255}

Now i need to receive and splitt my array.

Could you get by without using the values 254 and 255? If so you can use them as start- and end-markers and use code like in the third example in Serial Input Basics to receive the data - changing the datatype from char to byte

You could send the data with this sort of code

Serial.write(254);
Serial.write(array, 24);
Serial.write(255);

and on the receiving side your data will be in the array receivedBytes

...R

:sweat_smile: I GOT IT !!!

My god, i can’t believe it needed so much time !!! But i can say the common mistake found in almost every posts and Tutos !! Too bad !

"if (Serial.available() > 0) { " Will never help to get the right slot/byte/numbered byte from the array in its place !!!

What works well now is :

void sniff() {
    while (Serial1.available() >= 24) {

            
        for (int i = 1; i <= 25; i=i+1) {
        array[i] = Serial1.read();
        }
    }
}

void spititout() {
    digitalWrite(TP, array[1]);
    analogWrite(XP, array[2]);
    analogWrite(LED1, array[3]);
    analogWrite(LED2, array[4]);
}

Thanks to Rob for letting me find the little amount of motivation i missed !!

This

while (Serial1.available() >= 24) {

does not guarantee that the first of the 24 bytes is the first byte of the array that you sent although it will probably work most of the time.

...R