receiving 5 (R,B,G) Values over serial. my ode doesn't work (15 3 digit values)

So, I have been trying to write a code for my PC Lighting, I’m planning to only to use (arduino for now, will make a custom board or something) it for receiving color of the 5 pixels.

the problem is, parseInt is so slow even with \n on the end, and serial.read() - ‘0’ reads only 1 digit at a time so 255 would be (2,2,5)

So i made a function named recieve, but the problem is i get my values like this, instead of zero i get 2 integers, the first one might be the value i send, the second one is something like -14000 etc,

#include "Adafruit_NeoPixel.h"
#include "WS2812_Definitions.h"

#define PIN 4
#define LED_COUNT 5

struct pixel {
  int R = 0;
  int B = 0;
  int G = 0;
};

Adafruit_NeoPixel leds = Adafruit_NeoPixel(LED_COUNT, PIN, NEO_GRB + NEO_KHZ800);

char count = 1;
int pixelNumber = 0;
struct pixel tempPixel;
//struct pixel Pixels[LED_COUNT];

void setup()
{
  Serial.begin(9600);
  leds.begin();  // Call this to start up the LED strip.
  clearLEDs();   // This function, defined below, turns all LEDs off...
  leds.show();   // ...but the LEDs don't actually update until you call this.
}

void loop() {
  if(Serial.available() > 0) {
    if(count == 1) {
      tempPixel.R = PC_Receive();
    } else if (count == 2) {
      tempPixel.G = PC_Receive();
    } else if (count == 3) {
      tempPixel.B = PC_Receive();
      count = 0;
      
      setPixelColor(pixelNumber, tempPixel);
//      Serial.print("OK:");
      Serial.println(pixelNumber);
      leds.show();
//      Pixels[pixelNumber] = tempPixel;
      if(++pixelNumber >= LED_COUNT) {
        pixelNumber = 0;
      }
    }
    count++;
  }
  
//  if(pixelNumber == 0) {
//    for(int i = 0; i < LED_COUNT; i++ ) {
//       setPixelColor(i, Pixels[i]); 
//    }
//    
//    leds.show();
//  }
}

void setPixelColor(int a, struct pixel P)
{
  leds.setPixelColor(a, P.R, P.G, P.B);
}

int PC_Receive() {
  int result;
  
  for(int i = 0; i < 3; i++) {
    while(Serial.available() <= 0);
      Serial.println(Serial.read() - '0');
      if(i = 0) { result = (Serial.read() - '0'; }
      if(i = 1) { result += (Serial.read() - '0') * 10; }
      if(i = 2) { result += (Serial.read() - '0') * 100; }
  }
  Serial.println(result);
  
  return result;
}

the problem is, parseInt is so slow even with \n on the end

The time that it takes parseInt() to collect data, recognize that the end of the value has arrived (no data for a period of time OR a non-numeric character arrived), and convert the value to an int depends on the baud rate. IF you send some non-numeric value after the last digit and use a decent baud rate, parseInt() is not slow. YOUR code might be.

    while(Serial.available() <= 0);

Do you seriously think that available() can return a negative value?

      Serial.println(Serial.read() - '0');
      if(i = 0) { result = (Serial.read() - '0'; }
      if(i = 1) { result += (Serial.read() - '0') * 10; }
      if(i = 2) { result += (Serial.read() - '0') * 100; }

If there IS a byte to read, read it and throw it away. Then, read a byte that hasn’t arrived…

That is NOT how to compare i to a number.

you certainly cannot count on all of your values being three decimal places…

on the transmit side, send the three values in a single packet, something like this:

byte red = 0;
byte green = 255;
byte blue = 155;
char txBuffer[10] = "";
sprintf(txBuffer"*%d|%d|%d#", red, green, blue);
Serial.println(txBuffer);

then on the receiving side, parse like this:

const int redPin = 5;
const int greenPin = 3;
const int bluePin = 6;

byte colorValue [3] = {0};

bool displayedNewValue = true;

void setup() 
{
  Serial.begin(9600);
  pinMode(redPin, OUTPUT);
  pinMode(greenPin, OUTPUT);
  pinMode(bluePin, OUTPUT);
}

void loop() 
{
  if(Serial.available())
  {
    char myChar = Serial.read();
    if(myChar == '*') // found leading *
    {
      for (int i = 0; i < 3; i++)
      {
        colorValue[i] = Serial.parseInt();
        if(i!=2)
        {
          Serial.read();  // ignore the pipe
        }
        else
        {
          char lastChar;
          lastChar = Serial.read();
          if(lastChar != '#')  // expects a # ... abort if it didn't arrive
          {
            Serial.println(F("bad read"));
            break;
          }
          else
          {
            displayedNewValue = false;
          }
        }
        delay(10);
      }
    }
  }
  if (!displayedNewValue)
  {
    char packetContents[32];
    sprintf(packetContents, "Red:%3d Green:%3d Blue:%3d", colorValue[2], colorValue[1], colorValue[0]);
    Serial.println(packetContents);
    analogWrite(redPin, colorValue[2]);
    analogWrite(greenPin, colorValue[1]);
    analogWrite(bluePin, colorValue[0]);
    displayedNewValue = true;
  }    
}

Have a look at the examples in Serial Input Basics - simple reliable non-blocking ways to receive data. There is also a parse example.

...R

Thanks, before i visited here i wrote a new code that works, and im sure my input is 3 digits as max value for my pwm is 255;

char PC_Receive() {
  int result = 0;
  
  while(Serial.available() == 0);
  result += ((int)Serial.read() - '0') * 100;
  
  while(Serial.available() == 0);
  result += ((int)Serial.read() - '0') * 10;
  
  while(Serial.available() == 0);
  result += ((int)Serial.read() - '0');
  
  Serial.println(result);
  return result;
}

Why are you casting the int that Serial.read() returns to an int?

Short TEST code to read 3 bytes from serial port.

Reads 3 bytes into buffer and prints ( to LCD / serial monitor) 3 bytes from such buffer - A TEST CODE !

 char  SerialBuffer[256];
  do
  {
    // test serial int
    while (!Serial.available());
    while (Serial.available())
    {
      lcd_i2c.clear();
      lcd_i2c.print(__func__);
      lcd_i2c.setCursor(0, 1);
      //lcd_i2c.print((int) Serial.parseInt());
      //for (;;);
      //while (lcd_i2c.print((int) Serial.parseInt() != 0 ));
      //      lcd_i2c.setCursor(0, 2);
      // return number of characters in SerialBuffer
      lcd_i2c.print(Serial.readBytes(SerialBuffer, 3));
      //      lcd_i2c.setCursor(0, 3);
      //      lcd_i2c.print(Serial.print(SerialBuffer[0]));
      // print buffer 
      lcd_i2c.setCursor(0, 3);
      for (int i = 0; i  != 3; i++)
{
        lcd_i2c.print(SerialBuffer[i]);
        Serial.print(SerialBuffer[i]);
}

      //      //for (;;);
      lcd_i2c.setCursor(16, 3);
      lcd_i2c.print(__LINE__);
      delay(DELAY);
      delay(5000);
      lcd_i2c.clear();
    }
  } while (true);
  for (;;);

Perhaps you should provide a little more description of the data you are trying to send/receive. There may be better/easier ways of doing the task.

Im trying to control 5leds from my pc, i found a better way, i will send a hex numbers like this:
(0x(lednum)(g)(b)(r))
For example = 5FF0C00

I made a new post about a problem i had there,