text:
RGB LED strip controlled through PySerial only somewhat functional
I am trying to set up an LED-strip of 30 RGB LEDs (model WS2801). The strip is connected to an Arduino Uno and an external power supply and the goal is to send colors to the arduino using PySerial which are then shown on the LED strip.
I have been trying to wrap my head around the communications, which I am having a hard time with, especially due to the loose typing of python.
I wrote some code that generates smooth color transitions and got the strip to actually show a fairly smooth color transition, unfortunately the colors are the wrong ones.
Now I am guessing something overflows somewhere, especially since colors such as 0xFF0000 (red) show as a yellow tone, which indicates that on top of red some green gets added as well.
The Python code using pySerial:
@classmethod
def set_lights(self: RGBHardware, colors: List[int]) -> None:
    for i in range(len(colors)):
        rgb = color_to_rgb(colors[i])
        self.arduino.write(chr(76).encode()) # 'L'
        self.arduino.write(chr(i).encode())
        self.arduino.write(chr(rgb[0]).encode())
        self.arduino.write(chr(rgb[1]).encode())
        self.arduino.write(chr(rgb[2]).encode())
    self.arduino.write(chr(90).encode()) # 'Z'

@classmethod
def turn_on(self) -> None:
    self.arduino = serial.Serial('/dev/ttyACM0', 115200)
    if self.arduino.isOpen:
        self.arduino.close()
    self.arduino.open()
    pass

The code running on the Arduino Uno:
void setup() {
#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000L)
  clock_prescale_set(clock_div_1); // Enable 16 MHz on Trinket
#endif

  Serial.begin(115200);
  strip.begin();
  // Update LED contents, to start they are all 'off'
  strip.show();
}

void loop() {
   while (Serial.available()) {
        uint8_t serial = Serial.read();
        if (serial == 'Z') {
            strip.show();
        } else if (serial == 'L') {
            int i = getNextInput();
            int r = getNextInput();
            int g = getNextInput();
            int b = getNextInput();
            strip.setPixelColor(i, Color(r,g,b));
        }
   }
}

uint8_t getNextInput() {
  while(!Serial.available()); // wait for a character
  return Serial.read();
}

I am having the strong feeling I am just missing a miniscule detail and it is quite frustrating.
Any help would be greatly appreciated!
EDIT:
So I recorded some data and pasted the results below. I found that always not the whole LED-strip was updated and none of it with the correct color. Once even the character "Z" seemed to go missing (that causes the strip to fully refresh) so no color was showing at all.
What I also forgot to mention earlier was that I am using Celery in Python to do the light switching as a background task.
To record the results I used
print("i, R,G,B: " + str(i) + ", " + str(rgb[0]) + "," + str(rgb[1]) + "," + str(rgb[2])) to print the data in python and
Serial.println("i, R,G,B: " + String(i) + ", " + String(r) + "," + String(g) + "," + String(b)); to do the same on the Arduino.
Sending color red from Python:
[2018-07-23 16:13:57,121: WARNING/ForkPoolWorker-7] i, R,G,B: 0, 255,0,0
[2018-07-23 16:13:57,122: WARNING/ForkPoolWorker-7] i, R,G,B: 1, 255,0,0
[2018-07-23 16:13:57,123: WARNING/ForkPoolWorker-7] i, R,G,B: 2, 255,0,0
[2018-07-23 16:13:57,125: WARNING/ForkPoolWorker-7] i, R,G,B: 3, 255,0,0
[2018-07-23 16:13:57,126: WARNING/ForkPoolWorker-7] i, R,G,B: 4, 255,0,0
[2018-07-23 16:13:57,127: WARNING/ForkPoolWorker-7] i, R,G,B: 5, 255,0,0
[2018-07-23 16:13:57,127: WARNING/ForkPoolWorker-7] i, R,G,B: 6, 255,0,0
[2018-07-23 16:13:57,128: WARNING/ForkPoolWorker-7] i, R,G,B: 7, 255,0,0
[2018-07-23 16:13:57,129: WARNING/ForkPoolWorker-7] i, R,G,B: 8, 255,0,0
[2018-07-23 16:13:57,129: WARNING/ForkPoolWorker-7] i, R,G,B: 9, 255,0,0
[2018-07-23 16:13:57,131: WARNING/ForkPoolWorker-7] i, R,G,B: 10, 255,0,0
[2018-07-23 16:13:57,132: WARNING/ForkPoolWorker-7] i, R,G,B: 11, 255,0,0
[2018-07-23 16:13:57,132: WARNING/ForkPoolWorker-7] i, R,G,B: 12, 255,0,0
[2018-07-23 16:13:57,133: WARNING/ForkPoolWorker-7] i, R,G,B: 13, 255,0,0
[2018-07-23 16:13:57,134: WARNING/ForkPoolWorker-7] i, R,G,B: 14, 255,0,0
[2018-07-23 16:13:57,136: WARNING/ForkPoolWorker-7] i, R,G,B: 15, 255,0,0
[2018-07-23 16:13:57,137: WARNING/ForkPoolWorker-7] i, R,G,B: 16, 255,0,0
[2018-07-23 16:13:57,139: WARNING/ForkPoolWorker-7] i, R,G,B: 17, 255,0,0
[2018-07-23 16:13:57,140: WARNING/ForkPoolWorker-7] i, R,G,B: 18, 255,0,0
[2018-07-23 16:13:57,141: WARNING/ForkPoolWorker-7] i, R,G,B: 19, 255,0,0
[2018-07-23 16:13:57,142: WARNING/ForkPoolWorker-7] i, R,G,B: 20, 255,0,0
[2018-07-23 16:13:57,144: WARNING/ForkPoolWorker-7] i, R,G,B: 21, 255,0,0
[2018-07-23 16:13:57,145: WARNING/ForkPoolWorker-7] i, R,G,B: 22, 255,0,0
[2018-07-23 16:13:57,146: WARNING/ForkPoolWorker-7] i, R,G,B: 23, 255,0,0
[2018-07-23 16:13:57,147: WARNING/ForkPoolWorker-7] i, R,G,B: 24, 255,0,0
[2018-07-23 16:13:57,148: WARNING/ForkPoolWorker-7] i, R,G,B: 25, 255,0,0
[2018-07-23 16:13:57,149: WARNING/ForkPoolWorker-7] i, R,G,B: 26, 255,0,0
[2018-07-23 16:13:57,150: WARNING/ForkPoolWorker-7] i, R,G,B: 27, 255,0,0
[2018-07-23 16:13:57,151: WARNING/ForkPoolWorker-7] i, R,G,B: 28, 255,0,0
[2018-07-23 16:13:57,151: WARNING/ForkPoolWorker-7] i, R,G,B: 29, 255,0,0

Received color red on the arduino:
i, R,G,B: 0, 195,191,0
i, R,G,B: 1, 195,191,0
i, R,G,B: 2, 195,191,0
i, R,G,B: 3, 195,191,0
i, R,G,B: 4, 195,191,0
i, R,G,B: 5, 195,191,0
i, R,G,B: 6, 195,191,0
i, R,G,B: 7, 195,191,0
i, R,G,B: 8, 195,191,0
i, R,G,B: 9, 195,191,0
i, R,G,B: 10, 195,191,0
i, R,G,B: 11, 195,191,0
i, R,G,B: 12, 195,191,0
i, R,G,B: 13, 195,191,0
i, R,G,B: 14, 195,191,0
i, R,G,B: 15, 195,191,0
i, R,G,B: 16, 195,191,0
i, R,G,B: 17, 195,191,0
i, R,G,B: 18, 195,191,0
i, R,G,B: 19, 195,191,0
i, R,G,B: 20, 195,191,0
i, R,G,B: 21, 195,191,0
i, R,G,B: 22, 195,191,0
i, R,G,B: 23, 195,191,0
i, R,G,B: 24, 195,191,0
i, R,G,B: 25, 195,191,0
i, R,G,B: 26, 76,27,195

Sending color green from Python:
[2018-07-23 16:22:34,374: WARNING/ForkPoolWorker-8] i, R,G,B: 0, 0,255,0
[2018-07-23 16:22:34,376: WARNING/ForkPoolWorker-8] i, R,G,B: 1, 0,255,0
[2018-07-23 16:22:34,377: WARNING/ForkPoolWorker-8] i, R,G,B: 2, 0,255,0
[2018-07-23 16:22:34,378: WARNING/ForkPoolWorker-8] i, R,G,B: 3, 0,255,0
[2018-07-23 16:22:34,380: WARNING/ForkPoolWorker-8] i, R,G,B: 4, 0,255,0
[2018-07-23 16:22:34,381: WARNING/ForkPoolWorker-8] i, R,G,B: 5, 0,255,0
[2018-07-23 16:22:34,382: WARNING/ForkPoolWorker-8] i, R,G,B: 6, 0,255,0
[2018-07-23 16:22:34,383: WARNING/ForkPoolWorker-8] i, R,G,B: 7, 0,255,0
[2018-07-23 16:22:34,384: WARNING/ForkPoolWorker-8] i, R,G,B: 8, 0,255,0
[2018-07-23 16:22:34,385: WARNING/ForkPoolWorker-8] i, R,G,B: 9, 0,255,0
[2018-07-23 16:22:34,386: WARNING/ForkPoolWorker-8] i, R,G,B: 10, 0,255,0
[2018-07-23 16:22:34,387: WARNING/ForkPoolWorker-8] i, R,G,B: 11, 0,255,0
[2018-07-23 16:22:34,387: WARNING/ForkPoolWorker-8] i, R,G,B: 12, 0,255,0
[2018-07-23 16:22:34,388: WARNING/ForkPoolWorker-8] i, R,G,B: 13, 0,255,0
[2018-07-23 16:22:34,389: WARNING/ForkPoolWorker-8] i, R,G,B: 14, 0,255,0
[2018-07-23 16:22:34,389: WARNING/ForkPoolWorker-8] i, R,G,B: 15, 0,255,0
[2018-07-23 16:22:34,390: WARNING/ForkPoolWorker-8] i, R,G,B: 16, 0,255,0
[2018-07-23 16:22:34,390: WARNING/ForkPoolWorker-8] i, R,G,B: 17, 0,255,0
[2018-07-23 16:22:34,391: WARNING/ForkPoolWorker-8] i, R,G,B: 18, 0,255,0
[2018-07-23 16:22:34,392: WARNING/ForkPoolWorker-8] i, R,G,B: 19, 0,255,0
[2018-07-23 16:22:34,393: WARNING/ForkPoolWorker-8] i, R,G,B: 20, 0,255,0
[2018-07-23 16:22:34,393: WARNING/ForkPoolWorker-8] i, R,G,B: 21, 0,255,0
[2018-07-23 16:22:34,394: WARNING/ForkPoolWorker-8] i, R,G,B: 22, 0,255,0
[2018-07-23 16:22:34,395: WARNING/ForkPoolWorker-8] i, R,G,B: 23, 0,255,0
[2018-07-23 16:22:34,395: WARNING/ForkPoolWorker-8] i, R,G,B: 24, 0,255,0
[2018-07-23 16:22:34,396: WARNING/ForkPoolWorker-8] i, R,G,B: 25, 0,255,0
[2018-07-23 16:22:34,397: WARNING/ForkPoolWorker-8] i, R,G,B: 26, 0,255,0
[2018-07-23 16:22:34,398: WARNING/ForkPoolWorker-8] i, R,G,B: 27, 0,255,0
[2018-07-23 16:22:34,398: WARNING/ForkPoolWorker-8] i, R,G,B: 28, 0,255,0
[2018-07-23 16:22:34,399: WARNING/ForkPoolWorker-8] i, R,G,B: 29, 0,255,0

Received color green on the Arduino:
i, R,G,B: 0, 0,195,191
i, R,G,B: 1, 0,195,191
i, R,G,B: 2, 0,195,191
i, R,G,B: 3, 0,195,191
i, R,G,B: 4, 0,195,191
i, R,G,B: 5, 0,195,191
i, R,G,B: 6, 0,195,191
i, R,G,B: 7, 0,195,191
i, R,G,B: 8, 0,195,191
i, R,G,B: 9, 0,195,191
i, R,G,B: 10, 0,195,191
i, R,G,B: 11, 0,195,191
i, R,G,B: 12, 0,195,191
i, R,G,B: 13, 0,195,191
i, R,G,B: 14, 0,195,191
i, R,G,B: 15, 0,195,191
i, R,G,B: 16, 0,195,191
i, R,G,B: 17, 0,195,191
i, R,G,B: 18, 0,195,191
i, R,G,B: 19, 0,195,191
i, R,G,B: 20, 0,195,191
i, R,G,B: 21, 0,195,191
i, R,G,B: 22, 0,195,191
i, R,G,B: 23, 0,195,191
i, R,G,B: 24, 0,195,191
i, R,G,B: 25, 0,195,191
i, R,G,B: 26, 76,28,0

Sending color blue from Python:
[2018-07-23 16:26:52,416: WARNING/ForkPoolWorker-2] i, R,G,B: 0, 0,0,255
[2018-07-23 16:26:52,416: WARNING/ForkPoolWorker-2] i, R,G,B: 1, 0,0,255
[2018-07-23 16:26:52,417: WARNING/ForkPoolWorker-2] i, R,G,B: 2, 0,0,255
[2018-07-23 16:26:52,417: WARNING/ForkPoolWorker-2] i, R,G,B: 3, 0,0,255
[2018-07-23 16:26:52,418: WARNING/ForkPoolWorker-2] i, R,G,B: 4, 0,0,255
[2018-07-23 16:26:52,418: WARNING/ForkPoolWorker-2] i, R,G,B: 5, 0,0,255
[2018-07-23 16:26:52,419: WARNING/ForkPoolWorker-2] i, R,G,B: 6, 0,0,255
[2018-07-23 16:26:52,419: WARNING/ForkPoolWorker-2] i, R,G,B: 7, 0,0,255
[2018-07-23 16:26:52,420: WARNING/ForkPoolWorker-2] i, R,G,B: 8, 0,0,255
[2018-07-23 16:26:52,420: WARNING/ForkPoolWorker-2] i, R,G,B: 9, 0,0,255
[2018-07-23 16:26:52,421: WARNING/ForkPoolWorker-2] i, R,G,B: 10, 0,0,255
[2018-07-23 16:26:52,421: WARNING/ForkPoolWorker-2] i, R,G,B: 11, 0,0,255
[2018-07-23 16:26:52,422: WARNING/ForkPoolWorker-2] i, R,G,B: 12, 0,0,255
[2018-07-23 16:26:52,422: WARNING/ForkPoolWorker-2] i, R,G,B: 13, 0,0,255
[2018-07-23 16:26:52,423: WARNING/ForkPoolWorker-2] i, R,G,B: 14, 0,0,255
[2018-07-23 16:26:52,423: WARNING/ForkPoolWorker-2] i, R,G,B: 15, 0,0,255
[2018-07-23 16:26:52,424: WARNING/ForkPoolWorker-2] i, R,G,B: 16, 0,0,255
[2018-07-23 16:26:52,424: WARNING/ForkPoolWorker-2] i, R,G,B: 17, 0,0,255
[2018-07-23 16:26:52,425: WARNING/ForkPoolWorker-2] i, R,G,B: 18, 0,0,255
[2018-07-23 16:26:52,426: WARNING/ForkPoolWorker-2] i, R,G,B: 19, 0,0,255
[2018-07-23 16:26:52,427: WARNING/ForkPoolWorker-2] i, R,G,B: 20, 0,0,255
[2018-07-23 16:26:52,427: WARNING/ForkPoolWorker-2] i, R,G,B: 21, 0,0,255
[2018-07-23 16:26:52,428: WARNING/ForkPoolWorker-2] i, R,G,B: 22, 0,0,255
[2018-07-23 16:26:52,428: WARNING/ForkPoolWorker-2] i, R,G,B: 23, 0,0,255
[2018-07-23 16:26:52,429: WARNING/ForkPoolWorker-2] i, R,G,B: 24, 0,0,255
[2018-07-23 16:26:52,429: WARNING/ForkPoolWorker-2] i, R,G,B: 25, 0,0,255
[2018-07-23 16:26:52,430: WARNING/ForkPoolWorker-2] i, R,G,B: 26, 0,0,255
[2018-07-23 16:26:52,430: WARNING/ForkPoolWorker-2] i, R,G,B: 27, 0,0,255
[2018-07-23 16:26:52,431: WARNING/ForkPoolWorker-2] i, R,G,B: 28, 0,0,255
[2018-07-23 16:26:52,431: WARNING/ForkPoolWorker-2] i, R,G,B: 29, 0,0,255

Received color blue on the Arduino:
i, R,G,B: 0, 0,0,195
i, R,G,B: 1, 0,0,195
i, R,G,B: 2, 0,0,195
i, R,G,B: 3, 0,0,195
i, R,G,B: 4, 0,0,195
i, R,G,B: 5, 0,0,195
i, R,G,B: 6, 0,0,195
i, R,G,B: 7, 0,0,195
i, R,G,B: 8, 0,0,195
i, R,G,B: 9, 0,0,195
i, R,G,B: 10, 0,0,195
i, R,G,B: 11, 0,0,195
i, R,G,B: 12, 0,0,195
i, R,G,B: 13, 0,0,195
i, R,G,B: 14, 0,0,195
i, R,G,B: 15, 0,0,195
i, R,G,B: 16, 0,0,195
i, R,G,B: 17, 0,0,195
i, R,G,B: 18, 0,0,195
i, R,G,B: 20, 0,0,195
i, R,G,B: 23, 191,76,26

Sending color orange from Python:
[2018-07-23 16:29:20,725: WARNING/ForkPoolWorker-9] i, R,G,B: 0, 255,128,0
[2018-07-23 16:29:20,726: WARNING/ForkPoolWorker-9] i, R,G,B: 1, 255,128,0
[2018-07-23 16:29:20,727: WARNING/ForkPoolWorker-9] i, R,G,B: 2, 255,128,0
[2018-07-23 16:29:20,728: WARNING/ForkPoolWorker-9] i, R,G,B: 3, 255,128,0
[2018-07-23 16:29:20,729: WARNING/ForkPoolWorker-9] i, R,G,B: 4, 255,128,0
[2018-07-23 16:29:20,731: WARNING/ForkPoolWorker-9] i, R,G,B: 5, 255,128,0
[2018-07-23 16:29:20,732: WARNING/ForkPoolWorker-9] i, R,G,B: 6, 255,128,0
[2018-07-23 16:29:20,733: WARNING/ForkPoolWorker-9] i, R,G,B: 7, 255,128,0
[2018-07-23 16:29:20,734: WARNING/ForkPoolWorker-9] i, R,G,B: 8, 255,128,0
[2018-07-23 16:29:20,735: WARNING/ForkPoolWorker-9] i, R,G,B: 9, 255,128,0
[2018-07-23 16:29:20,736: WARNING/ForkPoolWorker-9] i, R,G,B: 10, 255,128,0
[2018-07-23 16:29:20,737: WARNING/ForkPoolWorker-9] i, R,G,B: 11, 255,128,0
[2018-07-23 16:29:20,738: WARNING/ForkPoolWorker-9] i, R,G,B: 12, 255,128,0
[2018-07-23 16:29:20,739: WARNING/ForkPoolWorker-9] i, R,G,B: 13, 255,128,0
[2018-07-23 16:29:20,740: WARNING/ForkPoolWorker-9] i, R,G,B: 14, 255,128,0
[2018-07-23 16:29:20,741: WARNING/ForkPoolWorker-9] i, R,G,B: 15, 255,128,0
[2018-07-23 16:29:20,742: WARNING/ForkPoolWorker-9] i, R,G,B: 16, 255,128,0
[2018-07-23 16:29:20,743: WARNING/ForkPoolWorker-9] i, R,G,B: 17, 255,128,0
[2018-07-23 16:29:20,744: WARNING/ForkPoolWorker-9] i, R,G,B: 18, 255,128,0
[2018-07-23 16:29:20,744: WARNING/ForkPoolWorker-9] i, R,G,B: 19, 255,128,0
[2018-07-23 16:29:20,745: WARNING/ForkPoolWorker-9] i, R,G,B: 20, 255,128,0
[2018-07-23 16:29:20,746: WARNING/ForkPoolWorker-9] i, R,G,B: 21, 255,128,0
[2018-07-23 16:29:20,747: WARNING/ForkPoolWorker-9] i, R,G,B: 22, 255,128,0
[2018-07-23 16:29:20,747: WARNING/ForkPoolWorker-9] i, R,G,B: 23, 255,128,0
[2018-07-23 16:29:20,749: WARNING/ForkPoolWorker-9] i, R,G,B: 24, 255,128,0
[2018-07-23 16:29:20,750: WARNING/ForkPoolWorker-9] i, R,G,B: 25, 255,128,0
[2018-07-23 16:29:20,750: WARNING/ForkPoolWorker-9] i, R,G,B: 26, 255,128,0
[2018-07-23 16:29:20,751: WARNING/ForkPoolWorker-9] i, R,G,B: 27, 255,128,0
[2018-07-23 16:29:20,752: WARNING/ForkPoolWorker-9] i, R,G,B: 28, 255,128,0
[2018-07-23 16:29:20,752: WARNING/ForkPoolWorker-9] i, R,G,B: 29, 255,128,0

Received color orange on the Arduino:
i, R,G,B: 0, 195,191,194
i, R,G,B: 1, 195,191,194
i, R,G,B: 2, 195,191,194
i, R,G,B: 3, 195,191,194
i, R,G,B: 4, 195,191,194
i, R,G,B: 5, 195,191,194
i, R,G,B: 6, 195,191,194
i, R,G,B: 7, 195,191,194
i, R,G,B: 8, 195,191,194
i, R,G,B: 9, 195,191,194
i, R,G,B: 10, 195,191,194
i, R,G,B: 11, 195,191,194
i, R,G,B: 12, 195,191,194
i, R,G,B: 13, 195,191,194
i, R,G,B: 14, 195,191,194
i, R,G,B: 15, 195,191,194
i, R,G,B: 16, 195,191,194
i, R,G,B: 17, 195,191,194
i, R,G,B: 18, 195,191,194
i, R,G,B: 19, 195,191,194
i, R,G,B: 76, 23,195,191
i, R,G,B: 194, 128,0,76

Received color orange on the Arduino (again):
i, R,G,B: 0, 195,191,194
i, R,G,B: 1, 195,191,194
i, R,G,B: 2, 195,191,194
i, R,G,B: 3, 195,191,194
i, R,G,B: 4, 195,191,194
i, R,G,B: 5, 195,191,194
i, R,G,B: 6, 195,191,194
i, R,G,B: 7, 195,191,194
i, R,G,B: 8, 195,191,194
i, R,G,B: 9, 195,191,194
i, R,G,B: 10, 195,191,194
i, R,G,B: 11, 195,191,194
i, R,G,B: 12, 195,191,194
i, R,G,B: 13, 195,191,194
i, R,G,B: 14, 195,191,194
i, R,G,B: 15, 195,191,194
i, R,G,B: 16, 195,191,194
i, R,G,B: 17, 195,191,194
i, R,G,B: 18, 195,191,194
i, R,G,B: 128, 0,76,24
i, R,G,B: 27, 195,191,194

Another Edit:
What is also interesting is that the main color (e.g. when I send red most of the LEDs are yellow) stays the same every time I tried.
But the amount of LEDs that gets passed differs with each try. The same goes for the last one or two LEDs the Arduino receives. Their colors and indexes are all over the place.

generates smooth color transitions .... do not send transitions ..... send discrete colors to the whole string  0xFF0000, 0x00FF00, 0x0000FF, 0xFFFF00 ... etc ...............document the resulting color ...... check color value on the web ....  http://html-color-codes.com/       ................ update your question with results

Red and green produce yellow. I think you are seeing cyan 0x00FFFF. It kind of looks like the bits are inverted.

@jsotola I added some sample data, maybe you could take a look again?

@Gerben That was a mistake on my end, red actually show up as yellow on the strip.

Try using a lower baudrate and see if the problem persists.

You don't seem to be using the bytes correctly

@Gerben Thank you, after reducing the baud rate to 57600 all lights look the same (still the same wrong color though). Unfortunately the weird behavior persists if I leave the color printing on, so apparently the Arduino Uno is a little too weak for doing both.

@esoterik Can you elaborate?

@smoelge chr(rgb[0]).encode() is a little bit obtuse; you are making an arbitrary chcaracer of an int, then encoding it, when you should just call .to_bytes on it. ex. rgb[0].to_bytes(1,'big') or simple convert all 3 at once with bytes(rgb)

@smoelge, you have to start at bottom and work your way up .... remove all code that has anything to do with the LEDs  .... send only single bytes and receive only single bytes, with a pause in between ..... if that has no errors, then send two bytes and test again .... reinsert the LED code only after the serial comm is reliable

This
...
  self.arduino.write(chr(76).encode()) # 'L'
  self.arduino.write(chr(i).encode())
  self.arduino.write(chr(rgb[0]).encode())
  self.arduino.write(chr(rgb[1]).encode())
  self.arduino.write(chr(rgb[2]).encode())
self.arduino.write(chr(90).encode()) # 'Z'
...

should be spelled:
  self.arduino.write(b'L')
  self.arduino.write(i.to_bytes(1,'big'))
  self.arduino.write(bytes(rgb))
self.arduino.write(b'Z')

It is much more readable this way; you could refactor even further:
  sout = b'L' + i.to_bytes(1,'big') + bytes(rgb)
  self.arduino.write(sout)
self.arduino.write(b'Z')

Your also wasting effort here:
Serial.println("i, R,G,B: " + String(i) + ", " + String(r) + "," + String(g) + "," + String(b));

This should be said more like this:
Serial.print(i);
Serial.print(", ");
Serial.print(r);
Serial.print(", ");
Serial.print(g);
Serial.print(", ");
Serial.println(b);

This eliminates three temporary String objects you were creating with String().
The rest of the code looks like it should work so you should try trouble shooting, you could:

Lower the baud rate till it works
Try 9600 baud and increase it until it stops working
Try the a serial sample program, make sure the serial portion is working correctly first
Write your own minimal test program, make sure the serial is working correctly at first.

Thank you very much, this worked perfectly.
And you are completely right about the String concatenation, I wasn't really paying attention to performance, due to those values just being printed for debugging.


text:
storage problem
I made a Arduino program to control my air conditioner(model:GREE Lomo) by PC.
I download IRremote library from here for that.
#include "IRremote.h"

IRsend irsend;
int irPin = 3; // pin IR led

int khz = 38; // 38kHz carrier frequency for the NEC protocol

const unsigned int irSignalOn[] = {8972, 4492, 644, 1664, 640, 564, 644, 564, 640, 1668, 636, 568, 640, 1664, 644, 560, 644,
                               560, 644, 564, 640, 564, 644, 560, 644, 1664, 640, 564, 644, 564, 640, 564, 640, 1668, 640, 1664, 640, 564, 644,
                               1664, 640, 564, 644, 564, 640, 1668, 640, 1664, 640, 564, 644, 564, 640, 564, 640, 564, 644, 564, 640, 1664, 644,
                               560, 644, 1664, 640, 564, 644, 564, 640, 1668, 640, 560, 644, 19980, 640, 564, 644, 1664, 640, 1668, 640, 564, 640,
                               564, 644, 1660, 644, 560, 644, 564, 644, 560, 644, 564, 640, 564, 644, 560, 644, 564, 640, 1664, 640, 564, 644, 564,
                               640, 564, 640, 564, 644, 564, 640, 564, 644, 560, 644, 564, 640, 564, 644, 564, 640, 564, 640, 564, 644, 560, 644, 564,
                               640, 564, 640, 564, 644, 1664, 640, 564, 644, 39972, 8976, 4496, 640, 1664, 644, 560, 644, 564, 640, 1668, 640, 564, 640,
                               1668, 640, 564, 640, 564, 644, 560, 644, 564, 640, 564, 644, 1664, 640, 564, 644, 564, 640, 564, 644, 1664, 640, 1668, 640,
                               564, 640, 1668, 640, 564, 640, 564, 644, 1668, 636, 1668, 640, 564, 640, 564, 640, 564, 644, 560, 644, 564, 644, 560, 644,
                               1668, 640, 1664, 640, 564, 644, 564, 640, 1668, 640, 564, 640, 19980, 640, 564, 644, 564, 640, 564, 644, 560, 644, 564, 640,
                               564, 644, 560, 644, 564, 640, 564, 640, 564, 644, 564, 640, 1668, 636, 568, 640, 1664, 640, 564, 640, 1672, 636, 1664, 640,
                               564, 644, 564, 640, 564, 640, 1668, 640, 564, 640, 564, 640, 568, 640, 1664, 640, 564, 640, 564, 644, 564, 640, 1692, 616,
                               1664, 640, 564, 640, 1664, 640, 39980, 8972, 4492, 644, 1664, 640, 568, 636, 564, 644, 1664, 640, 564, 640, 1668, 640, 564,
                               640, 564, 644, 564, 640, 564, 640, 564, 640, 1668, 640, 564, 640, 568, 640, 560, 644, 1664, 640, 1664, 644, 564, 640, 1668,
                               640, 564, 640, 564, 644, 1660, 644, 1664, 640, 564, 644, 560, 644, 564, 640, 564, 640, 564, 644, 1664, 640, 1664, 644, 1664,
                               644, 560, 644, 564, 640, 1668, 640, 560, 644, 19984, 640, 564, 644, 560, 644, 564, 640, 564, 640, 564, 640, 564, 644, 564, 640,
                               564, 644, 564, 640, 564, 640, 564, 640, 568, 640, 564, 644, 560, 644, 564, 640, 564, 644, 560, 644, 564, 640, 564, 644, 564,
                               640, 1664, 640, 1668, 640, 564, 640, 564, 640, 564, 644, 564, 640, 568, 640, 560, 644, 1668, 640, 1664, 640, 564, 640, 564, 644
                              };

const unsigned int irSignalOff[] = {8996, 4496, 640, 1688, 616, 568, 636, 568, 640, 568, 636, 568, 640, 1688, 616, 568, 640, 564, 640, 564, 640, 564, 644, 564,
                                640, 1688, 616, 1692, 616, 568, 640, 568, 636, 1668, 640, 1688, 616, 1692, 616, 568, 636, 568, 640, 564, 640, 1692, 616,
                                568, 636, 568, 636, 568, 640, 564, 640, 568, 636, 568, 640, 1688, 616, 564, 640, 1692, 616, 568, 636, 564, 640, 1672, 636,
                                564, 644, 19980, 640, 568, 636, 1692, 616, 1688, 616, 568, 636, 568, 640, 1688, 616, 572, 636, 564, 640, 568, 640, 564, 640,
                                568, 636, 568, 636, 568, 640, 1688, 616, 568, 640, 564, 640, 568, 636, 564, 640, 568, 640, 564, 640, 564, 640, 568, 640, 568,
                                636, 568, 636, 568, 640, 564, 640, 564, 640, 568, 636, 568, 640, 1688, 616, 568, 636, 1692, 616, 39980, 8972, 4496, 640, 1688,
                                616, 568, 636, 568, 640, 568, 636, 568, 636, 1692, 616, 564, 640, 568, 640, 564, 640, 564, 640, 568, 640, 1688, 616, 1692, 612,
                                568, 640, 564, 640, 1692, 612, 1692, 616, 1692, 616, 564, 640, 568, 640, 564, 640, 1692, 612, 568, 640, 568, 636, 568, 636, 568,
                                640, 564, 640, 564, 640, 568, 640, 1692, 612, 1692, 616, 568, 640, 564, 640, 1688, 616, 568, 636, 19984, 640, 564, 640, 568, 640,
                                564, 640, 568, 636, 568, 636, 568, 640, 564, 640, 568, 636, 568, 640, 564, 640, 564, 644, 1688, 616, 568, 640, 564, 640, 568, 636,
                                568, 640, 564, 640, 568, 636, 1672, 636, 1692, 612, 568, 640, 564, 640, 568, 636, 568, 640, 1692, 612, 568, 640, 568, 636, 568, 640,
                                564, 640, 1692, 616, 1668, 632, 568, 640, 39980, 8972, 4500, 640, 1688, 616, 568, 636, 568, 640, 564, 640, 568, 636, 1668, 640, 568,
                                636, 568, 640, 568, 636, 564, 640, 568, 636, 1692, 616, 1688, 616, 568, 636, 568, 640, 1668, 636, 1688, 620, 1692, 612, 568, 640, 564,
                                640, 564, 640, 1692, 612, 568, 640, 564, 644, 564, 640, 564, 640, 552, 652, 568, 640, 1688, 616, 1688, 616, 1692, 616, 564, 640, 568,
                                640, 1664, 640, 564, 640, 19988, 636, 568, 640, 564, 640, 568, 636, 568, 640, 564, 640, 568, 636, 568, 640, 564, 640, 564, 640, 568,
                                636, 568, 640, 568, 636, 568, 640, 568, 640, 564, 636, 568, 640, 568, 636, 568, 636, 568, 636, 568, 640, 1668, 636, 1692, 616, 568,
                                640, 564, 640, 564, 640, 568, 636, 568, 640, 564, 640, 1692, 616, 564, 640, 568, 636, 1692, 616
                               };

void setup() {
  pinMode(irPin, OUTPUT);
  Serial.begin(9600);
}

void loop() {

  if (Serial.available() > 0) {
    char letter = Serial.read();
    if (letter == '1') {
      irsend.sendRaw(irSignalOn, sizeof(irSignalOn) / sizeof(irSignalOn[0]), khz); //Note the approach used to automatically calculate the size of the array.
      Serial.println("ON");
    } else if (letter == '0') {
      irsend.sendRaw(irSignalOff, sizeof(irSignalOff) / sizeof(irSignalOff[0]), khz); //Note the approach used to automatically calculate the size of the array.
      Serial.println("OFF");
    }
  }
}

i got an error for arduino uno :
 Global variables use 2080 bytes (101%) of dynamic memory, leaving -32 bytes for local variables. Maximum is 2048 bytes.
how can i fix it?
EDIT 07/26:
I know with board like ATmega2560 problem will fix but I want use Arduino uno.
I tried to save my data at program memory but I don't know how to read that.

Search “PROGMEM”.

https://arduino.stackexchange.com/questions/54150/locally-declared-variable-takes-up-global-variable-space-in-dynamic-memory-sram

what make and model of air conditioner?

the signal data could be greatly reduced .... https://techdocs.altium.com/display/FPGA/NEC+Infrared+Transmission+Protocol

Re “I don't know how to read that”: 1. Search the Web for “Arduino PROGMEM”, or “AVR PROGMEM”. 2. Carefully read the resources you find, and try for yourself. 3. If you still can't after having given a genuine effort, then post here another question.

A solution is to move the tables into program memory (aka PROGMEM). Use the below:
const unsigned int irSignalOn[] PROGMEM = {
 ...
};

And modify the call to sendRaw() to sendRaw_P().
irsend.sendRaw_P(irSignalOn, sizeof(irSignalOn) / sizeof(irSignalOn[0]), khz);

For more information see the library documentation.
Cheers!

i used shirriff's IRremote library and compiler don't find sendRaw_P function ?

@MortezaMirzai Please update your question with all relevant information.

not an answer
please try this
let me know if it turns on the A/C when you press 1
#include "IRremote.h"

IRsend irsend;
int irPin = 3; // pin IR led

int khz = 38; // 38kHz carrier frequency for the NEC protocol

void setup() {
  pinMode(irPin, OUTPUT);
  Serial.begin(9600);
}

void loop() {

  if (Serial.available() > 0) {
    char letter = Serial.read();
    if (letter == '1') {
      irsend.sendNEC(0x4A08D3052, 35);
      irsend.sendNEC(0x64040002,  32);
      irsend.sendNEC(0x4A08D3032, 35);
      irsend.sendNEC(0x0015888D,  32);
      irsend.sendNEC(0x4A08D3072, 35);
      irsend.sendNEC(0x00000C0C,  32);

      Serial.println("ON");
    }
  }
}

I test that but it don't work. (maybe my fault) and compiler give a warning.

that's it? .... compiler give a warning  .... nothing about the warning? .... do you want help or not?

warning: large integer implicitly truncated to unsigned type [-Woverflow] irsend.sendNEC(0x4A08D3052, 35);

One can also jump to a Atmega1284P based board, with it's 16K of SRAM, 8x that of a '328P's 2K and 2x that of the Mega's 8K.  Dual hardware serial ports too if your project should need one.

or an esp8266 for cheaper and with 4X the ram and dozens of times the flash...

But limited to 3.3V operation, and I think much less current capability on the IO, if the project needs that.

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/

sort: votes


text:
How to parse 20180810T143000Z to time_t
What is the shortest/most elegant way (i.e. use existing lib functions) to parse a string in the form of 20180810T143000Z to a time_t? Note that the literal always represents a UTC timestamp.
I started parsing the string and assigning values to a struct tm *tm in order to do a mktime(tm) at the end. That feels overly complicated, though.

Which time library do you use? I would copy each needed character with an array index to a buffer and convert it to year, month, day, hours, minutes. After that I would use the library to convert that into a time_t for the number of seconds since 1970. Straightforward is not overly complicated in my opinion. Can you show what you have so far? sscanf might work, but some think that is not a elegant function.

Parsing the string really is the only way. However there are many ways of doing it.
My preferred method is to first check that the format is correct, by looking for the T and Z being in the right place:
if (timeString[8] == 'T' && timeString[15] == 'Z') {
    ... parse in here
}

And the parsing is just making numbers with multiplication:
int year = (timeString[0] - '0') * 1000 +
           (timeString[1] - '0') * 100 +
           (timeString[2] - '0') * 10 +
           (timeString[3] - '0');

You can clean things up with a macro if you like:
#define NUM(off, mult) ((timeString[(off)] - '0') * (mult))

Then:
int year =   NUM(0, 1000) + NUM(1, 100) + NUM(2, 10) + NUM(3, 1);
int month =  NUM(4, 10)   + NUM(5, 1);
int day =    NUM(6, 10)   + NUM(7, 1);
int hour =   NUM(9, 10)   + NUM(10, 1);
int minute = NUM(11, 10)  + NUM(12, 1);
int second = NUM(13, 10)  + NUM(14, 1);

And then, yes, put them in a struct tm (or directly assign them calculation results without using the intermediate variables) and call mktime().

@Juraj Yeah, but you haven't included any answer in your answer, only a block of code ;)

"first check that the format is correct" - a valid point but what would you do in the else branch?

I can't tell you that. It depends on the rest of your program. The answer may be "nothing", or it may be "tell the user", it "request a new timestamp", or any number of other things.

@Majenko sorry, I was a little unspecific. I'm still getting familiar with Arduino (as you can tell). What I meant was that in most other environments/platforms I'm familiar with I'd probably throw an exception. So, I believe returning -1 and handle this outside the function will make this more robust.

@MarcelStör Sure - if that's what you want to do.

Here is yet another way to convert the time stamp string to time_t. There are several great answers here already, but you may want to compare binary file sizes. This sketch's is 3884 bytes (IDE Version 1.0.6.2, GCC 4.2.1).
#include <Time.h>
TimeElements myTimeElements;
char timeString[] = "20180810T143000Z";

void setup(){

  Serial.begin(9600);

  myTimeElements.Year = CalendarYrToTm((timeString[0] - '0') * 1000 + (timeString[1] - '0') * 100 + (timeString[2] - '0') * 10 + (timeString[3] - '0'));
  myTimeElements.Month = (timeString[4] - '0') * 10 + (timeString[5] - '0');
  myTimeElements.Day = (timeString[6] - '0') * 10 + (timeString[7] - '0');
  myTimeElements.Hour = (timeString[9] - '0') * 10 + (timeString[10] - '0');
  myTimeElements.Minute = (timeString[11] - '0') * 10 + (timeString[12] - '0');
  myTimeElements.Second = (timeString[13] - '0') * 10 + (timeString[14] - '0');

  // Assemble time elements into time_t.
  time_t t = makeTime(myTimeElements);

  // Print out the contents of "t" one "piece" at a time using the "time_t" functions.
  Serial.println(year(t));
  Serial.println(month(t));
  Serial.println(day(t));
  Serial.println(hour(t));
  Serial.println(minute(t));
  Serial.println(second(t));

}

void loop(){}

#include <Time.h>

void setup() {

  Serial.begin(115200);

  char buff[] = "20180810T143000Z";
  for (int i = 0; i < sizeof(buff); i++) {
    buff[i] = buff[i] - '0';
  }
  int yr = buff[0] * 1000 + buff[1] * 100 + buff[2] * 10 + buff[3];
  if (yr > 99)
    yr = yr - 1970;
  else
    yr += 30;
  TimeElements tm;
  tm.Year = yr;
  tm.Month = buff[4] * 10 + buff[5];
  tm.Day = buff[6] * 10 + buff[7];
  // 8 T
  tm.Hour = buff[9] * 10 + buff[10];
  tm.Minute = buff[11] * 10 + buff[12];
  tm.Second = buff[13] * 10 + buff[14];

  time_t t = makeTime(tm);

  sprintf(buff, "%02d%02d%02d %02d%02d%02d", year(t), month(t), day(t), hour(t), minute(t), second(t));

  Serial.println(buff);

}

void loop() {

}

You can install TimeLib in Library Manager. It works on all Arduino platforms.

Yep, I did look into strptime but concluded it would probably not work w/o delimiters. Therefore, I didn't even try.

In buff[i++] * 10 + buff[i++], the order of evaluation of the i++ is unspecified. It may work as expected with any particular combination of compiler version and settings, and fail on the next one. gcc 5.4 warns me that “operation on ‘i’ may be undefined”. The correct way to do that is tm.Month = buff[i++] * 10; tm.Month += buff[i++];.

@EdgarBonet thanks, I just proposed this change: https://arduino.stackexchange.com/review/suggested-edits/38715

@MarcelStör, I read Edgar's comment, but this code is not some snippet, but a complete working example. I don't like edit it without testing. And I can't test it now.

@MarcelStör: What I wrote for tm.Month is valid for every instance where i++ appears more than once in the same expression.

@EdgarBonet I know, makes total sense. That's why proposed that edit. In the end it was ok to get rejected because many more lines are actually affected.

in this case the use of i++ is good. the compiler has no reason to evaluate some subexpression with i++ later in expression before some subexpression with i++ earlier in expression. I will change it. I saw the warning, but I had limited time for this.

Re “the compiler has no reason to evaluate [...]”: it also has no reason to evaluate them in the order you expect! Please, learn about sequence points in C++ before making such wrong assumptions. Note specifically that “Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression.”

Alternative to my first answer would be to use standard C functions from time.h and sscanf. C function strptime can't parse the timestamp without delimiters. But sscanf can parse your input.
#include <time.h>

void setup() {

  Serial.begin(115200);

  const char* buff = "20180810T143000Z";

  tm tms;
  sscanf(buff, "%04d%02d%02dT%02d%02d%02d", &(tms.tm_year), &(tms.tm_mon), &(tms.tm_mday), &(tms.tm_hour), &(tms.tm_min), &(tms.tm_sec));
  tms.tm_year -= 1900;
  tms.tm_mon -= 1;
  tms.tm_isdst = 0;
  time_t t = mktime(&tms);

  Serial.println(ctime(&t));
}

void loop() {
}

In AVR "%02hhd" must be used because the corresponding members in struct tm are int8_t.

The %d is for an integer, also for an avr microcontroller. The difference is that the TimeLib TimeElements does not use integers, but bytes.

@Jot, this is C time.h

Yes, for the C time.h the tm_year and other elements are all integers. Also for a avr microcontroller the %d matches an integer. The %d expects an 'int', not a 2 or 4 byte variable.

%d on AVR works for sprintf, but sscanf read wrong without hh. try it

I tried it in a number of different ways with different data on the stack, using arduino 1.8.5 with arduino uno board. A 'int' is two bytes, a 'short int' is also two bytes and 'short short int' does not exist. Format "%d" works with a 'int', and "%hd" seems to do the same as the "%d". Format "%hhd" reads a signed byte. Everything is as I remember it, no weird things. If you can prove that you are right with a sketch, can you start a new topic for that?

@Jot, it is only when I use the tm struct members as sscanf parameters. The warning is '%d' expects argument of type 'int*', but argument 4 has type 'int8_t* {aka signed char*}'. and the scanned values are wrong. With regular int variable the hh is not needed.

AVR has int8_t          tm_hour

Now I see it, the tm for avr has int8_t and int16_t elements. Sorry, they are indeed not all integers for avr. I did not know that. Thanks. Do you agree that %d in sscanf matches 'int' for avr? I see that you have removed that confusing last sentence.

I used hh because a compiler warning saying that it is int8_t and it helped to get correct data. I opened time.h, but it was for samd or for esp and there was int. I had limited time so I didn't investigate it further than. Of course %d is for int. I tested int and removed the note. Then I discovered that in tm really is unt8_t in tm.

For the sake of completeness here's my "answer" working with Strings rather than char[].
time_t convertToTime(String calTimestamp) {
  struct tm tm;
  Serial.println("Parsing " + calTimestamp);
  String year = calTimestamp.substring(0, 4);
  String month = calTimestamp.substring(4, 6);
  if (month.startsWith("0")) {
    month = month.substring(1);
  }
  String day = calTimestamp.substring(6, 8);
  if (day.startsWith("0")) {
    month = day.substring(1);
  }
  tm.tm_year = year.toInt() - 1900;
  tm.tm_mon = month.toInt() - 1;
  tm.tm_mday = day.toInt();
  tm.tm_hour = calTimestamp.substring(9, 11).toInt();
  tm.tm_min = calTimestamp.substring(11, 13).toInt();
  tm.tm_sec = calTimestamp.substring(13, 15).toInt();
  return mktime(&tm);
}

That poor poor heap. I feel for it...

This should work, but note that every call to the substring() method allocates a new String on the heap. Even if you have plenty of free memory, the multiple calls to malloc() and free() can make this quite inefficient.

@EdgarBonet yes, I know, point taken. What is fed into this function is the (partial) result of an HTTP response readStringUntil(). I guess it'd be more efficient to first convert calTimestamp into a char[]?

Quite likely. The String method c_str() returns the internal char * pointer, so no real conversion is needed.

This is not complete without sscanf.
I took the sketch by @Juraj and declared seperate integers to be sure that every %d would match with an integer.
#include <Time.h>

void setup() {

  Serial.begin(115200);

  char buff[] = "20180810T143000Z";

  TimeElements tm;

  int yr, mnth, d, h, m, s;
  sscanf( buff, "%4d%2d%2dT%2d%2d%2dZ", &yr, &mnth, &d, &h, &m, &s);

  tm.Year = yr - 1970;
  tm.Month = mnth;
  tm.Day = d;
  tm.Hour = h;
  tm.Minute = m;
  tm.Second = s;

  time_t t = makeTime(tm);

  sprintf(buff, "%02d-%02d-%02d %02d:%02d:%02d", year(t), month(t), day(t), hour(t), minute(t), second(t));

  Serial.println(buff);
}

void loop() {
}

Marcel Stör, there are now four good solutions. In my opinion they are equally good.

String datetimestr = "20180810T143000Z";
int splitted = datetimestr.indexOf("T");
String datestr = datetimestr.substring(0, splitted); //20180810
String timestr = datetimestr.substring(splitted + 1, datetimestr.length() - 1); //143000

The question was how to parse the string to a time_t, and you are not answering it.

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/


text:
Merge two Arduino projects (change build process)
I'm working on a big software project consisting of several Arduino sketches.
I have one Arduino project providing general functionality, such as TCP/IP communication, parsing queries, handling errors, and some more. This part is fundamental for several devices, which extend this fundamental part by specific functionalities. E.g. one device needs to read temperature sensors and manage a loop to control the temperature and has its own sketch. Another device is driving a servo motor and measuring sun light and also has its own sketch. (And there are some other devices with specific sketches.)
I want to maintain the fundamental part in ONE sketch and the specific parts of the different devices each in OTHER sketches, so I can code both separately.
The problem is, those specific parts can not be compiled if not merged with the fundamental sketch, as this provides basic functions. So if I compile any specific part, I want the fundamental part to be added to the specific one and afterwards the whole code should be compiled.
Is there a way to manipulate the makefile used by the Arduino IDE? Then I could use whatever I want (bash or Python script) to merge in the desired way first.

Assuming that each separate hardware device (ESP32?) must run self-contained with both the fundamental parts, and the use-specific parts, then you would do well to separate out the fundamentals into a library, and then include that library in each use-specific sketch.
The Adafruit Unified Sensor Driver would be one project that shows this. Each of the sensor libraries based on this driver must #include the unified sensor driver library, and that provides some basic properties and interfaces, while each sensor's individual code handles the specifics for communicating to/from that particular unique hardware device.

Okay, that's a pretty simple approach. Don't know how that didn't come to my mind! Thanks for that! Thinks are a bit complicate in my scenario, but I think implementing specific code as a library should work...

In my opinion, you don't need another Arduino. Most of the time, Arduino is fast enough to handle all the things you mentioned. It highly depends on your programming skills. For example, don't make your Arduino do nothing while waiting for a communication to complete and so on. The techniques you require are:
1) No delay functions at all in your programming. Go Arduino's examples and look for 'blink without delay' sketch.
2) Organize your programming. Make use of creating your own functions. Your void loop() should be a to-do-list.

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/


text:
How to get the firmware (hex) file from a .ino file containing the code
I currently have a .ino firmware file that I use in the Arduino IDE to program an ATmega328 micro-controller. I would like to get the file that the Arduino IDE uses to program the micro-controller.
Probably the IDE uses a hexadecimal (hex) file or something and sends it to the micro-controller through the serial.
How can I get this file being the only file that the IDE generates is the .ino?

These questions have been answered here before.

@ChrisStratton I removed my question (was not aware of what you wrote) ... if the question has already been answered, it should be marked as duplicate question (s).

I am getting .BIN file while using the above method in Arduino IDE.

I guess this isn't allowing to add another answer.  One approach is to use the "Export compiled binary" listed in the answers.  You can also have the build go to a more predictable (non-temp) folder/directory.   Edit your preferences.txt file and add the line build.path=<folder for build output>, specifying an existing folder to send the build artifacts to.  Your hex files will be in there the next check/build you run.

In the Preferences of the Arduino IDE; after Show verbose output during: check the box next to compilation.
Then when you compile you should get something like this at the bottom of the window:
...
...
"/Applications/Arduino.app/Contents/Java/hardware/tools/avr/bin/avr-objcopy" -O ihex -R .eeprom  "/var/folders/tp/grrlc56j3z7057f12_7f1_0r0000gn/T/arduino_build_635063/Blink.ino.elf" "/var/folders/tp/grrlc56j3z7057f12_7f1_0r0000gn/T/arduino_build_635063/Blink.ino.hex"
Sketch uses 928 bytes (3%) of program storage space. Maximum is 30720 bytes.
Global variables use 9 bytes (0%) of dynamic memory, leaving 2039 bytes for local variables. Maximum is 2048 bytes.

At the end of the third line from the bottom you get the .hex filename. In this case (on OSX) that would be /var/folders/tp/grrlc56j3z7057f12_7f1_0r0000gn/T/arduino_build_635063/Blink.ino.hex

Perfect, this I needed. Now if I send through the serial this .hex file to the microcontroller it will work as the UPLOAD of the IDE?

Click the checkbox next to it to get verbose output on upload. You can the see the command the IDE uses to upload. Just a hint. It uses the avrdude command line program for that.

You are asking how to locate the compiled hex file. It's easy! Follow these steps:

In the Arduino IDE select Sketch > Export Compiled Binary. This performs a compile. Once complete, this command places a copy of the compiled .hex file into the directory of your sketch.

Then either browse to the sketch folder or in the IDE select Sketch > Show Sketch Folder.

This generates two hex files for the target micro-controller; one with the bootloader and one without the bootloader. These hex files can be uploaded to the micro-controller using a programmer such as the Atmel Ice or AVRISPmkII.

It only places .bin files in the sketch folder.

The easiest way to get the file is:

Sketch > Export Compiled Binary
Wait for the compilation process to finish
Sketch > Show Sketch Folder

You will find an extra file in the sketch folder, which in this case will have a .hex extension. This is the compiled file which would normally be uploaded to the Arduino board via Sketch > Upload.
Note that the "Export Compiled Binary" feature is only available from Arduino IDE 1.6.5 and newer.

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/


text:
How can I add PWM to my BLDC code using port manipulation?
I have the following code, which currently uses 6 output pins (pins 8 - 13) from the Arduino to my inverter circuit, which controls a BLDC motor. The code is fine and it works, however I want to add PWM using port manipulation and not analogWrite, as this is not fast enough for this application.
I know for example I could write OCR1B = 200, which sets the duty cycle of pin 10 to 200 and replaces the analogWrite function, but I do not know where to put this in my code. Also, do I need 3 PWM pins as the commutation of a BLDC motor is done in 6 steps in order to do 1 full revolution, or do I only need 1 PWM pin?
void setup() {
  pinMode(A0, INPUT); // sensor inputs
  pinMode(A1, INPUT);
  pinMode(A2, INPUT);
  DDRB  |= B00111111; // Sets D8, D9, D10, D11, D12 and D13 as OUTPUT
  PORTB &= B11000000; // D8 to D13 LOW
}

void loop() {
  switch (PINC) {
    case 3:
      PORTB |= _BV(PB3); // set pin 11 high
      PORTB |= _BV(PB5); // set pin 13 high
      PORTB &= ~_BV(PB0); //set low
      PORTB &= ~_BV(PB1); //set low
      PORTB &= ~_BV(PB4); //set low
      PORTB &= ~_BV(PB2); //set low
      break;
    case 2:
      PORTB |= _BV(PB3); // set pin 11 high
      PORTB |= _BV(PB4); // set pin 12 high
      PORTB &= ~_BV(PB5); //set low
      PORTB &= ~_BV(PB2); //set low
      PORTB &= ~_BV(PB1); //set low
      PORTB &= ~_BV(PB0); //set low
      break;
    case 6:
      PORTB |= _BV(PB2); // set pin 10 high
      PORTB |= _BV(PB4); // set pin 12 high
      PORTB &= ~_BV(PB0); //set low
      PORTB &= ~_BV(PB1); //set low
      PORTB &= ~_BV(PB3); //set low
      PORTB &= ~_BV(PB5); //set low
      break;
    case 4:
      PORTB |= _BV(PB2); // set pin 10 high
      PORTB |= _BV(PB0); // set pin 8 high
      PORTB &= ~_BV(PB1); //set low
      PORTB &= ~_BV(PB5); //set low
      PORTB &= ~_BV(PD3); //set low
      PORTB &= ~_BV(PD4); //set low
      break;
    case 5:
      PORTB |= _BV(PB1); // set pin 9 high
      PORTB |= _BV(PB0); // set pin 8 high
      PORTB &= ~_BV(PB2); //set low
      PORTB &= ~_BV(PB4); //set low
      PORTB &= ~_BV(PB5); //set low
      PORTB &= ~_BV(PD4); //set low
      break;
    case 1:
      PORTB |= _BV(PB1); // set pin 9 high
      PORTB |= _BV(PB5); // set pin 13 high
      PORTB &= ~_BV(PB0); //set low
      PORTB &= ~_BV(PB4); //set low
      PORTB &= ~_BV(PB3); //set low
      PORTB &= ~_BV(PB2); //set low
      break;
  }
}

Did you manage to solve it?


text:
Send structure through Serial
Suppose that one defined a data structure and wanted to send it through serial.
 struct Gyro_data_structure {
    char command_name[5];
    float gyro_X;
    float gyro_Y;
    float gyro_Z;
};

Gyro_data_structure Gyro_data;

int size_gyro=sizeof(struct Gyro_data_structure);

void setup() {
  Serial.begin(9600); // opens serial port, sets data rate to 9600 bps
}

void loop() {
  Gyro_data.command_name[0]='H';
  Gyro_data.gyro_X++;
  Serial.println(size_gyro);
  delay(500);
  Serial.write(Gyro_data,size_gyro);
}

However, it returned an error saying "no matching function for call to 'HardwareSerial:write(Gyro_data_structure&,int&)'". I googled and found Michaël Roy's answer here. However, it's not working: "can not convert ..."
How to send a structure through UART?

i would start with code that works and then make small changes to find out what works and what does not work .... use the code that you found as an example ... change your struct to all integers

@jsotola currently, non of them were working, the only thing I haven't tried was union. Right now I'm trying the bitwise operator, but apparently int is singed.

start with the exact same sketch as the link that you posted

@jsotola That's the question, it didn't work.

you can send the structure as binary only if the receiver has the exact same way of store binary data in a structure as the sender. basically it will work only if the receiver uses the same compiler

I tried the code from the link you posted and it worked:
struct Gyro_data_structure
{
    char command_name[6];
    int gyro_X;
    int gyro_Y;
    int gyro_Z;
};

struct Gyro_data_structure Gyro_data = {"Hello", 48, 49 , 50};

int size_gyro = sizeof(struct Gyro_data_structure);

void setup()
{
  Serial.begin(9600); // opens serial port, sets data rate to 9600 bps
}

void loop()
{
  send(&Gyro_data);
  Serial.println();
  delay(1000);
}

void send (const Gyro_data_structure* table)
{
  Serial.write((const char*)table, size_gyro);  // 2 bytes.
}

bool receive(Gyro_data_structure* table)
{
  return (Serial.readBytes((char*)table, sizeof(Gyro_data_structure)) == sizeof(Gyro_data_structure));
}

I changed the float type to int for easy representation. When you run the code the serial window will show: Hello012
Because Arduino IDE serial window shows ASCII characters. 0's ASCII value is 48 and so on.

Update
It depends on what you want from the read function. Let's break down what Michaël Roy's implementation is doing. First, he reads sizeof(Gyro_data_structure) number of serial bytes and put it in the variable that table points to:
Serial.readBytes((char*)table, sizeof(Gyro_data_structure))

The 2nd argument of readBytes() takes how many bytes you want to read. Also readBytes() return how many bytes it read. Let's say we stored that number in return_bytes. In the next part he did:
return (return_bytes == sizeof(Gyro_data_structure))

He is checking if the number of bytes readBytes() read is the same as the size of  Gyro_data_structure. If it is not, then return false.
This just tells you if you read more or less than what you are supposed to read. Regardless of true or false, the actual bytes that were read will be in the variable that you passed to the receive() function.
If you don't want the function to not return anything this is how it should be:
void receive(Gyro_data_structure* table)
{
  Serial.readBytes((char*)table, sizeof(Gyro_data_structure));
}

Thank you soooooo much !!!!! That was really helpful! However, could you explain just a little bit what happened there? (char*) and send(&Gyro_data); receive(&Gyro_data); I want to learn and adjust the code for better noise resistance.

send() takes a pointer of Gyro_data_structure. That's why in the loop()  send() uses the address of the declared variable (Gyro_data). When you want to send the address of any variable you use '&' in front of that variable. Now, the address points to the first variable of the structure, which is command_name[0]. Serial.write() starts printing one byte at a time from that variable until it reaches size_gyro.

could you explain a little bit of why receiving part used bool instead of void?  and isn't second input of Serial.readBytes just 1?(say, 12==12 )

@ShoutOutAndCalculate I updated my answer to reflect your comment.

First of all, you have to decide whether you want to send the data as
raw bytes (“binary data”) or as an ASCII text representation. Binary
tends to be more efficient: you can send a float with full precision
in only four bytes, whereas you would typically need 8 to 9 significant
digits to recover the full precision from an ASCII representation.
Binary is, however, harder to handle: some types have different binary
representations on your Arduino and your PC, and you may need to define
a protocol of sorts in order to get the framing right. ASCII is easier,
and you can usually use end-of-lines as a simple framing device. I
generally recommend using ASCII unless you really need the extra
efficiency of a binary protocol.
Sending as binary
You can easily send arbitrary binary data using the method
write(const uint8_t *buffer, size_t size) from the Serial object:
Gyro_data_structure Gyro_data = {"Gyro", 0.0, 4.0, 5.0};

void loop() {
    Gyro_data.gyro_X++;
    Serial.write((uint8_t *) &Gyro_data, sizeof Gyro_data);
    delay(200);
}

Here is an hex dump of the output:
0000  47 79 72 6f 00 00 00 80  3f 00 00 80 40 00 00 a0  |Gyro....?...@...|
0010  40 47 79 72 6f 00 00 00  00 40 00 00 80 40 00 00  |@Gyro....@...@..|
[...]

which can be parsed as follows:
47 79 72 6f 00 = {'G', 'y', 'r', 'o', '\0'}
00 00 80 3f    = 0x3f800000 = 1.0f
00 00 80 40    = 0x40800000 = 4.0f
00 00 a0 40    = 0x40a00000 = 5.0f

Note that the floats are sent in little-endian order: lest significant
byte first. The 32-bit hex numbers above are the binary representations
of the floats.
Sending as text
Serial.print() is intended to print a text representation of the data
you give it. But since it does not know how to represent a
Gyro_data_structure, you have to Serial.print() each data member in
turn, and then add some formatting around all that:
void print_gyro(const Gyro_data_structure &gyro) {
    Serial.print(F("Gyro{command = \""));
    Serial.print(gyro.command_name);
    Serial.print(F("\", X = "));
    Serial.print(gyro.gyro_X);
    Serial.print(F(", Y = "));
    Serial.print(gyro.gyro_Y);
    Serial.print(F(", Z = "));
    Serial.print(gyro.gyro_Z);
    Serial.print(F("}"));
}

void loop() {
    Gyro_data.gyro_X++;
    print_gyro(Gyro_data);
    Serial.println();
    delay(200);
}

The output is
Gyro{command = "Gyro", X = 1.00, Y = 4.00, Z = 5.00}
Gyro{command = "Gyro", X = 2.00, Y = 4.00, Z = 5.00}
[...]

Making your data printable
This is a variation on the previous technique. You can Serial.print()
your object directly, if you tell the Arduino core how to print this
type of objects. This is done by letting your class inherit from
Printable and implementing the virtual method printTo(). But then
the class is not an “aggregate” anymore, and thus needs an explicit
constructor:
struct Gyro_data_structure : Printable
{
    char command_name[5];
    float gyro_X;
    float gyro_Y;
    float gyro_Z;
    Gyro_data_structure(const char *name, float x, float y, float z)
    : gyro_X(x), gyro_Y(y), gyro_Z(z) {
        strncpy(command_name, name, 4);
        command_name[4] = '\0';
    }
    size_t printTo(Print& p) const {
        size_t count = 0;
        count += p.print(F("Gyro{command = \""));
        count += p.print(command_name);
        count += p.print(F("\", X = "));
        count += p.print(gyro_X);
        count += p.print(F(", Y = "));
        count += p.print(gyro_Y);
        count += p.print(F(", Z = "));
        count += p.print(gyro_Z);
        count += p.print(F("}"));
        return count;
    }
};

Gyro_data_structure Gyro_data("Gyro", 0.0, 5.0, 5.0);

void loop() {
    Gyro_data.gyro_X++;
    Serial.println(Gyro_data);
    delay(200);
}

The output is identical as before. The definition of the class gets a
little bit clumsier, but then you can very easily print to any serial
port (be it an UART or a software implementation), to an LCD... or
whatever understands print().


text:
Is there a library to use Amazon IoT services on any Arduino?
I started to work with AWS IoT today, which offers a MQTT based connection to their web service. They officially only have a demo for the Arduino Yún, which is rather expensive. Has someone managed to get it running (e.g. with a NodeMCU with a ESP8266)?

Any comments from the downvoter?

You can try the AWS IoT Embedded C SDK, that is for more general devices.
Other Arduinos requires a crypto library and a device powerful enough, maybe PI, to support the authentication process...
At this time they have no crypto library like the YUN SDK, for other Arduinos...
Try it...


text:
How to add a yield before else if?
So I am running my project on a NodeMCU, but I don't know how to let it add a yield in front of an else if. It will give me an error like this:

Arduino:1.8.12 (Windows 10), 開發板:"NodeMCU 1.0 (ESP-12E Module), 80 MHz, Flash, Legacy (new can return nullptr), All SSL ciphers (most compatible), 4MB (FS:2MB OTA:~1019KB), 2, v2 Lower Memory, Disabled, None, Sketch + WiFi Settings, 115200"
G:\資優班\科展\程式碼\Front_End\Main_Code_V5\Main_Server\Main_Server.ino: In function 'void loop()':
Main_Server:84:5: error: 'else' without a previous 'if'
exit status 1
  'else' without a previous 'if'
This report would have more information with
  "Show verbose output during compilation"
  option enabled in File -> Preferences.

Here's the code:
#include <SPI.h>
#include <ESP8266WiFi.h>

#define MAX_SRV_CLIENTS 2
#define led LED_BUILTIN

WiFiServer server(80);
WiFiClient serverClients[MAX_SRV_CLIENTS];
IPAddress ip(10, 241, 241, 27);
IPAddress mask(255, 255, 255, 0);
IPAddress gateway(10, 241, 241, 254);
char ssid[] = "AP";
char pass[] = "Science_Fair";

void setup() {
  Serial.begin(9600);
  WiFi.config(ip, gateway, mask);
  WiFi.begin(ssid, pass);
  while (WiFi.status() != WL_CONNECTED) {
    yield();
  }
  server.begin();
  pinMode(led, OUTPUT);
  digitalWrite(led, LOW);
}

void loop() {
  uint8_t i;
  Serial.setTimeout(10);
  for (i = 0; i < MAX_SRV_CLIENTS; i++) {
    Serial.println("Pre 1");
    if (server.hasClient()) {
      Serial.println("Pre 2");
      if (!serverClients[i] || !serverClients[i].connected()) {
        Serial.println("Pre 3");
        if (serverClients[i]) {
          Serial.println("Pre 4");
          serverClients[i].stop();
          Serial.println("Pre 5");
        }
        Serial.println("Pre 6");
        serverClients[i] = server.available();
        Serial.println("Pre 7");
        serverClients[i].setTimeout(10);
        Serial.println("Pre 8");
        Serial.print("New client: ");
        Serial.println("Pre 9");
        Serial.println(i);
        Serial.println("Pre 10");
        break;
      }
    }
    yield();
  }
  for (i = 0; i < MAX_SRV_CLIENTS; i++) {
    String fromClient = serverClients[i].readStringUntil('e');
    Serial.println("P1");
    yield();
    if (fromClient == "LR") {
      Serial.println("LR");
      String reply = Serial.readStringUntil('e');
      Serial.println("P2");
      yield();
      if (reply == "Warn_B") {
        yield();
        Serial.println("Confirm");
        Serial.println("P3");
        for (i = 0; i < MAX_SRV_CLIENTS; i++) {
          serverClients[i].print("Warn_B");
          Serial.println("P4");
          yield();
        }
      }
    }
    yield(); // this is the yield I need to add
    else if (fromClient == "RR") {
      Serial.println("RR");
      Serial.println("P5");
      String reply = Serial.readStringUntil('e');
      Serial.println("P6");
      yield();
      if (reply == "Warn_A") {
        Serial.println("P7");
        Serial.println("Confirm");
      }
      for (i = 0; i < MAX_SRV_CLIENTS; i++) {
        serverClients[i].print("Warn_A");
        Serial.println("P8");
        yield();
      }
    }
    yield();
  }
}

I need the yield() there but I don't know how to let it still do the else if. Please help me guys, thanks!

Why do you  think you need a yield there?

@Majenko Uh cuz I am using my NodeMCU and I have a watchdog timer, I think there is the problem cuz it is always giving me a bunch of errors like feefeffe

Yes, but why there? Why between two pieces of code that are "either / or"? If the first ran then the second won't. If the second ran then the first won't have. There's no "between" in that scenario.

the yield() before the if is the yield() before the else

First of all do yourself a favour and listen to your IDE
This report would have more information with
 "Show verbose output during compilation"
option enabled in File -> Preferences.

and in an if else there is no in between so either let it run as a state machine especially inyour case A != B != C != other:
void subfunction(){
  if(A){
  // code to run
  return;
  }
 yield();
 if(B){
  // code to run
  return;
  }
 yield();
 if(C){
  // code to run
  return;
  }
 else{}  // to catch if not A or B or C
 yield();
}

or implement switch case (Pseudo code)
 switch(fromClient){
    case "LR":
      //code to run
      yield();
      break;
    case "RR":
      //code to run
      yield();
      break;
    default:
      //code to run
      yield();
      break;
  }

Id else chains are prone to errors as in your case its A != B != C != other

Thank you! But again I am at home, I'll test it tmr in my lab, thank you again!

why not yield() after the switch?

I just copied his"use case" but you are right he could even do it before the cases and in the case (depends on his WD timer


text:
How to split a *char and pass to a function needing uint8_t?
I have a requirement where an event has char *newvalue.
void event(char *newValue) {
//Code here
}

newValue is 2 digits. If it's 1-9 it is " 1" " 2" and 10+ is "10" "11" etc. It also can contain alpha characters as well not just numbers.
I am passing this to a function void function(uint8_t ascii) to display on a single digit display. If I pass newValue it doesn't register less than 10 as it picks up the space.
So what I am trying to achieve is if it's a single character, strip the space somehow into a uint8_t and if it's 2 digits strip just the right digit as a uint_8 and have a bool where I will turn on the decimal point.
I've googled like crazy and can't seem to get something workable. If somebody can help it would be appreciated. If the above is not clear please let me know what more info you need.
The code below, 'value here' is where I want to put the rightmost value from *newvalue.
void onUfcComm2DisplayChange(char *newValue) {
  comdisp.setBrightness(9);
  comdisp.writeDigitAscii(0, 'valuehere');
  comdisp.writeDisplay();
}

void Adafruit_AlphaNum4::writeDigitAscii(uint8_t n, uint8_t a,  boolean d, boolean w) {
  uint16_t font;
  if (w == false) {
    font = pgm_read_word(alphafonttable + a);
  } else {
    font = pgm_read_word(alphafonttableWD + a);
  }
  displaybuffer[n] = font;
  if (d) displaybuffer[n] |= (1 << 14);
}

Please show us the sketch you're using.

C++ function strtok() can be used for spliting a str into a token, as long as there is a delimiter in the str. https://www.cplusplus.com/reference/cstring/strtok/.

Thats where I have been unstuck. there is no delimiter.

I amended the basic code in original post

I'm not real clear on exactly what you want to have there, but here are a few ideas that may help:
If you know what character you want, then just get it.  Like if you always want the second character (I think this is what you need):
void someFunc(char *p)
{
  char secondChar = p[1];
  Serial.print(secondChar);
}

If you just want the last character in the string no matter how long, get the length of it and then pull that character:
void someFunc(char *p)
{
  int len = strlen(p);
  char lastChar = p[len-1];
  Serial.print(lastChar);
}

If you want the last digit in the string no matter how long and no matter how many random characters that aren't digits after it:
void someFunc(char *p)
{
  int len = strlen(p);
  char lastDigitChar = 0;
  // Cycle backwards til we get the first digit
  for(int i=len-1; i>=0; i--){
    if(isDigit(p[i]){
      lastDigitChar = p[i];
      break;
    }
  }
  Serial.print(lastDigitChar);
}

Thanks that is exactly what I was after..... I think I was just trying to overengineer the whole thing and that is just so simple it works perfectly thankyou!


text:
My 1604 LCD is bright with USB power but not when powered through the jack
I'm making a bench PSU. The Arduino runs off the purple 5v standby. The Mega also powers 2 LEDs (normal 5mm clear). The thing is, when I upload the code and watch the screen go through the process, it's bright and visible. But when I turn on the 5v standby (without USB) the text is visible if you try really really hard to see.
The 5v standby is rated at 2 amps MAX. I can't imagine it's the code but would anyone help? Why does USB power allow the LCD to power fully compared to the 5v standby?

Can you supply a schematic? And are you putting 5V into the barrel jack connector? If so, that's why you're getting a dim screen: the supply through the jack is supposed to be a minimum of 7V or so because it powers the onboard 5V regulator. 5V in will only give you about 3.75V out, maybe less. By "purple 5V standby" I guess you're using an ATX PSU?

get a barrel-jack to microUSB adapter for ~$1 online to by-pass the on-board voltage regulator dropout. Also, you might be able to adjust the contrast to work acceptably; i had one that i ran off 3.3v and at first it was super faint, but with tweaks it was more than acceptable for the viewing angle i needed.

I do not know how to upload fritzing files to the comment. However, dandavis sounds like he is onto something. The problem i have is that, i made a slot on the side of the enclosure to allow updates and debugging easy. The 5v standby was soldered under the onboard barrel connector legs. can i power the arduino  with the purple 5v standy via usb?

You are not supposed to put fritzing files to comments. Instead edit your question and put a screenshot of the fritzing there.

This really sounds, as if you were putting 5V to the barrel jack. That won't work, as CharlieHanson wrote. Connect it to the USB jack or directly to the Arduinos 5V pin.


text:
Analog pins as output by using digitalWrite
I am making a triac-controlled light dimmer. To control the triac I want to use pins A4 or A5, because others are occupied. I have tried the following functions and methods, but nothing seems to put the pins to HIGH state:
 1. pinMode(A4, OUTPUT);
    digitalWrite(A4, HIGH);
 2. pinMode(18,OUTPUT);
    digitalWrite(18,HIGH);
 3. DDRC |= (1 << DDC4);
    PORTC |= (1 << PC4);

I have tried the same things with A5 and other A# pins to no avail. The only pin that works is A0. Only when the triac is connected to it, the lamp lights on.
Is this a valid way to set analog pins?
void setup(){
  pinMode(A4, OUTPUT);
}

void loop(){
  digitalWrite(A4, HIGH);
}

Edit: My code was quite messy, it appears that some other functions prevented from using pins A4 or A5. It is working now.
It was the DS1307Emulator library. After initialization I had to use DS1307Emulator.busDisconnect();
Didn't know it uses I2C.

I feel that the code is ok.  How can you be sure that the pin is not in high state? Only with the triac? Can you post the schematic here?

Do you use a Atmega328p chip and not an Arduino board ? Did you forget to apply 5V to all the VCC and AVCC pins ? and GND to all the GND pins ? If you have done everything right, then the Atmega32p is broken.

@fra
Actually the pin is in high state when measuring with voltmeter, but when it is connected to the triac, the lamp does not light up, however, it does when it is connected to A0.

@Jot Arduino pro mini is used. All pins are connected. By changing Arduinos results are the same.

@flowian very strange. Do you use an optocoupler between the arduino and the triac? Can you post the schematic?

Can you post the sketch as well ? Are you sure you are using A4 and A5 and not A6 and A7 ? And you don't use I2C ? You could make a small test sketch to test those pins. The problem is in the part that you have not showed us yet.

@fra, there is optocoupler. I posted the schematic. All this works with regular digital pins 2-11 and A0 though.

@Jot I2C is not used. The sketch that is used is in the OP

Got it to work, it appears that there were some things in code which prevented A4 and A5 to set output as high. I am still not sure what it was.

@flowian Can you add "
Edit: My code was quite messy, it appears that some other functions prevented from using pins A4 or A5. It is working now.
It was the DS1307Emulator library. After initialization I had to use DS1307Emulator.busDisconnect();
Didn't know it uses I2C." as a answer and close this question?

My code was quite messy, it appears that some other functions prevented from using pins A4 or A5. It is working now.
    It was the DS1307Emulator library. After initialization I had to use DS1307Emulator.busDisconnect();
    Didn't know it uses I2C.

DS1307 is an I2C device indeed. When I saw you were using A4/A5, an I2C issue was my first thought... Why are you using this library? Do you have an RTC connected to your board?

@dda RTC is not connected to the board, the library is used for internal real-time keeping, which is then displayed on LCD. So there is no need of external RTC module.


text:
Can't flash ESP8266-01 with Sparkfun FTDI basic - wrong direction/command
Connections:
RX -> TX
TX -> RX
GND -> GND
VCC -> 3.3v
CH_PD -> 3.3v
GPIO0 -> GND (flash mode)

Click the picture to make it larger/more readable.
I am trying to flash an ESP8266-01 using a Sparkfun FTDI Basic. Above is my diagram. I am using a 16v max in to 3.3v out to handle the drop from my FTDI (5v) to the ESP8266 (3.3v). I am using a logic converter to change the 5v to 3.3v for the Rx/Tx. I have done this successfully (but with spotty results), flashing the ESP8266 with an Arduino Uno. Then I tried to reprogram the ESP8266 with my Arduino Uno and it kept giving me an error that ends with:
warning: espcomm_sync failed
error: espcomm_open failed
error: espcomm_upload_mem failed
error: espcomm_upload_mem failed

So I decided to troubleshoot by seeing if the problem was with my Uno, because it is fairly old - and I got an FTDI Basic - with the basic I get a little further - the whole output when I try to upload is:
Archiving built core (caching) in: /var/folders/lv/lj7d61jn61x_8knqdhghk_pc0000gn/T/arduino_cache_244685/core/core_esp8266_esp8266_generic_CpuFrequency_80,FlashFreq_40,FlashMode_dio,UploadSpeed_115200,FlashSize_1M64,ResetMethod_ck,Debug_Disabled,DebugLevel_None_____4d67f8743716b2ecc4b09162f2cdb6e3.a
Sketch uses 241193 bytes (25%) of program storage space. Maximum is 958448 bytes.
Global variables use 35476 bytes (43%) of dynamic memory, leaving 46444 bytes for local variables. Maximum is 81920 bytes.
/Users/eamonwhite/Library/Arduino15/packages/esp8266/tools/esptool/0.4.9/esptool -vv -cd ck -cb 115200 -cp /dev/cu.usbserial-AL034FJS -ca 0x00000 -cf /var/folders/lv/lj7d61jn61x_8knqdhghk_pc0000gn/T/arduino_build_545013/esp8266arest.ino.bin
esptool v0.4.9 - (c) 2014 Ch. Klippel <ck@atelier-klippel.de>
    setting board to ck
    setting baudrate from 115200 to 115200
    setting port from /dev/tty.usbserial to /dev/cu.usbserial-AL034FJS
    setting address from 0x00000000 to 0x00000000
    espcomm_upload_file
    espcomm_upload_mem
opening port /dev/cu.usbserial-AL034FJS at 115200
    tcgetattr
    tcsetattr
    serial open
opening bootloader
resetting board
trying to connect
    espcomm_send_command: sending command header
    espcomm_send_command: sending command payload
trying to connect
    espcomm_send_command: sending command header
    espcomm_send_command: sending command payload
    espcomm_send_command: receiving 2 bytes of data
    espcomm_send_command: receiving 2 bytes of data
An error occurred while uploading the sketch
    espcomm_send_command: receiving 2 bytes of data
    espcomm_send_command: receiving 2 bytes of data
    espcomm_send_command: receiving 2 bytes of data
    espcomm_send_command: receiving 2 bytes of data
    espcomm_send_command: receiving 2 bytes of data
    espcomm_send_command: receiving 2 bytes of data
Uploading 245344 bytes from /var/folders/lv/lj7d61jn61x_8knqdhghk_pc0000gn/T/arduino_build_545013/esp8266arest.ino.bin to flash at 0x00000000
    erasing flash
    size: 03be60 address: 000000
    first_sector_index: 0
    total_sector_count: 60
    head_sector_count: 16
    adjusted_sector_count: 44
    erase_size: 02c000
    espcomm_send_command: sending command header
    espcomm_send_command: sending command payload
    setting timeout 15000
    setting timeout 100
    espcomm_send_command: receiving 2 bytes of data
    writing flash
warning: espcomm_send_command: didn't receive command response
warning: espcomm_send_command(FLASH_DOWNLOAD_DATA) failed
warning: espcomm_send_command: wrong direction/command: 0x01 0x03, expected 0x01 0x04
closing bootloader
error: espcomm_upload_mem failed

Can anyone explain this line in detail?
warning: espcomm_send_command: wrong direction/command: 0x01 0x03, expected 0x01 0x04

Before, when flashing it with my Uno, it would work well enough. This used to happen, and then I would unplug it and plug it in (reset) and try again, until it eventually worked. However, now it happens every time. I have 4 different ESP8266 that are functional and they all respond the same way, with the error above. This leads me to believe that is something with the circuit, or with my settings, which are:
Board - Generic ESP8266
Flash mode - DIO
Flash freq. - 40hz
CPU freq. - 80hz
Flash size - 1M(64k SPIFFS)
Debug Level - none
Upload Speed - 115200

I have tried messing with the SPIFFS (what are those? packet size?) as well as changing the CPU frequency to 160 Hz, and I tried 80 Hz for the flash frequency.
I used this same system to program the ESP before with an Arduino Uno and I was successful. Why is it so finicky, and what does the response with the 0x01 0x03 instead of 0x01 0x04 trying to say?

Instead of using Arduino IDE to upload (I compiled with it), I used esptool standalone. After messing with it for a few minutes...this worked without a hitch:
esptool.py -c esp8266 --port /dev/cu.usbserial-AL034FJS -b 115200 write_flash --flash_freq 40m --flash_size 1MB 0x00000 /var/folders/lv/lj7d61jn61x_8knqdhghk_pc0000gn/T/arduino_build_545013/esp8266arest.ino.bin

I decided to try this after seeing that maybe the esptool that Arduino IDE uses is outdated - it has 0.4.9 where as the latest version is 2.1.


text:
Connecting to Alexa with FAUXMOESP library not detecting the device
I am using NodeMCU (ESP8266 12E) module from some days. I am trying to connect to Alexa for voice controlling. I have Amazon Alexa Echo 2 from which I am trying to discover my nodemcu as a smart home device.
Here is my sketch I am trying to use to detect.

#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <fauxmoESP.h>

fauxmoESP fauxmo;

const char* ssid = "myssid";
const char* password = "mypassword";

void setup() {
  Serial.begin(115200);
  wifisetup();

  fauxmo.enable(true);

  fauxmo.addDevice("light one");
  fauxmo.addDevice("light two");

// this is not able to detect .onSetState function I am not sure about the reason.

//  fauxmo.onSetState([](unsigned char device_id, const char * device_name, bool state, unsigned char value) {
//        Serial.printf("[MAIN] Device #%d (%s) state: %s value: %d\n", device_id, device_name, state ? "ON" : "OFF", value);
//    });
}

void loop() {
    fauxmo.handle();

}

void wifisetup() {
  pinMode(2, OUTPUT);
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  IPAddress ip(192, 168, 1, 243); // this 3 lines for a fix IP-address
  IPAddress gateway(192, 168, 1, 1);
  IPAddress subnet(255, 255, 255, 0);
  IPAddress dns(192, 168, 1, 1);
  WiFi.config(ip, dns, gateway, subnet);

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);

  while (WiFi.waitForConnectResult() != WL_CONNECTED) {
    Serial.println("Connection Failed! Rebooting...");
    delay(10000);
    digitalWrite(2, HIGH);
    ESP.restart();
  }
  if (WiFi.status() == WL_CONNECTED) {
    digitalWrite(2, LOW);
    Serial.println("");
    Serial.println("Your ESP is connected!");
    Serial.println("Your IP address is: ");
    Serial.println(WiFi.localIP());

    delay(100);
  }

}

I am using https://bitbucket.org/xoseperez/fauxmoesp library to do the setup. Alexa is not able to detect my device. Not sure whats the issue with this, but in the Serial Monitor I can see the logs which is showing that I am getting ping from Alexa to my ESP8266.
Taking an output pin is compulsory? I have tried that too although but no output found.
Thank you!

If you are using fauxmoESP library version 3.0 and above your device will not be detected by alexa, i dont know why this is.
You may degrade fauxmoESp version to 2.4.0 so that your issue ie. .onSetState will be resolved.
Are you able to connect wifi?

Yes it worked before itself. And yes i was able to connect through Wifi.

2.4.0 is not available anymore.. any idea which one works now?


text:
avr/io.h No such file or directory error when compiling using avr-gcc
I am trying to use the atmega328p as standalone microchip and program it. I ama using an Arduino Uno as ISP. I have written a simple program to test it however when I try to compile it using
avr-gcc -mmcu=atmega328p -o main.out main.c

I get the error:
main.c:1:20: fatal error: avr/io.h: No such file or directory
compilation terminated.

I am running OpenSUSE Leap 42.3 and i have installed avr-gcc, avr-libc.
My code:
#include <avr/io.h>

int main() {
    DDRB = 1;
    PORTB = 1;
}

Thank you in advance!

Have you installed avr-libc?

You can use the Arduino IDE to compile such programs. What is the objection to doing that?

@NickGammon there are lots of reasons to avoid the IDE. https://christopherjmcclellan.wordpress.com/2018/02/16/test-driving-arduino/

[Opinion piece] If you want a (IMHO, a million times) better dev environment than Arduino IDE then start using PlatformIO. Automatically generates project files for every possible IDE out there, downloads the compilers and frameworks you need, 'just works' without worries.

@RubberDuck - well ... the complaint about "the IDE" that SoftwareSerial disables interrupts is hardly the IDE's fault. And the IDE supports using a different editor. It's not the greatest IDE I've seen but it easily produces .hex files ready for uploading (and indeed uploads them if you want it to).

@NickGammon I’ll admit that’s more a complaint about Arduino than the Arduino IDE and yes, it’s pretty good at uploading, but you still can’t write & run tests unless you compile it yourself.

I’m guessing you started with the toolchain Arduino put on your machine.
Try explicitly including the header files on the include path with the -I switch.
avr-gcc -mmcu=atmega328p -I /path/to/avr/include -o main.out main.c

Just search for the io.h file. It should be somewhere close by to where you found the compiler.


text:
Timer0 overflow interrupt not working

I try to use the Timer0 of an Arduino Leonardo (ATmega32u) to trigger an interrupt at regular intervals, using plain avr-gcc (not the arduino library). I try to blink the built-in LED as test, but it does not light up.
If I place a PINC=0x80; in the main function, the LED turns up, but not if I do it from the interrupt.
What am I doing wrong?
EDIT : The LED turns on with TCCR0B = (1 << CS00);, (no prescaler) or TCCR0B = (1 << CS01) (prescaler /8), but it does not with TCCR0B = (1 << CS00) | (1 << CS02); (prescaler /1024, what I want). At 16MHz CPU frequency the resulting frequency should be more than 15kHz, so I should see it instantly.
Here is my code:
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdbool.h>

ISR(TIMER0_OVF_vect)
{
    PINC = 0x80;
}

int main()
{
    DDRC = 0b10000000;

    //Start Timer 0 @ 15625 Hz
    TCCR0A = 0;
    TCCR0B = (0b101 << CS00);
    TIMSK0 = (1 << TOIE0);
    sei();

    while(true); // Avoid return from main
}

what research have you done?

@jsotola I read the corresponding chapters of the processor datasheet and googled for a while, but I only found unrelated issues (e.g. using CTC mode or returning from main).

i misread .... deleting my comments .... you can delete yours

then you have to assume that the ISR is never called  .....maybe this may help  ....... http://www.instructables.com/id/Arduino-Timer-Interrupts/

Sidenote: 0b101 <<  CS00 looks like bad code. Personally; I’d use (1 <<  CS00) | (1 << CS02)

I just found the answer here : https://www.avrfreaks.net/forum/atmega32u4-arduino-leonardo-strange-timer-behavior
It seems that the USB connection generates higher-priority interrupts. I still don't know why the interrupts do work at higher frequency.
Solutions include powering the board from a USB charger or other power source rather than through the computer USB or adding the following code before the interrupt enable :
// Clear usb interrupt flags
USBINT = 0;
UDINT  = 0;
for (uint8_t i = 0; i < 6; i++)
{ // For each USB endpoint
    UENUM = i; // select the _i-th endpoint
    UEINTX = UEIENX = 0; // Clear interrupt flags for that endpoint
}

Thanks to those who helped me !

I think the interrupt handler is missing when the bootloader exits, so avr-gcc defaults to reset the board, which might result in higher frequency to switch on the led while at lower frequency the board is reset before the first interrupt.


text:
Controlling common anode RGB LED with PWM - Can individual colors be done w/o transistors?

I am using PWM (analogWrite) with a common anode LED. My previous experience is using a common cathode. My breadboard is as shown:

simulate this circuit – Schematic created using CircuitLab
This creates a semi-bright white (ugly red-green-blue mixture) like I expected. I am using only one PWM output (It is currently fading).
Now, what I ask is how can I use multiple PWM outputs to make different colors display without transistors? I was thinking that I could have 3 dedicated pins on the Arduino that switch from ground to floating extremely fast, but is there an easier way?
If not, a little explanation on how to do it with transistors (mostly just a small wiring diagram) would be great. Cheers!

As long as each LED in the array uses 20mA or less you can do it directly with the Arduino:

simulate this circuit – Schematic created using CircuitLab
Note that the blue LED will have a higher forward voltage than the red and green ones, hence the lower resistor.
Also note that the PWM will be inverted. Writing 255 to a channel will switch that LED off, while writing 0 will give it full brightness.

Why exactly does this work? Also, does the PWM pin mode need to be input? Thanks!

A PWM pin cannot be input - that makes no sense. It works because when a pin is an output (as in when you are using PWM, or just simple digitalWrite()) it is either connected to +5V or to GND. When on +5V there isn't enough voltage difference across the LED for it to light. When it's connected to GND there is 5V across the LED and the resistor, making the LED light up.

@Blake I keep meaning to make a video tutorial describing exactly how a GPIO pin on a device like an Arduino actually works. It would show you instantly how this arrangement can work. Maybe I will get round to it over the next day or so.

I get it now! I was doubting to ask if it was an input anyway, like you said, that would make no sense. I just didn't know that is was 5V or to GND, thanks!

@Majenko My brain just had a fight with the yesterday as I was trying to explain it to someone else. The best I could come up with is that the Arduino is outputting a (PWM-proportional) "voltage” and it’s "butting heads" w/ the 5V going into the LED. So with 255 it’s a complete head-butt, no voltage drop across LED since it’s the same(-ish) on both sides. As the Arduino output voltage drops the differential increases, hence more differential, hence more light.

What I don’t quite grok is the Arduino pin circuitry—is the nutshell that in-between PWM pulses the LED is connected to the Arduino’s internal ground? I mean, it must be, but I’m trying to square that with the pin being set to output, but I guess if it’s outputting 0V somehow the pin circuitry does the right thing? I can build circuits, but I don’t always have a clear picture in my head why they act like they do :/

@DaveNewton Maybe this will help: https://majenko.co.uk/blog/what-exactly-gpio-pin

@Majenko Ah you did write it :) I think it helps--AFAICT it's more or less how I was thinking of it in my head, except with actual details. Thanks!

I am using only one PWM output (It is currently fading).

use three independent pwm channels to drive three leds.

how can I use multiple PWM outputs to make different colors display without transistors?

the answer depends on the leds. for leds that require small current, it is totally doable, just connect the pwm output to them.
for leds that require lots of current, no solution.

I agree with this, but why would you say that there is no solution for high-current LEDS? Would it be different if it was a common-cathode LED? I mean, if not, I understand.

There is indeed a solution for high-current common-anode RGB LEDs: use a transistor driven by the PWM pins. For example: https://electronics.stackexchange.com/a/64623, or https://electronics.stackexchange.com/a/241384 .


text:
My ESP8266 01 is saying at espcomm_sync failed, espcomm_open failed, and (2x) espcomm_upload_mem failed. OS X
I'm extremely frustrated at my ESP8266 right now, with the Arduino. I am using a 6v DC battery power supply (4xAA batteries), and a 3.3v voltage regulator (NTE1904). I have the connections as shown:

Vcc - 3.3v rail
CH_PD - 3.3v rail
RST - 3.3v rail (I put it into GND when I need to reset)
GPIO 0 - GND (I momentarily put the reset in ground after)
TXD - Rx
RXD - Tx

I have the 6V from the 4xAA batteries into the Vin of the 3.3V voltage reulgator, it's ground to the ground of batteries (and therefore connected to Arduino), and the output connected to the 3.3v rail.
I had the circuit working before, and I had it not receiving a packet header, but when I resembled the circuit fully I am now getting these errors when uploading my code:
Sketch uses 232778 bytes (53%) of program storage space. Maximum is 434160 bytes.
Global variables use 31981 bytes (39%) of dynamic memory, leaving 49939 bytes for local variables. Maximum is 81920 bytes.
warning: espcomm_sync failed
error: espcomm_open failed
error: espcomm_upload_mem failed
error: espcomm_upload_mem failed
I've tried a bunch, and I am not sure where my problem is. Note:

I have changed my platform.txt (Arduino15/packages/.../esp8266/2.2.0/platform.txt)'s tools.esptool.upload.pattern to: tools.esptool.upload.pattern="{path}/{cmd}" {upload.verbose} -cd {upload.resetmethod} -cb {upload.speed} -cp "{serial.port}" -ca 0x00000 -cf "{build.path}/{build.project_name}.bin" (or have I? It seems quite unorganized I've changed it in the past from a tutorial saying that esptool doesn't work properly on OS X, but the page is quite hard to locate again. Please tell me what you use currently)

Again, I am on OS X (10.11.4)
Thank you for any help. It is extremely frustrating trying to get this, and I cannot seem to find any up-to-date tutorials with my problem. If you know anything I could try, that would be great.

Can you describe in better detail what hardware you're using? I am not clear on if you're using a single ESP 8266 board acting as the CPU, or some sort of other microcontroller on a board (e.g., an Arduino Uno) with a separate pre-programmed ESP 8266 board acting as a peripheral. Links to datasheets or product pages for your exact hardware are best. Also, if you can provide a schematic of some sort so we can see exactly what pins are connected to what, that will be a lot more clear than your textual description.

don't ground gpio0

Depending on you hardware you might need level shifters on the serial lines (both of them)

any luck after un-grounding? if not, please post more wiring details.


text:
Simple relay switching program crashes UNO
A very simple
digitalwrite(pin, HIGH)
delay(1200)
digitalwrite(pin, LOW)
delay(1200)

crashes the uno after about half an hour. Of course it works again after pressing the reset button.
It's switching this relay

Which is connected to a 230v 80W DC motor. The relay cuts the '+'
Because I've read that 230v stuff can be too much for such a litte relay,
I've disconnected the motor and not the relay switches another 24v OMRON P2RF-05-PU (10A250VAC) relay, which has his own 24V Mean Well power supply. And connected the motor to that one.
I thought this solved my problem, but now the Arduino crashes after about 3 hours.
Any thoughts on what else I could try?

Neither of those relays are rated for 230VDC, only 230VAC. The DC rating is usually about a tenth of the AC rating. You will destroy the relay contacts, cause massive arcs, and lots and lots of EMI while it switches. Get the right relays for the job.

Apologies, should have mentioned: the motor is rated 230VAC 80W 50hz.
The AC to DC conversion is done within the motor.

You may want to brush up on switching theory WRT arcs: https://en.wikipedia.org/wiki/Arc_suppression

Nothing to brush up, only learning new stuff for me.
From what I've read, I should try a solidstate. Going to do that tomorrow.

post the complete source. In my project I have two 30 A 230VAC relays and one 10 A 230 VAC relay and other sensors and actuators connected to Uno WiFi working all day


text:
noisy output lines when waking up from a sleep
Using code similar to these examples from AVR
https://www.microchip.com/webdoc/AVRLibcReferenceManual/group__avr__sleep.html
my program causes my Adafruit Feather 32u4 to often sleep. When the firmware has nothing to do it will sleep about 75% of the time. Typically after several hours of operation there will be corruption on the LCD display. The elapsed time to the corruption is not deterministic.
When it sleeps or wakes up from sleep I believe the processor sends garbage to the LCD module via the SPI (serial) lines. I have no oscilloscope to observe this but the problem seems to be removed if I comment out the sleep code.
A description of the Adafruit ST7565 LCD module is at this link
https://www.adafruit.com/product/250.
My Arduino setup code relevant to sleeping is this:
cli(); // atomic operation begins here
WDTCSR = bit(WDCE) | bit(WDE); // enter a very brief change mode
WDTCSR = bit(WDP2); // prescaler without reset mode, 1001 means 8 seconds, 0101 means 0.5 seconds, 0100 means 0.25 seconds, 0011 means 0.125 seconds
WDTCSR = bit(WDIE); // use interrrupt mode because we do not want an WDT triggered reset
sei(); // global interrupt enable
set_sleep_mode(SLEEP_MODE_PWR_DOWN);

My sleep code in the Arduino loop is adapted from the AVR webpage and is invoked if the firmware is not busy, is as follows:
cli(); // atomic operation begins here
sleep_enable();
sei();
sleep_cpu();
sleep_disable();

The watchdog ISR for when it wakes up is an empty function, as follows:
ISR(WDT_vect) // need this to avoid a reset
{ // no code here
}

I have a little bit of other evidence that some lines are uncontrolled when the processor wakes up. The evidence comes from my rotary encoders. I see false encoder activity sometimes when the processor wakes up and I eliminated this problem by putting some "debounce code" in the watchdog ISR. I also make sure the encoder lines use the processor's internal pull-up resistors. Note that I already have debounce code for the encoders for the purpose of doing actual debouncing of the activity of actually touching the encoders. The additional "debounce code" in the watchdog ISR is for the situation in which I am not even touching the encoders but the processor is waking up and the lines are noisy. The encoder "debounce code" is not shown in the watchdog ISR code snippet because it's not relevant to my LCD problem.
The pull-up and debounce remedy for encoder input lines is not applicable to my LCD problem because the LCD involves output lines.
Edit: I tried to solve it by setting high the active low chip select of the LCD before sleep and then reverting the line upon waking up (in the watchdog ISR). This had the effect of making the display very sluggish. I update the display once per second and it seemed to be updating only once every 2 or 3 seconds. I have not analyzed whether my "direct intervention" is incompatible with the Adafruit library for this LCD.
The LCD library: https://github.com/adafruit/ST7565-LCD
The boards are as pictured. The encoder board has 2 encoders wired up and 2 encoders unused. The encoder board sits on a 3mm thick piece of foam and is clamped to the desk. The breadboard is attached to the desk via the double sided foam tape that seems to be standard on this item.

Addendum: Given Nick Gammon's answer, I will run with the following to see if the problem is eliminated. Since the corruption is not deterministic, it may take many hours or days before I form an opinion.
  cli(); // atomic operation begins here
  WDTCSR = bit(WDCE); // enter a brief change mode
  WDTCSR = bit(WDIE) | bit(WDP2); // 1001=8s, 0101=0.5s, 0100=0.25s, 0011=0.125s
  sei(); // global interrupt enable
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);

After less than 10 hours there was corruption on the LCD. I will test with the following.
  cli(); // atomic operation begins here
  WDTCSR = bit(WDCE) | bit(WDE); // enter a brief change mode
  WDTCSR = bit(WDIE) | bit(WDP2); // 1001=8s, 0101=0.5s, 0100=0.25s, 0011=0.125s
  sei(); // global interrupt enable
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);

The above still failed after several hours.

WDTCSR = bit(WDCE) | bit(WDE); // enter a very brief change mode
WDTCSR = bit(WDP2); // prescaler without reset mode, 1001 means 8 seconds, 0101 means 0.5 seconds, 0100 means 0.25 seconds, 0011 means 0.125 seconds
WDTCSR = bit(WDIE); // use interrrupt mode because we do not want an WDT triggered reset

Your code above is not doing a WDT interrupt every 0.25 seconds as you appear to be wanting, because you assign (not OR) in the third line. That means WDP0/WDP1/WDP2?WDP3 will all be zero which means the watchdog will fire every 16 ms.

This had the effect of making the display very sluggish.

I'm not totally surprised, if you interrupt every 16 ms.

I have a little bit of other evidence that some lines are uncontrolled when the processor wakes up.

The lines should remain what they were set to when the processor sleeps. It wouldn't be very useful to sleep if the processor started outputting random junk while asleep. I can't comment further as I can only see part of your code.

Thank  you. My comment will be an addendum to the question.

You were likely correct to say that the problem was not caused by sleeping. By shortening the wires to the display I was able to run for over 50 hours without seeing display corruption and 50 hours is unprecedented.


text:
How to do I2C on Arduino with SDA and SCL pin already used
i have a Arduino screwshield from sparkfun that I purchased: https://www.sparkfun.com/products/9729 which I used to put between my arduino uno and my 2.8" TFT LCD touch shield so that I am able to use the unused pins. I have to make an I2C connection between 2 Arduino Unos which I understand will require the A4 and A5 pins however the TFT currently uses both pins. also, my tft screen is from here: https://www.sgbotic.com/index.php?dispatch=products.view&product_id=2756
The schematics of my tft are: http://www.sgbotic.com/products/datasheets/development/02756-schematic.jpg .
I am wondering if I can just use the A4 and A5 pins using the screw shield anyway since according to the schematics, the A4 pin is connected to the LCD_RST or is the pin necessary for displaying images taken from the SD card?
If that isn't the way, how should I go about doing it, does anyone know?

Please add a link to this in your question: https://www.sgbotic.com/index.php?dispatch=products.view&product_id=2756 The memory of the arduino uno will be filled before you can do something useful with it. I suggest to use the arduino mega or use a nextion screen instead. This example confirms that the reset is connected to a4: https://github.com/SGBotic/LCD-GUI-Library/blob/066d3c71cd00760af6da987e81b904bd36dbe29c/examples/display_text/display_text.ino

Even better, the chipKIT Lenny (like a Leonardo but far more powerful) with 2 I2C buses, plenty of RAM, and a professional TFT library (DisplayCore).

@Jot i see! thank you so much for pointing out that the uno memory may be filled else i would be wasting a lot of time. i've added the link to my question!

@Majenko, as in chipKIT Majenko-Lenny?

@Jot As in I designed it, yes ;) The chipKIT™ name isn't mine though - that's Microchip's property - I just license it from them.

No, you can't just use it. While I2C itself may work, the screen will keep resetting itself all the time and will be useless.
You may be able to get some luck with a software bit-banged I2C  on other pins. However I would personally choose to modify the TFT screen's PCB and cut the LCD_RST signal from the A4 pin and connect a 10kΩ resistor to +5V, or re-route it to another pin. That way you can then use I2C.

Second the Software I2C library (kudos felias-fogg, excellent work!). I have worked a lot with it and it performed really well. Had lots of trouble with the hardware Wire lib that went away with the software lib. Pick your own pins.

i see! thank you so much. as mentioned by @jot im afraid my uno will run out of memory so i will be switching over to the mega instead to save myself the trouble. thank you for your help!

If the LCD is using A4/A5 for something besides I2C, than no you cannot.

As I have very little knowledge about Prototype connection.But to avoid the soldering problems,
You May use I2C adapters as well as I2C cable joiners will be much useful and are specially designed for expansion of more than 1 I2C modules at the same time.
Hope These Sheilds and Adapters will be helpful for you.