Weird timing problem

The following is my program. I’m using a software serial, to avoid causing problems with my programming the board over the hardware serial. The program does nothing but accepts a character, and turns an addressable LED to that color. Say for example, if ‘R’ is received, the LED will show red color. But as soon as I use the print() function in my loop() to transmit the received data back to the serial port, the LED does not work as expected. Some times it accepts data, and some times it does not.

#include <SoftwareSerial.h>

#define RX 2
#define TX 4

#define R 0x52
#define Y 0x59
#define B 0x42
#define G 0x47
#define S 0x53
#define LED 11;
#define D1 12
#define D2 6

SoftwareSerial soft_serial(RX, TX);
char c = S;

void setup() {
  DDRB |= 8;
  pinMode(RX, INPUT);
  pinMode(TX, OUTPUT);
  soft_serial.begin(1200);
  soft_serial.listen();
}

void loop() {
  if (soft_serial.available()) {
    char n = soft_serial.read();
    Serial.println(n);
    if (n != c) {
      if (n == R || n == Y || n == B || n == G || n == S) {
        Serial.print(c);
        Serial.println(n);
        c = n;
        led_control();
      }
    }
  }
  soft_serial.print(c);   // problem if this line is present.
}

void led_control() {
  switch (c) {
    case R:
      ws2812b(255, 0, 0);
      break;
    case Y:
      ws2812b(255, 240, 0);
      break;
    case B:
      ws2812b(0, 0, 255);
      break;
    case G:
      ws2812b(0, 255, 0);
      break;
    case S:
      ws2812b(0, 0, 0);
      break;
  }
}

void ws2812b(unsigned char r, unsigned char g, unsigned char b) {
  noInterrupts();
  bitfield(g);
  bitfield(r);
  bitfield(b);

  PORTB = 0;
  __builtin_avr_delay_cycles(1000);
  interrupts();
}

void bitfield(unsigned char c) {
  portwrite(B10000000 & c);
  portwrite(B01000000 & c);
  portwrite(B00100000 & c);
  portwrite(B00010000 & c);
  portwrite(B00001000 & c);
  portwrite(B00000100 & c);
  portwrite(B00000010 & c);
  portwrite(B00000001 & c);
}

void portwrite(bool d) {
  if (d) {
    writeone();
  } else {
    writezero();
  }
}

void writeone() {
  PORTB = 8;
  __builtin_avr_delay_cycles(D1);
  PORTB = 0;
  __builtin_avr_delay_cycles(D2);
}

void writezero() {
  PORTB = 8;
  __builtin_avr_delay_cycles(D2);
  PORTB = 0;
  __builtin_avr_delay_cycles(D1);
}

But, if I add a 20ms or more delay() after the use of print() function, it works somewhat OK. What could be the problem?

SoftwareSerial soft_serial(RX, TX);

There's your problem. Read up on how SoftwareSerial actually works. It can't tolerate any interruptions. print() uses interrupts to print, so it can disrupt the SoftwareSerial.

That's kind of a mess of AVR programming mixed into an Arduino program.

#define R 0x52
#define Y 0x59
#define B 0x42
#define G 0x47
#define S 0x53[/quote[
That is totally unnecessary. In the code which uses these constants, you should do it like this...

      if (n == 'R' || n == 'Y' || n == 'B' || n == 'G' || n == 'S') {

...
  switch (c) {
    case 'R':




And one more clue: You are encouraged to use variable names longer than one character. For example, "c" probably should have been called "currentColor" or something like that.

Using the real serial port is not going to mess up your downloading. I would just use it.

MorganS is correct. The serial port is asynchronous, which means it is not synched to a clock for timing so once

the timing is interrupted by an interrupt routine call you've lost your data.