title: Cant upload sketches

text:
# Question
Title: Cant upload sketches
I started using the arduino as a hobby and it really is quite fun. I took a break for a bit and when I came back I wasnt able to upload a sketch to my UNO. I checked to see if I was using the correct port and programmer and everything seemed fine. Not exactly sure what to do so I was hoping someone could help me. Thanks in advance.

Here is the error message I receive every time I try to upload a sketch:

```
Arduino: 1.8.13 (Windows 7), Board: "Arduino Uno"

C:\Program Files (x86)\Arduino\arduino-builder -dump-prefs -logger=machine -hardware C:\Program Files (x86)\Arduino\hardware -hardware C:\Users\User\AppData\Local\Arduino15\packages -tools C:\Program Files (x86)\Arduino\tools-builder -tools C:\Program Files (x86)\Arduino\hardware\tools\avr -tools C:\Users\User\AppData\Local\Arduino15\packages -built-in-libraries C:\Program Files (x86)\Arduino\libraries -libraries C:\Users\User\Documents\Arduino\libraries -fqbn=arduino:avr:uno -vid-pid=2341_0043 -ide-version=10813 -build-path C:\Users\User\AppData\Local\Temp\arduino_build_36096 -warnings=none -build-cache C:\Users\User\AppData\Local\Temp\arduino_cache_693101 -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.arduinoOTA.path=C:\Users\User\AppData\Local\Arduino15\packages\arduino\tools\arduinoOTA\1.3.0 -prefs=runtime.tools.arduinoOTA-1.3.0.path=C:\Users\User\AppData\Local\Arduino15\packages\arduino\tools\arduinoOTA\1.3.0 -prefs=runtime.tools.avrdude.path=C:\Users\User\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino17 -prefs=runtime.tools.avrdude-6.3.0-arduino17.path=C:\Users\User\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino17 -prefs=runtime.tools.avr-gcc.path=C:\Users\User\AppData\Local\Arduino15\packages\arduino\tools\avr-gcc\7.3.0-atmel3.6.1-arduino7 -prefs=runtime.tools.avr-gcc-7.3.0-atmel3.6.1-arduino7.path=C:\Users\User\AppData\Local\Arduino15\packages\arduino\tools\avr-gcc\7.3.0-atmel3.6.1-arduino7 -verbose C:\Users\User\Desktop\Arduino\Blink\Blink.ino

C:\Program Files (x86)\Arduino\arduino-builder -compile -logger=machine -hardware C:\Program Files (x86)\Arduino\hardware -hardware C:\Users\User\AppData\Local\Arduino15\packages -tools C:\Program Files (x86)\Arduino\tools-builder -tools C:\Program Files (x86)\Arduino\hardware\tools\avr -tools C:\Users\User\AppData\Local\Arduino15\packages -built-in-libraries C:\Program Files (x86)\Arduino\libraries -libraries C:\Users\User\Documents\Arduino\libraries -fqbn=arduino:avr:uno -vid-pid=2341_0043 -ide-version=10813 -build-path C:\Users\User\AppData\Local\Temp\arduino_build_36096 -warnings=none -build-cache C:\Users\User\AppData\Local\Temp\arduino_cache_693101 -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.arduinoOTA.path=C:\Users\User\AppData\Local\Arduino15\packages\arduino\tools\arduinoOTA\1.3.0 -prefs=runtime.tools.arduinoOTA-1.3.0.path=C:\Users\User\AppData\Local\Arduino15\packages\arduino\tools\arduinoOTA\1.3.0 -prefs=runtime.tools.avrdude.path=C:\Users\User\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino17 -prefs=runtime.tools.avrdude-6.3.0-arduino17.path=C:\Users\User\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino17 -prefs=runtime.tools.avr-gcc.path=C:\Users\User\AppData\Local\Arduino15\packages\arduino\tools\avr-gcc\7.3.0-atmel3.6.1-arduino7 -prefs=runtime.tools.avr-gcc-7.3.0-atmel3.6.1-arduino7.path=C:\Users\User\AppData\Local\Arduino15\packages\arduino\tools\avr-gcc\7.3.0-atmel3.6.1-arduino7 -verbose C:\Users\User\Desktop\Arduino\Blink\Blink.ino

Using board 'uno' from platform in folder: C:\Users\User\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.8.3

Using core 'arduino' from platform in folder: C:\Users\User\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.8.3

Detecting libraries used...

"C:\\Users\\User\\AppData\\Local\\Arduino15\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10813 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR "-IC:\\Users\\User\\AppData\\Local\\Arduino15\\packages\\arduino\\hardware\\avr\\1.8.3\\cores\\arduino" "-IC:\\Users\\User\\AppData\\Local\\Arduino15\\packages\\arduino\\hardware\\avr\\1.8.3\\variants\\standard" "C:\\Users\\User\\AppData\\Local\\Temp\\arduino_build_36096\\sketch\\Blink.ino.cpp" -o nul -DARDUINO_LIB_DISCOVERY_PHASE

Generating function prototypes...

"C:\\Users\\User\\AppData\\Local\\Arduino15\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10813 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR "-IC:\\Users\\User\\AppData\\Local\\Arduino15\\packages\\arduino\\hardware\\avr\\1.8.3\\cores\\arduino" "-IC:\\Users\\User\\AppData\\Local\\Arduino15\\packages\\arduino\\hardware\\avr\\1.8.3\\variants\\standard" "C:\\Users\\User\\AppData\\Local\\Temp\\arduino_build_36096\\sketch\\Blink.ino.cpp" -o "C:\\Users\\User\\AppData\\Local\\Temp\\arduino_build_36096\\preproc\\ctags_target_for_gcc_minus_e.cpp" -DARDUINO_LIB_DISCOVERY_PHASE

"C:\\Program Files (x86)\\Arduino\\tools-builder\\ctags\\5.8-arduino11/ctags" -u --language-force=c++ -f - --c++-kinds=svpf --fields=KSTtzns --line-directives "C:\\Users\\User\\AppData\\Local\\Temp\\arduino_build_36096\\preproc\\ctags_target_for_gcc_minus_e.cpp"

Compiling sketch...

"C:\\Users\\User\\AppData\\Local\\Arduino15\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -MMD -flto -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10813 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR "-IC:\\Users\\User\\AppData\\Local\\Arduino15\\packages\\arduino\\hardware\\avr\\1.8.3\\cores\\arduino" "-IC:\\Users\\User\\AppData\\Local\\Arduino15\\packages\\arduino\\hardware\\avr\\1.8.3\\variants\\standard" "C:\\Users\\User\\AppData\\Local\\Temp\\arduino_build_36096\\sketch\\Blink.ino.cpp" -o "C:\\Users\\User\\AppData\\Local\\Temp\\arduino_build_36096\\sketch\\Blink.ino.cpp.o"

Compiling libraries...

Compiling core...

Using previously compiled file: C:\Users\User\AppData\Local\Temp\arduino_build_36096\core\wiring_pulse.S.o

Using previously compiled file: C:\Users\User\AppData\Local\Temp\arduino_build_36096\core\WInterrupts.c.o

Using previously compiled file: C:\Users\User\AppData\Local\Temp\arduino_build_36096\core\wiring_analog.c.o

Using previously compiled file: C:\Users\User\AppData\Local\Temp\arduino_build_36096\core\wiring.c.o

Using previously compiled file: C:\Users\User\AppData\Local\Temp\arduino_build_36096\core\wiring_digital.c.o

Using previously compiled file: C:\Users\User\AppData\Local\Temp\arduino_build_36096\core\hooks.c.o

Using previously compiled file: C:\Users\User\AppData\Local\Temp\arduino_build_36096\core\wiring_pulse.c.o

Using previously compiled file: C:\Users\User\AppData\Local\Temp\arduino_build_36096\core\wiring_shift.c.o

Using previously compiled file: C:\Users\User\AppData\Local\Temp\arduino_build_36096\core\CDC.cpp.o

Using previously compiled file: C:\Users\User\AppData\Local\Temp\arduino_build_36096\core\HardwareSerial.cpp.o

Using previously compiled file: C:\Users\User\AppData\Local\Temp\arduino_build_36096\core\HardwareSerial1.cpp.o

Using previously compiled file: C:\Users\User\AppData\Local\Temp\arduino_build_36096\core\HardwareSerial2.cpp.o

Using previously compiled file: C:\Users\User\AppData\Local\Temp\arduino_build_36096\core\HardwareSerial3.cpp.o

Using previously compiled file: C:\Users\User\AppData\Local\Temp\arduino_build_36096\core\HardwareSerial0.cpp.o

Using previously compiled file: C:\Users\User\AppData\Local\Temp\arduino_build_36096\core\Print.cpp.o

Using previously compiled file: C:\Users\User\AppData\Local\Temp\arduino_build_36096\core\Stream.cpp.o

Using previously compiled file: C:\Users\User\AppData\Local\Temp\arduino_build_36096\core\Tone.cpp.o

Using previously compiled file: C:\Users\User\AppData\Local\Temp\arduino_build_36096\core\WMath.cpp.o

Using previously compiled file: C:\Users\User\AppData\Local\Temp\arduino_build_36096\core\PluggableUSB.cpp.o

Using previously compiled file: C:\Users\User\AppData\Local\Temp\arduino_build_36096\core\WString.cpp.o

Using previously compiled file: C:\Users\User\AppData\Local\Temp\arduino_build_36096\core\USBCore.cpp.o

Using previously compiled file: C:\Users\User\AppData\Local\Temp\arduino_build_36096\core\new.cpp.o

Using previously compiled file: C:\Users\User\AppData\Local\Temp\arduino_build_36096\core\abi.cpp.o

Using previously compiled file: C:\Users\User\AppData\Local\Temp\arduino_build_36096\core\IPAddress.cpp.o

Using previously compiled file: C:\Users\User\AppData\Local\Temp\arduino_build_36096\core\main.cpp.o

Using previously compiled file: C:\Users\User\AppData\Local\Temp\arduino_build_36096\core\core.a

Archiving built core (caching) in: C:\Users\User\AppData\Local\Temp\arduino_cache_693101\core\core_arduino_avr_uno_cac111a68e84b6e7f84741aaeecd4f29.a

Linking everything together...

"C:\\Users\\User\\AppData\\Local\\Arduino15\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-gcc" -w -Os -g -flto -fuse-linker-plugin -Wl,--gc-sections -mmcu=atmega328p -o "C:\\Users\\User\\AppData\\Local\\Temp\\arduino_build_36096/Blink.ino.elf" "C:\\Users\\User\\AppData\\Local\\Temp\\arduino_build_36096\\sketch\\Blink.ino.cpp.o" "C:\\Users\\User\\AppData\\Local\\Temp\\arduino_build_36096/core\\core.a" "-LC:\\Users\\User\\AppData\\Local\\Temp\\arduino_build_36096" -lm

"C:\\Users\\User\\AppData\\Local\\Arduino15\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-objcopy" -O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0 "C:\\Users\\User\\AppData\\Local\\Temp\\arduino_build_36096/Blink.ino.elf" "C:\\Users\\User\\AppData\\Local\\Temp\\arduino_build_36096/Blink.ino.eep"

"C:\\Users\\User\\AppData\\Local\\Arduino15\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-objcopy" -O ihex -R .eeprom "C:\\Users\\User\\AppData\\Local\\Temp\\arduino_build_36096/Blink.ino.elf" "C:\\Users\\User\\AppData\\Local\\Temp\\arduino_build_36096/Blink.ino.hex"

"C:\\Users\\User\\AppData\\Local\\Arduino15\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-size" -A "C:\\Users\\User\\AppData\\Local\\Temp\\arduino_build_36096/Blink.ino.elf"

Sketch uses 924 bytes (2%) of program storage space. Maximum is 32256 bytes.

Global variables use 9 bytes (0%) of dynamic memory, leaving 2039 bytes for local variables. Maximum is 2048 bytes.

avrdude: stk500_recv(): programmer is not responding

avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x33

avrdude: stk500_recv(): programmer is not responding

avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0x33

avrdude: stk500_recv(): programmer is not responding

avrdude: stk500_getsync() attempt 3 of 10: not in sync: resp=0x33

avrdude: stk500_recv(): programmer is not responding

avrdude: stk500_getsync() attempt 4 of 10: not in sync: resp=0x33

avrdude: stk500_recv(): programmer is not responding

avrdude: stk500_getsync() attempt 5 of 10: not in sync: resp=0x33

avrdude: stk500_recv(): programmer is not responding

avrdude: stk500_getsync() attempt 6 of 10: not in sync: resp=0x33

avrdude: stk500_recv(): programmer is not responding

avrdude: stk500_getsync() attempt 7 of 10: not in sync: resp=0x33

avrdude: stk500_recv(): programmer is not responding

Problem uploading to board.  See http://www.arduino.cc/en/Guide/Troubleshooting#upload for suggestions.

avrdude: stk500_getsync() attempt 8 of 10: not in sync: resp=0x33

avrdude: stk500_recv(): programmer is not responding

avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0x33

avrdude: stk500_recv(): programmer is not responding

avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0x33

```

Hope you will be able to help

# Answer
It's a generic communications error between the Arduino and your PC, there can be many reasons for this, going through the steps outlined in Juraj's link above may get you closer to the cause. Another thing worth trying is holding down the Arduino reset button until uploading starts then releasing it.
> 0 votes

---
Tags: arduino-uno
---


# Question
Title: Arduino Wifi Rev2, bug when reading PWM duty cycle value on pin 6
I am trying to read the PWM duty cycle set for pin 6 on the Arduino Wifi Rev2.

By default, the timer used is TCB0, used in 8-bit PWM mode. The 16-bit Compare channel CCMP is used as two 8-bit registers, the lowest byte CCMPL is for the period, while the highest byte CCMPH is for the duty cycle.

However, something weird happens when I try to read the Compare channel register, the value of CCMPH is unexpecteadly copied into CCMPL.

```

// PWM on pin 6, timer TCB0
//TCB_t* timer_B0 = (TCB_t *)&TCB0; // pointer on timer structure

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

void loop() {
  setPWMValueOnPin6(20);
  setPWMValueOnPin6(40);
  setPWMValueOnPin6(60);
  setPWMValueOnPin6(80);
}

void printCompareChannelValues()
{
  Serial.print("Compare channel = ");
  unsigned int r = TCB0_CCMP;
  //byte r = timer_B0->CCMP;
  Serial.println(r);

  Serial.print("Compare channel L = ");
  byte l = TCB0_CCMPL;
  //byte l = timer_B0->CCMPL;
  Serial.println(l);

  Serial.print("Compare channel H = ");
  byte h = TCB0_CCMPH;
  //byte h = timer_B0->CCMPH;
  Serial.println(h);
}

void setPWMValueOnPin6(byte value)
{
  analogWrite(6, value);
  printCompareChannelValues();
  delay(2000);
}

```

Here is the serial monitor output:

```
Compare channel = 5375
Compare channel L = 255
Compare channel H = 20
Compare channel = 10260
Compare channel L = 20
Compare channel H = 40
Compare channel = 15400
Compare channel L = 40
Compare channel H = 60
Compare channel = 20540
Compare channel L = 60
Compare channel H = 80
Compare channel = 5200
Compare channel L = 80
Compare channel H = 20
Compare channel = 10260
Compare channel L = 20
Compare channel H = 40
Compare channel = 15400
Compare channel L = 40
Compare channel H = 60
Compare channel = 20540
Compare channel L = 60
Compare channel H = 80
Compare channel = 5200
Compare channel L = 80
Compare channel H = 20

```

Problem occurs even when removing the serial functions (by watching at a led intensity on pin 6). The same behavior occurs on pin 3 (timer TCB1).

Does someone has any idea what is going on? Thanks for your help.

# Answer
## Arguable bug location

The problem appears to be here in the `analogWrite()` code:

```
    timer_B->CCMPH = val;

```

I suppose it could be argued that you're using the timer in an way unintended by the Arduino megaavr core, but I think it's *reasonable* to consider this as a bug that should be fixed in the core.

## 16-bit hardware register access and analogWrite() internals

According to the "Accessing 16-Bit Registers" of the ATMega4809 datasheet (among others no doubt):

> The AVR data bus has a width of eight bits, and so accessing 16-bit registers requires atomic operations. These registers must be byte accessed using two read or write operations. 16-bit registers are connected to the 8-bit bus and a temporary register using a 16-bit bus.
>
> **For a write operation, the low byte of the 16-bit register must be written before the high byte. The low byte is then written into the temporary register. When the high byte of the 16-bit register is written, the temporary register is copied into the low byte of the 16-bit register in the same clock cycle.**
>
> **For a read operation, the low byte of the 16-bit register must be read before the high byte. When the low byte register is read by the CPU, the high byte of the 16-bit register is copied into the temporary register in the same clock cycle as the low byte is read. The high byte will now be read from the temporary register.**
>
> This ensures that the low and high bytes of 16-bit registers are always accessed simultaneously when reading or writing the register. Interrupts can corrupt the timed sequence if an interrupt is triggered and accesses the same 16-bit register during an atomic 16-bit read/write operation. To prevent this, interrupts can be disabled when writing or reading 16-bit registers. The temporary registers can be read and written directly from user software.

So in effect, `timer_B->CCMPH = val;` is not just writing the real `CCMPH` hardware register, it is also writing the real `CCMPL` register with whatever is in this anonymous temporary register that was filled by either the last read or write operation.

## So here's what's happening in your code:

* You execute `byte l = TCB0_CCMPL;` in `printCompareChannelValues()` which both reads TCB0\_CCMPL **and loads the temporary register with the real CCMPH register's value**, which as you'll see is important.
* You execute `byte h = TCB0_CCMPH;` which is reading the temporary register rather than the real CCMPH hardware register from which the temporary register was loaded in your read from `TCB0_CCMPL` above. Note: technically this statement doesn't play a role in problem. I'm mentioning it only to drive home the behaviour of the temporary register.
* You exit `printCompareChannelValues()` and exit-and-reenter `setPWMValueOnPin6()` which calls `analogWrite()` which inside runs `timer_B->CCMPH = val;`, which **stores `val` in the real CCMPH with and stores the temporary register (containing the previous CCMPH value) into the real CCMPL**.

So yeah, on each time through the previous CCMPH becomes the new CCMPL value.

## Patching the core

Arguably what the core should contain, instead of `timer_B->CCMPH = val;`, is something like:

```
{
    const uint8_t saved_SREG = SREG;
    cli();

    uint16_t temp  = timer_B->CCMP;
    temp          &= 0xFF;
    temp          |= (uint16_t)val << 8;
    timer_B->CCMP  = temp;

    SREG = saved_SREG;
}

```

Here we're doing full 16-bit register reads. The load from CCMP reads the CCMPL first which primes the temporary register with the real CCMPH. Then the second half of the load from CCMP tries to read CCMPH, but is really reading the temporary register *correctly* containing CCMPH's value. And now there are no unpleasant surprises when this plays out in reverse.

The statement that assigns CCMP writes the CCMPL (really the temp register) then writes to the real CCMPH and simultaneously commits the temp register to the real CCMPL.

You can patch the above snipped over the `timer_B->CCMPH = val;` in your `PATH-TO-ARDUINO15-DIRECTORY/packages/arduino/hardware/megaavr/CORE-VERSION/cores/arduino/wiring_analog.c`

I have not spent a pile of time thinking about that patch, so use a bit of caution. I may well have forgotten something important.

## Priming the temporary register instead

If you don't want to mess with the core or you can't for some reason or another, a ugly hack would be to turn your simple `analogWrite(6, value);` call into something like the following:

```
{
  const uint8_t saved_SREG = SREG; cli();
  TCB0_CCMPL = TCB0_CCMPL;
  analogWrite(6, value);
  SREG = saved_SREG;
}

```

Besides turning off interrupt and then restoring them, the only thing happening here is this somewhat ridiculous looking statement:
`TCB0_CCMPL = TCB0_CCMPL;`

All this is doing is priming the temporary register for you. On the right-hand side of the assignment we read the real CCMPL register. This is also loading the temporary register with the real CCMPH, but we don't care about that. Then on the left-hand side of the assignment, we attempt to write into CCMPL, but what we're in fact doing is writing to the temporary register. And now your temporary register has the correct CCMPL value for when you run the `timer_B->CCMPH = val;` in the original `analogWrite()` code.

So, I suppose if you want to do this and you're unable/unwilling to modify your core, you could do this, potentially wrapping with an `#if #else` based on the Arduino megaavr core version, should they update the core in the future with patch given above or something equivalent.

## Core patch using the same priming technique

The same priming technique could be applied inside the patch as follows. This is maybe more confusing but slightly more efficient than the comparatively normal looking first patch.

```
{
    const uint8_t saved_SREG = SREG; cli();
    timer_B->CCMPL = timer_B->CCMPL; // Prime temporary register
    timer_B->CCMPH = val;
    SREG = saved_SREG;
}

```
> 1 votes

---
Tags: pwm, arduino-uno-wifi
---


# Question
Title: MQTT connection not being recognised in void loop()
I am trying to publish MPU 9250 readings in the Adafruit IO sending the data from ESP32. The WiFi connection is being established, but the code is not going inside the `if(mqtt.connected())` inside the `void loop()` whereas it's going inside the same command inside the `void setup()`.

I am sure there are no connection issues because once I change `if(mqtt.connected())` to `while(mqtt.connected())` inside `setup()`, code is going inside the `while` loop continuously.

Why is the code not going inside the `if` command and how can this be solved?

```
#include <WiFi.h >
#include <Adafruit_MQTT_Client.h>
#include <MPU9250.h>

#define wifi "********"
#define password "********"
#define server "io.adafruit.com"
#define port 1883
#define username "*******"
#define key "********"

WiFiClient esp;
MPU9250 IMU(Wire,0x68);
Adafruit_MQTT_Client mqtt(&esp, server, port, username, key);
Adafruit_MQTT_Publish feed = Adafruit_MQTT_Publish(&mqtt, username"feeds/accelerodata");

void setup() {
  Serial.begin(115200);
  delay(10);
  Serial.println("Adafruit MQTT Demo");
  Serial.println("Connecting to");
  Serial.println(wifi);
  WiFi.begin(wifi,password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.println("Connecting...");
  }
  Serial.println("Connected");
  Serial.println("IP Address: ");
  Serial.println(WiFi.localIP());
  Serial.println("Connecting to MQTT");

  if (mqtt.connect()) {
    Serial.println("MQTT Connected");
  }
}

void loop () {
  Serial.println("Test line to check if code reaches inside loop");
  delay(1000);

  if (mqtt.connected()) {
    int data=IMU.getAccelX_mss();
    Serial.println("\nSending accelero data");
    Serial.println(data);
    Serial.println("....");
    if (feed.publish(data)) {
      Serial.println("Success");
    } else {
      Serial.println("Fail");
    }
    delay(800);
  }
}

```

# Answer
I believe your problem is that you are attempting to use the MQTT connection before it's actually connected. So your check:

```
if(mqtt.connected())

```

is always FALSE since it's not really connected. The Adafruit library information here:

Adafruit MQTT

Says to initialize MQTT as:

```
// Function to connect and reconnect as necessary to the MQTT server.
// Should be called in the loop function and it will take care if connecting.
void MQTT_connect() {
  int8_t ret;

  // Stop if already connected.
  if (mqtt.connected()) {
    return;
  }

  Serial.print("Connecting to MQTT... ");

  while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected
       Serial.println(mqtt.connectErrorString(ret));
       Serial.println("Retrying MQTT connection in 5 seconds...");
       mqtt.disconnect();
       delay(5000);  // wait 5 seconds
  }
  Serial.println("MQTT Connected!");
}

```
> 1 votes

---
Tags: esp32, adafruit, mqtt
---


# Question
Title: nRF24l01+ Problems. Data is being recieved as 0
I am trying to transmit the values of three potentiometers via the nRF24L01+ (w/antenna). I am using the regulator designed for the nRF24L01+, so I don't think I need to add a decoupling capacitor. I am using a data structure to send the POT outputs as bytes. On the transmitter end, the values of the data structure are correct. On the receiver, however, each value of the data structure is being received as 0. I have an if statement to verify if radio.available() and apparently the radio is available. If I change the wiring of either the receiver or the transmitter, the radio is not available, so I am assuming it is wired correctly. Plus, the regulator makes it pretty simple.

I have :

* CE = D7
* CSN = D8
* (and all the other mandatory pins 11, 12, 13 connected correctly) and D10 set to output with nothing connected. (I read on another post that D10 must be set to output to make it the SPI master, or something like that)...

I have been trying for days and can't seem to figure out what I'm doing wrong. Let me know if you need anymore information.

```
//Transmitter//
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

// Define the digital inputs
#define liftPOT A2  // Joystick button 1
#define thrustPOT A0  // Joystick button 2
#define rudderPOT A1   // Toggle switch 1

RF24 radio(7, 8);   // nRF24L01 (CE, CSN)
const byte address[6] = "00001"; // Address
// Max size of this struct is 32 bytes - NRF24L01 buffer limit
struct Data_Package {
  byte thrustPOT;
  byte liftPOT;
  byte rudderPOT;
};
Data_Package data; //Create a variable with the above structure
void setup() {
  Serial.begin(9600);
  // Define the radio communication
  radio.begin();
  radio.openWritingPipe(address);
  radio.setAutoAck(false);
  radio.setDataRate(RF24_250KBPS);
  radio.setPALevel(RF24_PA_LOW);

  // Set initial default values
  data.thrustPOT = 127; // Values from 0 to 255. When Joystick is in resting position, the value is in the middle, or 127. We actually map the pot value from 0 to 1023 to 0 to 255 because that's one BYTE value
  data.rudderPOT = 127;
  data.liftPOT = 1;
}
void loop() {
  // Read all analog inputs and map them to one Byte value
  data.thrustPOT = map(analogRead(A1), 0, 1023, 0, 255); // Convert the analog read value from 0 to 1023 into a BYTE value from 0 to 255
  data.rudderPOT = map(analogRead(A0), 0, 1023, 0, 255);
  data.liftPOT = map(analogRead(A2), 0, 1023, 0, 255);
  radio.write(&data, sizeof(Data_Package));

  int liftVal, thrustVal, rudderPOS;
  liftVal = map(analogRead(A2), 0, 1023, 0, 255);
  thrustVal = map(analogRead(A0), 0, 1023, 0, 255);
  rudderPOS = map(analogRead(A1), 0, 1023, 0, 255);
  Serial.print("Lift : ");
  Serial.print(data.liftPOT);
  Serial.print(" Thrust : ");
  Serial.print(data.thrustPOT);
  Serial.print(" Rudder : ");
  Serial.println(data.rudderPOT);

```

```
//Receiver//
    #include <RF24Network.h>
#include <RF24Network_config.h>
#include <Sync.h>

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <Servo.h>

RF24 radio(7, 8);   // nRF24L01 (CE, CSN)
const byte address[6] = "00001";
unsigned long lastReceiveTime = 0;
unsigned long currentTime = 0;
Servo thrustESC;  // create servo object to control the ESC
Servo liftESC;
Servo rudder;
int thrustVal, liftVal, rudderVal;
// Max size of this struct is 32 bytes - NRF24L01 buffer limit
struct Data_Package {
  byte thrustPOT;
  byte liftPOT;
  byte rudderPOT;
};
Data_Package data; //Create a variable with the above structure
void setup() {
  Serial.begin(9600);
  radio.begin();
  radio.openReadingPipe(0, address);
  radio.setAutoAck(false);
  radio.setDataRate(RF24_250KBPS);
  radio.setPALevel(RF24_PA_LOW);
  radio.startListening(); //  Set the module as receiver
  resetData();
  thrustESC.attach(6);
  liftESC.attach(5);
  rudder.attach(3);
  pinMode(10, OUTPUT);

}
void loop() {
  // Check whether we keep receving data, or we have a connection between the two modules
  currentTime = millis();
  if ( currentTime - lastReceiveTime > 1000 ) { // If current time is more then 1 second since we have recived the last data, that means we have lost connection
    resetData(); // If connection is lost, reset the data. It prevents unwanted behavior, for example if a drone jas a throttle up, if we lose connection it can keep flying away if we dont reset the function
  }
  // Check whether there is data to be received
  if (radio.available()) {
    radio.read(&data, sizeof(Data_Package)); // Read the whole data and store it into the 'data' structure
    lastReceiveTime = millis(); // At this moment we have received the data
    Serial.print("recieving");
  }
  // Controlling servos
  rudderVal = map(data.rudderPOT, 0, 255, 0, 50);
  rudder.write(rudderVal);
  // Controlling brushless motor with ESC
  // Lift propeller
  liftVal = map(data.liftPOT, 0, 255, 1000, 2000); // Map the receiving value form 0 to 255 to 0 1000 to 2000, values used for controlling ESCs
  liftESC.writeMicroseconds(liftVal); // Send the PWM control singal to the ESC

  // Thrust propeller
  thrustVal = constrain(data.thrustPOT, 130, 255); // Joysticks stays in middle. So we only need values the upper values from 130 to 255
  thrustVal = map(thrustVal, 130, 255, 1000, 2000);
  thrustESC.writeMicroseconds(thrustVal);
  Serial.print("Lift : ");
  Serial.print(data.thrustPOT);
  Serial.print(" Thrust : ");
  Serial.print(thrustVal);
  Serial.print(" Rudder : ");
  Serial.println(rudderVal);
}
void resetData() {
  // Reset the values when there is no radio connection - Set initial default values
  data.thrustPOT = 127;
  data.liftPOT = 1;
    data.rudderPOT = 127;
    Serial.println("reset");

}

```

# Answer
In order to diagnose my proplem, I used the radio.isChipConnected() function. When the function returns 0, you have a wiring problem. If you are getting consistent high or low values, run the above function. If you return a 1, that means that the nRF24L01 is connected correctly and there is likely a software error. Simplify everything in the code to where only one simple thing is being transmitted and received. I would recommend starting small with nothing attached to the arduino other than the radio module. Once that is behaving properly, build up to your goal step by step, checking along the way. My mistake was soldering my entire set up directly to the arduino and then trying to troubleshoot.
> 1 votes

---
Tags: arduino-nano, spi, nrf24l01+
---


# Question
Title: LCD shows wrong value from MQ-135 sensor and the txt is stuck on screen
i am using a MQ-135 gas sensor and 20x4 LCD screen and it shows different values on the serial monitor it shows 756 PPM and on the LCD screen it is stuck below 320PPM the text BAD is also stuck on the screen and doesn't update on the lowering of PPM value of CO2

this is my code

```
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
#define sensor A0
int gas, co2lvl;
#define updateDisplay();

void setup()
{
pinMode(sensor,INPUT);
Serial.begin(9600);
lcd.begin(20,4);
  lcd.clear();
}

void loop()
{
co2lvl=gas-255;
co2lvl=map(co2lvl, 0,1024,400,5000);
Serial.print(co2lvl);
Serial.print("ppm");
Serial.println();
delay(200);
if(co2lvl>=699){
updateDisplay();
lcd.setCursor(0,0);
lcd.print("CO2 IN THE AIR");
lcd.setCursor(0,1);
lcd.print(analogRead(co2lvl));
lcd.setCursor(6,1);
lcd.print("EXCELLENT");
}
else if(co2lvl<=700){
updateDisplay();
lcd.setCursor(0,0);
lcd.print("CO2 PRESENT IN THE AIR");
lcd.setCursor(0,1);
lcd.print(analogRead(co2lvl));
lcd.setCursor(4,1);
lcd.print("GOOD");}
else if(co2lvl<=900){
  updateDisplay();
  lcd.setCursor(0,0);
lcd.print("CO2 PRESENT IN THE AIR");
lcd.setCursor(0,1);
lcd.print(analogRead(co2lvl));
lcd.setCursor(5,1);
lcd.print("FAIR");}
else if(co2lvl<=1100){
  updateDisplay();
  lcd.setCursor(0,0);
lcd.print("CO2 PRESENT IN THE AIR");
lcd.setCursor(0,1);
lcd.print(analogRead(co2lvl));
lcd.setCursor(5,1);
lcd.print("MEDIOCRE");
}
else(co2lvl<=1600);{
  updateDisplay();
  lcd.setCursor(0,0);
lcd.print("CO2 PRESENT IN THE AIR");
lcd.setCursor(0,1);
lcd.print(analogRead(co2lvl));
lcd.setCursor(5,1);
lcd.print("BAD");}
}

```

# Answer
> 0 votes
You made a mistake in the line:

```
else(co2lvl<=1600);

```

Because of the semicolon (;) it will not do anything for that condition. But instead the following lines will be executed always.

The following is a slight refactoring making your code more clear, removing also duplicated code:

```
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
#define sensor A0
int gas, co2lvl;

void setup()
{
  pinMode(sensor,INPUT);
  Serial.begin(9600);
  lcd.begin(20,4);
  lcd.clear();
}

void loop()
{
  co2lvl=gas-255;
  co2lvl=map(co2lvl, 0,1024,400,5000);
  Serial.print(co2lvl);
  Serial.print("ppm");
  Serial.println();
  delay(200);

  lcd.setCursor(0,0);
  lcd.print("CO2 PRESENT IN THE AIR");
  lcd.setCursor(0,1);
  lcd.print(analogRead(co2lvl));

  if      (co2lvl <=  300) { show(6, "EXCELLENT"); }
  else if (co2lvl <=  700) { show(4, "GOOD"     ); }
  else if (co2lvl <=  900) { show(5, "FAIR"     ); }
  else if (co2lvl <= 1100) { show(5, "MEDIOCRE" ); }
  else if (co2lvl <= 1600) { show(5, "BAD"      ); }
}

void show(int position, char* text)
{
  lcd.setCursor(position, 1);
  lcd.print(text);
}

```

---
Tags: arduino-uno
---


# Question
Title: Multiple peripherals using SPI with a Mega
I am using a Mega 2560 and 2 x AD9833 programmable waveform generators.

The AD9833's use a SPI protocol and I have used vwlowen's code as a jumping off point (I'm not usng the display just the generators). I added a `channel` variable to select the slave device.

It all works fine until I try to add a second AD9833. I saw this post about more than 1 peripheral using SPI & a Mega, that says I can use any pin for slave selection (SS) but the following code only ever works if I use pin 53. The upshot if which is that I can send the same data to both i.e. both share the same SS pin as long as that pin is 53. Any other SS pin selection is ignored by the devices. I tried pin 49 for both & no change, I''ve tried 53 & 49 yet only the device on 53 changes.

So what's going on here? What's so special about pin 53 that it cant be replicated by another output pin?

```
/*
Amended code for AD9833 Waveform Module originally from vwlowen.co.uk
Common SPI terminology & pinout on AD9833
MOSI - DATA
SCLK - CLK
SS   - FSYNC
MISO - not implemented i.e. ther is no MISO pin on the AS9833
*/

#include <SPI.h>

const int SINE     = 0x2000;                // Define AD9833's waveform register value.
const int SQUARE   = 0x2028;                // When we update the frequency, we need to
const int TRIANGLE = 0x2002;                // define the waveform when we end writing.

const float refFreq = 25000000.0;           // On-board crystal reference frequency

const int FSYNCA = 53;                       // Standard SPI pins for the AD9833 waveform generator.
//const int FSYNCB = 49;
const int CLK    = 52;                       // CLK and DATA pins.
const int DATA   = 51;

unsigned long freq = 1000;                   // Set initial frequency.

void setup() {

  pinMode(FSYNCA, OUTPUT);
  // pinMode(FSYNCB, OUTPUT);

  SPI.begin();
  SPI.setDataMode(SPI_MODE2);
  delay(50);

  AD9833reset();                                   // Reset AD9833 module after power-up.
  delay(50);
  AD9833setFrequency(freq, SQUARE, FSYNCA);        // Set the frequency and Sine Wave output
 // AD9833setFrequency(freq, SINE, FSYNCB);

}

void loop() {

// TODO: PC control via USB

}

// AD9833 documentation advises a 'Reset' on first applying power.
void AD9833reset() {
  WriteRegister(0x100, FSYNCA);   // Write '1' to AD9833 Control register bit D8.
  delay(10);
 // WriteRegister(0x100, FSYNCB);
 // delay(10);
}

// Set the frequency and waveform registers in the AD9833.
void AD9833setFrequency(long frequency, int Waveform, int channel) {

  long FreqWord = (frequency * pow(2, 28)) / refFreq;

  int MSB = (int)((FreqWord & 0xFFFC000) >> 14);    //Only lower 14 bits are used for data
  int LSB = (int)(FreqWord & 0x3FFF);

  //Set control bits 15 ande 14 to 0 and 1, respectively, for frequency register 0
  LSB |= 0x4000;
  MSB |= 0x4000;

  WriteRegister(0x2100, channel);
  WriteRegister(LSB, channel);                  // Write lower 16 bits to AD9833 registers
  WriteRegister(MSB, channel);                  // Write upper 16 bits to AD9833 registers.
  WriteRegister(0xC000, channel);               // Phase register
  WriteRegister(Waveform, channel);             // Exit & Reset to SINE, SQUARE or TRIANGLE

}

void WriteRegister(int dat, int channel) {

  digitalWrite(channel, LOW);         // Set FSYNC low before writing to AD9833 registers
  delayMicroseconds(10);              // Give AD9833 time to get ready to receive data.

  SPI.transfer(highByte(dat));        // Each AD9833 register is 32 bits wide and each 16
  SPI.transfer(lowByte(dat));         // bits has to be transferred as 2 x 8-bit bytes.

  digitalWrite(channel, HIGH);        //Write done. Set FSYNC high
}

```

# Answer
> 1 votes
> What's so special about pin 53

Pin 53 is the slave select pin of the SPI peripheral. As such it has a bearing on how the SPI peripheral operates.

It is intimately tied to the master/slave operation in that when it's an input SPI works in slave mode, and when it's an output it runs in master mode.

So to use SPI in master mode, whether you use pin 53 or not, it *must* be in OUTPUT for SPI to work at all.

There is nothing much wrong with your methodology, but one thing is missing: the initial state of the chip select pins.

You should always start with all chip select pins *disabled* (i.e., HIGH) rather than in an unknown (probably low - I'd have to check the datasheet) state - the exception might be pin 53 which SPI might itself set HIGH for you.

So if you add:

```
digitalWrite(FSYNCA, HIGH);
digitalWrite(FSYNCB, HIGH);

```

right after setting the `pinMode` for your pins and still use both pins 53 and 49 then it *should* work.

---
Tags: arduino-mega, spi
---


# Question
Title: What's the best way to operate a remote control circuit board?
What would be the best way of using an Arduino to operate the pictured remote control circuit board? My initial instinct would be to leave the batteries in the remote and use a separate transistor for each of the five switches, connecting wires (solder or electrical tape) to the two sides of each button and the base to an Arduino output pin. I'm certainly not an expert, so I wanted to confirm whether (a) that would work and (b) if there's a much better way. The control is normally powered by two AAA batteries.

Edit: There's also a small capacitor on the underside of the circuit board, if that changes anything.

Thanks in advance for your help

Note: I've tried to simply record and emit the IR signals from the remote using my Arduino, but have thus far been unsuccessful, so want another way of using the Arduino to control my fan: Unable to control fan with IR circuit despite capturing and reproducing the IR transmissions

# Answer
> 2 votes
All the right sides of the buttons are connected to the negative of the battery (that is ground). So you connect the remotes GND to the Arduinos GND.

Next solder five wires to the left side of the buttons. You can do this by scraping away a bit of the green solder mask that's on top of the trace going to that button pad. Or find out which pin on the IC goes to the button, and solder a wire to that leg.

I wouldn't mess with the black stuff (graphite?) on top of button pad. That way you can always return the remote to it's original function.

Then connect those wires to the Collectors of NPN transistors. The Emitters all connect to GND. The Bases (via a resistor) to the Arduino pins.

Alternatively, you can connect them directly to the Arduino pins. But you'd have to be careful to never set the pin to HIGH, as the remote won't like 5V on it's input pins while it is itself running on only 3V. You "press" the button by setting the pin to OUTPUT. After a "press" you set it back to input.

To prevent accidentally supplying 5V to the button pin, you can also use diodes (instead of transistors described above). Put the diode between the Arduino pin, and the button wire, pointing towards the Arduino. That way current can only go towards the Arduino. Then you can safely use `digitalWrite`.

---
Tags: arduino-uno, remote-control
---


# Question
Title: Remove a sudden pulse on pin d3 of nodemcu when powering it up
I am using node mcu and a 2 channel relay connected to the motor via pin d3. When I power on the circuit, it shoots a pulse to the relay and i think it will damage the motor. Please suggest me how to stop that pulse from turning on the motor.

# Answer
D3 is GPIO0, which is used as an active low input to signal the ESP8266 bootloader to expect programming after a reset.

Use a different pin.
> 0 votes

---
Tags: nodemcu, relay
---


title: Measuring solar power with an Arduino

text:
# Question
Title: Measuring solar power with an Arduino
I'm pulling together a project for my class where students build a solar panel structure/frame that moves with the sun to capture more power than if the panel were just flat on the roof.

I can handle controlling the motors, but I wanted some help to make sure I safely/accurately measured power.

I have an Arduino (the model isn't especially important), a 12 V deep cell battery, and 6 V solar cells. Obviously I don't want to hook the cells straight to an analog pin, but I came up with the schematic below. The wire to the battery will go through the CT (the inductor) to get current in order to calculate power.

Would the battery still charge even if the cells are only producing, say, 8 V? Am I overlooking anything or is there any circuit protection I need to include? Maybe a computer fan as a load on the battery and to cool everything? Any help is appreciated.

# Answer
> 1 votes
Just a few points:

* You can't measure DC current with a coil; you would need a Hall-effect sensor;
* The charging current and the voltage you measure will depend on the state-of-charge of the battery, making it difficult to compare measurements;
* You can't fully charge a nominally 12 V battery with a 12 V solar panel; a 12 V lead-acid battery with the panel you mention in the comments should work;
* You need at least a diode between solar panels and battery, and possibly a proper charger, depending on the chemistry and capacity of the battery and the maximum charging current; maximum charging current for a 12 V, 9 Ah lead-acid battery is about 1 A if you stay on the very safe side, so the panel you mention should be OK; just don't overcharge the battery;
* You need to be sure the battery voltage doesn't exceed 12 V by too much, or the voltage divider will put more than 5 V on the Arduino's input pin and fry it. Nominally 12 V lead-acid batteries are usually charged to about 14 V, and the solar panel you mention can get there. This would put 5.6 V on the Arduino input pin with the resistor values you use in your voltage divider.

Also have a look here: Measure power of solar cell with an esp8266.

# Answer
> 0 votes
> Would the battery still charge even if the cells are only producing, say, 8V

Only if the battery is below 8V.

> Am I overlooking anything

Yes. Current transformers require a load resistance and bias voltage to convert a current measurement into a voltage the ADC can measure.

# Answer
> 0 votes
Use something like a 1NA169 'high side' current sensor, like this Sparkfun module instead of a resistor or inductor. Much more accurate, and it can be placed on the 'high side' of the power circuit - very handy.

# Answer
> 0 votes
I have done something similar on my boat. This has a 12v car battery and a solar panel charger that can generate upto 20v in bright sunshine. I used a 3:1 potential divider so that the voltage supplied to the Arduino input is never more than 5v.

---
Tags: arduino-uno, solar
---


# Question
Title: Adding a common activation pin to a group of buttons
I'm working on an Uno, which has only two interrupt capable pins, but i need at least three buttons to wake it up from its power saving mode.

Is there a way to wire buttons such that, in addition to their individual pin, they will also activate a common pin (in this case, the interrupt one)?

# Answer
You can connect all the buttons to a single interrupt pin by ORing them via diodes (like Gerben wrote in the comments). That would look like this:

simulate this circuit – Schematic created using CircuitLab

The diodes isolate each input pin from the other, but allow the buttons to pull down the interrupt pin.

Though that is not the way, that I would suggest. Instead you could simply use the PinChange interrupt. That is a different type of interrupt, which can react to all pins of a port in a single ISR for the whole port. You can mask unused pins of the port away, so that the interrupt doesn't trigger for them. Nearly every pin is usable that way.

If you want to use the Arduino framework for this, you can just use the `attachInterrupt()` function, which can use the PinChange interrupt in the background.

If you want to go more down into the hardware side and configure the interrupt yourself, you should look into the corresponding sections of the datasheet. The Uno uses the Atmega328p. From 12.2.4 on you see the registers used for the PinChange interrupt (aka PCINT).

* With the bits in `PCICR` you can enable the PinChange interrupt for the ports (3 distinct interrupts for the Uno).
* The `PCMSKn` (`n` meaning number between 0 and 2) is used to mask unused pins of the port away. You should set the bits for the used pins to 1, the others to zero.

Then you need to define the actual Interrupt Service Routine (ISR) in your code:

```
ISR (PCINTn_vect) // handle pin change interrupt for D8 to D13 here
{
    ...
}

```

Here again substitute the `n` for the number of the PinChange interrupt, that you are using. Inside the ISR you need to read all the input pins of the buttons, that are connected to this PinChange interrupt, and execute your code accordingly. **Note:** As the name states, the interrupt is triggered on every change of the pin. Inside the ISR you need to sort out, what change that was. It comes down to just reading the pin, but you should keep that fact in mind.

Also make sure to never do long things inside an ISR; it has to be as short as possible; Do long things inside the main code, which can get triggered via a flag variable from the ISR)

If you google for something like "Arduino pin change interrupt" you can find detailed tutorials for this, which can go way deeper, than I can on this Q&A site.

> Will this also work while in CPU sleep mode from the avr/sleep.h library?

According to Table 9-1 in Chapter "9.1 Sleep Modes" in the datasheet, the PinChange interrupts are on the same level as the External Interrupts INTn in regard of sleep modes. So this should work just like with the INTn interrupts.
> 3 votes

---
Tags: interrupt, button, wires, breadboard
---


# Question
Title: Else Statement Never Functions As Expected
I've been working on a rather simple Arduino-breadboard project, that is supposed to imitate a traffic light intersection. There are two sets of lights, one called the North-South lights, and then the East-West lights (quite similar to the traffic lights your would see at an intersection on the road). The goal is to get the traffic lights to turn their correct colors at the correct times; however, one of my yellow lights is not turning on at all, and the breadboard LEDs I'm using completely skip over the yellow light in question and go straight to the red-green configuratin that is supposed to happen after.

Here is the code I have:

```
void setup() {

  pinMode(2, OUTPUT); //R-ns
  pinMode(3, OUTPUT); //Y-ns
  pinMode(4, OUTPUT); //G-ns
  pinMode(5, OUTPUT); //R-ew
  pinMode(6, OUTPUT); //Y-ew
  pinMode(7, OUTPUT); //G-ew

}

void loop() {

  for(int count = 0; count<16; count++) {

    if (count<7) {
      digitalWrite(2, HIGH);
      digitalWrite(3, LOW);
      digitalWrite(4, LOW);
      digitalWrite(5, LOW);
      digitalWrite(6, LOW);
      digitalWrite(7, HIGH);
      }

     else if (count==7) {
      digitalWrite(2, HIGH);
      digitalWrite(3, LOW);
      digitalWrite(4, LOW);
      digitalWrite(5, LOW);
      digitalWrite(6, HIGH);
      digitalWrite(7, LOW);
      }

     else if (7<count<15) {
      digitalWrite(2, LOW);
      digitalWrite(3, LOW);
      digitalWrite(4, HIGH);
      digitalWrite(5, HIGH);
      digitalWrite(6, LOW);
      digitalWrite(7, LOW);
      }

     else {
      digitalWrite(2, LOW);
      digitalWrite(3, HIGH);
      digitalWrite(4, LOW);
      digitalWrite(5, HIGH);
      digitalWrite(6, LOW);
      digitalWrite(7, LOW);
      }

    delay(1000);
    }

}

```

As you can see, the North-South traffic light is supposed to turn on at the 16th second, except I don't see it happen on the physical LED. I don't understand why this is happening; can anyone explain what is happening?

# Answer
`7<count<15` is interpreted as `(7<count)<15`. `7<count` will result in a false or true, which will be interpreted as 0 and 1 when later involved in the `< 15` part of the expression, which means `7<count<15` is always true.

What you're probably looking for is `7 < count && count < 15`.
> 3 votes

---
Tags: arduino-uno, breadboard
---


title: Broken USB connection

text:
# Question
Title: Broken USB connection
When I connected an external power supply to my Arduino Uno R3 (it was connected to PC via USB cable too), I heard Windows disconnected device sound and the device isn't visible since then (nothing happens when I plugin the USB). Cable is ok, because it works with the second Arduino. TX/RX LEDs don't blink anymore.

Following this guide, I checked two things:

* I was able to flash ATMEGA328 with LED blinking program using external ICSP programmer and it worked
* I was able to flash ATMEGA16U2 with the official firmware and it completed without any error

Is there anything else I can check? I'm not really desperate to fix it - I just want to know which component is broken.

# Answer
> 0 votes
Is it possible you connected the 12V to the 5 volt pin. This would probably blow the port on windows and destroy the arduino but it appears you got lucky with the arduino. Try something else not related to the Arduino stuff after powering down and restarting the windows computer. If that does not work the odds are high the Windows port is blown. If it now is working try again you may be all set.

---
Tags: usb, atmega16u2
---


title: I can't find what I did wrong

text:
# Question
Title: I can't find what I did wrong
```
int lightPin = 13;
int buttonPin = 2

void setup() {
  pinMode(lightPin, OUTPUT); //red
  pinMode(buttonPin, INPUT);
}

void loop() {
  int buttonValue = digitalRead(buttonPin);

  if (buttonValue == HIGH) {
    digitalWrite(13, HIGH);
  }  //red

  digitalWrite(13, LOW);//red
}  //red

```

# Answer
In this example your missing a semi-colin after `int buttonPin = 2`, and your if statement should probably look like this

```
if (buttonValue == HIGH){
  digitalWrite(lightpin, HIGH);
}//red

else{
  digitalWrite(lightpin, LOW);//red
}//red/*

```

Also if you go into the examples in the Arduino IDE, under "digital", this sketch is called button.
> 3 votes

---
Tags: programming
---


# Question
Title: Can I use only Ruby or Crystal Lang with an Arduino?
I am new to Arduino. I have used other SBCs before and ran some ruby script to automate many tasks.

I know Ruby and Crystal programming languages.

Can I use Ruby or Crystal solely on Arduino for creating basic robot?

# Answer
You could bridging via Firmata: https://playground.arduino.cc/Interfacing/Ruby/

Another resource is https://code.tutsplus.com/articles/using-ruby-to-program-arduino--cms-21893

You will need to Flash your Arduino with Firmata and then program in Ruby. I'm not sure if that would work with Crystal.
> 4 votes

# Answer
No. You cannot. It is not possible. And some more filler to make the answer long enough.
> 2 votes

# Answer
This is for Ruby: https://playground.arduino.cc/Interfacing/Ruby/

Here are generic info about interfacing: https://playground.arduino.cc/Main/Interfacing/
> 1 votes

---
Tags: programming
---


# Question
Title: Making HTTPS requests using ESP8266 AT commands
I am trying to make HTTPS GET/POST requests to the following server using AT commands.

```
AT+CIPSTART="TCP","54.166.71.140 ",443

```

I get errors when i use port 443 but on port 80 the requests are successful.

How can i get around this issue ? what could be potential solutions ?

# Answer
> 3 votes
HTTPS requires that you make an SSL connection not a TCP connection. To do that you need to use

```
AT+CIPSTART="SSL","54.166.71.140 ",443

```

You also need to configure SSL itself.

However the SSL support is not great and struggles with some sites (no SNI support by all accounts).

So you're better off programming the ESP8266 directly with your own sketch to make any HTTPS requests and process the data for you.

---
Tags: esp8266, arduino-ide, http, espressif
---


# Question
Title: What's wrong? FastLED and WS2812B simulation works, physical build doesn't
I'm new to Arduino coding and FastLED. When it comes to coding, I'm a complete novice, however, I've been watching YouTube tutorials to help my knowledge. I have successfully run my code on Wokwi, however, when I upload my code to my Arduino, it uploads without error, yet the WS2812B doesn't run the code correctly and appears to freeze after the first pattern.

The LED strip works just run with my Adafruit code, running a very basic set of patterns I created (different than the below code).

Any help would be greatly appreciated! The code below is what I wrote up in Wokwi and the simulation works flawlessly. The only change when uploading to my Arduino is: NUM\_LEDS 135

```
#include <FastLED.h>
#define NUM_LEDS  16
#define LED_PIN   5
#define BRIGHTNESS  255
#define caseCount 7
CRGB source1[NUM_LEDS];
CRGB source2[NUM_LEDS];
CRGB output[NUM_LEDS];

DEFINE_GRADIENT_PALETTE (christmasBlue_gp) {
  0, 0, 0, 255,
  64, 0, 0, 135,
  127, 255, 255, 255,
  191, 0, 0, 135,
  255, 0, 0, 255
};
CRGBPalette16 bluePal = christmasBlue_gp;

uint8_t blendAmount = 0;
uint8_t patternCounter = 0;
uint8_t source1Pattern = 0;
uint8_t source2Pattern = 1;
bool useSource1 = false;

void setup() {
  FastLED.addLeds<WS2812B, LED_PIN, GRB>(output, NUM_LEDS);
  FastLED.setBrightness(BRIGHTNESS);
}

void loop() {

  EVERY_N_MILLISECONDS(5) {
    blend(source1, source2, output, NUM_LEDS, blendAmount);
    if (useSource1) {
      if (blendAmount < 255) blendAmount++;
      } else {
      if (blendAmount > 0) blendAmount--;
      }
  }

  EVERY_N_SECONDS(5) {
    nextPattern();
  }
  runPattern(source1Pattern, source1);
  runPattern(source2Pattern, source2);
  FastLED.show();
}

void nextPattern() {
  patternCounter = (patternCounter + 1) % caseCount;
  if (useSource1) source1Pattern = patternCounter;
  else source2Pattern = patternCounter;
  useSource1 = !useSource1;
  }

void runPattern(uint8_t pattern, CRGB *LEDArray) {
  switch (pattern) {
    case 0:
      movingDots(LEDArray);
      break;
    case 1:
      whiteFill(LEDArray);
      break;
    case 2:
      greenFill(LEDArray);
      break;
    case 3:
      whiteFill(LEDArray);
      break;
    case 4:
      redFill(LEDArray);
      break;
    case 5:
      greenBlueTwinkle(LEDArray);
      break;
    case 6:
      greenRedSplit(LEDArray);
      break;
  }
}

void movingDots(CRGB *LEDarray) {
  uint16_t posBeat = beatsin16(30, 0, NUM_LEDS -1, 0, 0);
  uint16_t posBeat2 = beatsin16(60, 0, NUM_LEDS -1, 0, 0);
  uint16_t posBeat3 = beatsin16(25, 0, NUM_LEDS -1, 0, 127);
  uint16_t posBeat4 = beatsin16(45, 0, NUM_LEDS -1, 0, 127);
  LEDarray[(posBeat + posBeat2) / 2] = CHSV(0, 255, 255);
  LEDarray[(posBeat3 + posBeat4) / 2] = CHSV(120, 255, 255);
  LEDarray[(posBeat3 + posBeat2) / 2] = CHSV(120, 255, 255);
  LEDarray[(posBeat2 + posBeat4) / 2] = CHSV(0, 255, 255);
  LEDarray[(posBeat2 + posBeat4 + posBeat) / 3] = CHSV(0, 0, 255);
  fadeToBlackBy(LEDarray, NUM_LEDS, 1);
}

void whiteFill(CRGB *LEDarray) {
  fill_solid(LEDarray, NUM_LEDS, CRGB::White);
}

void greenFill(CRGB *LEDarray) {
  fill_solid(LEDarray, NUM_LEDS, CRGB::Green);
}

void redFill(CRGB *LEDarray) {
  fill_solid(LEDarray, NUM_LEDS, CRGB::Red);
}

void greenBlueTwinkle(CRGB *LEDarray) {
  EVERY_N_MILLISECONDS(50){
    LEDarray[random8(0, NUM_LEDS-1)] = ColorFromPalette(bluePal, random8(), 255, LINEARBLEND);
    }
  fadeToBlackBy(LEDarray, NUM_LEDS, 1);
  FastLED.show();
}

void greenRedSplit(CRGB *LEDarray) {
  for(int i = 0; i < NUM_LEDS; i++) {
    LEDarray[i] = CHSV(0, 255, 255);
    LEDarray[(NUM_LEDS-1-i)] = CHSV(120, 255, 255);
    FastLED.show();
    delay(100);
    LEDarray[i] = CHSV(0, 255, 255);
  }

  for(int i = NUM_LEDS - 1; i >= 0; i--) {
    LEDarray[i] = CHSV(120, 255, 255);
    LEDarray[(NUM_LEDS-1-i)] = CHSV(0, 255, 255);
    FastLED.show();
    delay(100);
    LEDarray[i] = CHSV(120, 255, 255);
  }
}

```

# Answer
Consider what would happen if your power supply is not powerful enough. Depending on the number of WS2812B you are lighting at the same time you may be exceeding the current rating of your power source. Using the following quote from this source:

> ... consider how much current your LED strip is going to pull. With every single LED on at full brightness, each breakout board can pull about 60mA (20mA per color channel).

We can calculate for a string of 15 WS2812 set to full brightness it would take 15 x 60mA or almost 1 Amp of power. People commonly source power supply which can handle twice the expected high current load. So, in this case you would need a supply which can source at least 2 Amps

Also consider not using the Arduino's linear voltage regulator for large current loads. Not only does it have current limitations but it is also not as effective as a switching power supply. Instead use a power supply of the correct voltage and capable current rating for large current loads.

Try lighting only 1 LED at a time in the strip and stick to one color at a time. If this works it is likely your power supply is not capable of supplying the necessary current to operate your project as expected.
> 3 votes

---
Tags: arduino-uno
---


# Question
Title: 240*320 transparent OLED display with Arduino
A long time ago I ordered this transparent OLED display (from a chinese supplier on alibaba) planning on interfacing it with an Arduino but didn't really have the skills to get the project going.

I have the datasheet (linked below) for the driver and it seems to come with a schematic on it which takes the output from the OLED and gives me 8-bit wiring. My plan is to use the adafruit GFX library with it and probably steal the code from this adafruit TFT.

Please, someone tell me if this has no hope of working but my plan as it stands is:

1) draw up the datasheets schematic into Kicad, and get it printed onto a PCB (I am worried that if I breadboard/protoboard it, ill have all kinds of issues coming from my poor perfboarding skills and I want to be able to narrow down my problems. I know it's bad practise to print a PCB before doing any breadboarding but I don't think ill successfully manage it)

2) wire up the output pins from the new PCB in the same way that the adafruit board and try and use the same code.

3) Here are where the problems come I think as I am proficient at simple code (I'm probably being ignorant to the fact that 'simple' code is still way above my level) e.g functions/loops etc... but writing code like adafruits example for displays is way above my level. I hope that I can just edit some of Adafruits existing example code and it will just work.

A few years ago I asked a similar question on the Arduino forum but then I was much worse at programming and had less of an idea where to start.

If any of you can provide insight into if this will work or any better ideas then I am all ears.

Thanks

Documents containing datasheets and example code - https://drive.google.com/drive/folders/1ZTmipJKRKWNMudYVQ5ATxixbQtKD4hQm?usp=sharing

---

edit: there is also a file called example\_code.txt which contains a lot of (I dont know what I'm talking about really) hex commands.

edit 2: - ILI9341 Mock Example

```
/***************************************************
  This is our GFX example for the Adafruit ILI9341 Breakout and Shield
  ----> http://www.adafruit.com/products/1651

  Check out the links above for our tutorials and wiring diagrams
  These displays use SPI to communicate, 4 or 5 pins are required to
  interface (RST is optional)
  Adafruit invests time and resources providing this open source code,
  please support Adafruit and open-source hardware by purchasing
  products from Adafruit!

  Written by Limor Fried/Ladyada for Adafruit Industries.
  MIT license, all text above must be included in any redistribution
 ****************************************************/

#include "SPI.h"
#include "Adafruit_GFX.h"
#include "Adafruit_ILI9341.h"

// For the Adafruit shield, these are the default.
#define TFT_DC 9
#define TFT_CS 10

// Use hardware SPI (on Uno, #13, #12, #11) and the above for CS/DC
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);
// If using the breakout, change pins as desired
//Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_MOSI, TFT_CLK, TFT_RST, TFT_MISO);

void setup() {
  Serial.begin(9600);
  Serial.println("ILI9341 Test!");

  tft.begin();

  // read diagnostics (optional but can help debug problems)
  uint8_t x = tft.readcommand8(ILI9341_RDMODE);
  Serial.print("Display Power Mode: 0x"); Serial.println(x, HEX);
  x = tft.readcommand8(ILI9341_RDMADCTL);
  Serial.print("MADCTL Mode: 0x"); Serial.println(x, HEX);
  x = tft.readcommand8(ILI9341_RDPIXFMT);
  Serial.print("Pixel Format: 0x"); Serial.println(x, HEX);
  x = tft.readcommand8(ILI9341_RDIMGFMT);
  Serial.print("Image Format: 0x"); Serial.println(x, HEX);
  x = tft.readcommand8(ILI9341_RDSELFDIAG);
  Serial.print("Self Diagnostic: 0x"); Serial.println(x, HEX);

  Serial.println(F("Benchmark                Time (microseconds)"));
  delay(10);
  Serial.print(F("Screen fill              "));
  Serial.println(testFillScreen());
  delay(500);

  Serial.print(F("Text                     "));
  Serial.println(testText());
  delay(3000);

  Serial.print(F("Lines                    "));
  Serial.println(testLines(ILI9341_CYAN));
  delay(500);

  Serial.print(F("Horiz/Vert Lines         "));
  Serial.println(testFastLines(ILI9341_RED, ILI9341_BLUE));
  delay(500);

  Serial.print(F("Rectangles (outline)     "));
  Serial.println(testRects(ILI9341_GREEN));
  delay(500);

  Serial.print(F("Rectangles (filled)      "));
  Serial.println(testFilledRects(ILI9341_YELLOW, ILI9341_MAGENTA));
  delay(500);

  Serial.print(F("Circles (filled)         "));
  Serial.println(testFilledCircles(10, ILI9341_MAGENTA));

  Serial.print(F("Circles (outline)        "));
  Serial.println(testCircles(10, ILI9341_WHITE));
  delay(500);

  Serial.print(F("Triangles (outline)      "));
  Serial.println(testTriangles());
  delay(500);

  Serial.print(F("Triangles (filled)       "));
  Serial.println(testFilledTriangles());
  delay(500);

  Serial.print(F("Rounded rects (outline)  "));
  Serial.println(testRoundRects());
  delay(500);

  Serial.print(F("Rounded rects (filled)   "));
  Serial.println(testFilledRoundRects());
  delay(500);

  Serial.println(F("Done!"));

}

void loop(void) {
  for(uint8_t rotation=0; rotation<4; rotation++) {
    tft.setRotation(rotation);
    testText();
    delay(1000);
  }
}

unsigned long testFillScreen() {
  unsigned long start = micros();
  tft.fillScreen(ILI9341_BLACK);
  yield();
  tft.fillScreen(ILI9341_RED);
  yield();
  tft.fillScreen(ILI9341_GREEN);
  yield();
  tft.fillScreen(ILI9341_BLUE);
  yield();
  tft.fillScreen(ILI9341_BLACK);
  yield();
  return micros() - start;
}

unsigned long testText() {
  tft.fillScreen(ILI9341_BLACK);
  unsigned long start = micros();
  tft.setCursor(0, 0);
  tft.setTextColor(ILI9341_WHITE);  tft.setTextSize(1);
  tft.println("Hello World!");
  tft.setTextColor(ILI9341_YELLOW); tft.setTextSize(2);
  tft.println(1234.56);
  tft.setTextColor(ILI9341_RED);    tft.setTextSize(3);
  tft.println(0xDEADBEEF, HEX);
  tft.println();
  tft.setTextColor(ILI9341_GREEN);
  tft.setTextSize(5);
  tft.println("Groop");
  tft.setTextSize(2);
  tft.println("I implore thee,");
  tft.setTextSize(1);
  tft.println("my foonting turlingdromes.");
  tft.println("And hooptiously drangle me");
  tft.println("with crinkly bindlewurdles,");
  tft.println("Or I will rend thee");
  tft.println("in the gobberwarts");
  tft.println("with my blurglecruncheon,");
  tft.println("see if I don't!");
  return micros() - start;
}

unsigned long testLines(uint16_t color) {
  unsigned long start, t;
  int           x1, y1, x2, y2,
                w = tft.width(),
                h = tft.height();

  tft.fillScreen(ILI9341_BLACK);
  yield();

  x1 = y1 = 0;
  y2    = h - 1;
  start = micros();
  for(x2=0; x2<w; x2+=6) tft.drawLine(x1, y1, x2, y2, color);
  x2    = w - 1;
  for(y2=0; y2<h; y2+=6) tft.drawLine(x1, y1, x2, y2, color);
  t     = micros() - start; // fillScreen doesn't count against timing

  yield();
  tft.fillScreen(ILI9341_BLACK);
  yield();

  x1    = w - 1;
  y1    = 0;
  y2    = h - 1;
  start = micros();
  for(x2=0; x2<w; x2+=6) tft.drawLine(x1, y1, x2, y2, color);
  x2    = 0;
  for(y2=0; y2<h; y2+=6) tft.drawLine(x1, y1, x2, y2, color);
  t    += micros() - start;

  yield();
  tft.fillScreen(ILI9341_BLACK);
  yield();

  x1    = 0;
  y1    = h - 1;
  y2    = 0;
  start = micros();
  for(x2=0; x2<w; x2+=6) tft.drawLine(x1, y1, x2, y2, color);
  x2    = w - 1;
  for(y2=0; y2<h; y2+=6) tft.drawLine(x1, y1, x2, y2, color);
  t    += micros() - start;

  yield();
  tft.fillScreen(ILI9341_BLACK);
  yield();

  x1    = w - 1;
  y1    = h - 1;
  y2    = 0;
  start = micros();
  for(x2=0; x2<w; x2+=6) tft.drawLine(x1, y1, x2, y2, color);
  x2    = 0;
  for(y2=0; y2<h; y2+=6) tft.drawLine(x1, y1, x2, y2, color);

  yield();
  return micros() - start;
}

unsigned long testFastLines(uint16_t color1, uint16_t color2) {
  unsigned long start;
  int           x, y, w = tft.width(), h = tft.height();

  tft.fillScreen(ILI9341_BLACK);
  start = micros();
  for(y=0; y<h; y+=5) tft.drawFastHLine(0, y, w, color1);
  for(x=0; x<w; x+=5) tft.drawFastVLine(x, 0, h, color2);

  return micros() - start;
}

unsigned long testRects(uint16_t color) {
  unsigned long start;
  int           n, i, i2,
                cx = tft.width()  / 2,
                cy = tft.height() / 2;

  tft.fillScreen(ILI9341_BLACK);
  n     = min(tft.width(), tft.height());
  start = micros();
  for(i=2; i<n; i+=6) {
    i2 = i / 2;
    tft.drawRect(cx-i2, cy-i2, i, i, color);
  }

  return micros() - start;
}

unsigned long testFilledRects(uint16_t color1, uint16_t color2) {
  unsigned long start, t = 0;
  int           n, i, i2,
                cx = tft.width()  / 2 - 1,
                cy = tft.height() / 2 - 1;

  tft.fillScreen(ILI9341_BLACK);
  n = min(tft.width(), tft.height());
  for(i=n; i>0; i-=6) {
    i2    = i / 2;
    start = micros();
    tft.fillRect(cx-i2, cy-i2, i, i, color1);
    t    += micros() - start;
    // Outlines are not included in timing results
    tft.drawRect(cx-i2, cy-i2, i, i, color2);
    yield();
  }

  return t;
}

unsigned long testFilledCircles(uint8_t radius, uint16_t color) {
  unsigned long start;
  int x, y, w = tft.width(), h = tft.height(), r2 = radius * 2;

  tft.fillScreen(ILI9341_BLACK);
  start = micros();
  for(x=radius; x<w; x+=r2) {
    for(y=radius; y<h; y+=r2) {
      tft.fillCircle(x, y, radius, color);
    }
  }

  return micros() - start;
}

unsigned long testCircles(uint8_t radius, uint16_t color) {
  unsigned long start;
  int           x, y, r2 = radius * 2,
                w = tft.width()  + radius,
                h = tft.height() + radius;

  // Screen is not cleared for this one -- this is
  // intentional and does not affect the reported time.
  start = micros();
  for(x=0; x<w; x+=r2) {
    for(y=0; y<h; y+=r2) {
      tft.drawCircle(x, y, radius, color);
    }
  }

  return micros() - start;
}

unsigned long testTriangles() {
  unsigned long start;
  int           n, i, cx = tft.width()  / 2 - 1,
                      cy = tft.height() / 2 - 1;

  tft.fillScreen(ILI9341_BLACK);
  n     = min(cx, cy);
  start = micros();
  for(i=0; i<n; i+=5) {
    tft.drawTriangle(
      cx    , cy - i, // peak
      cx - i, cy + i, // bottom left
      cx + i, cy + i, // bottom right
      tft.color565(i, i, i));
  }

  return micros() - start;
}

unsigned long testFilledTriangles() {
  unsigned long start, t = 0;
  int           i, cx = tft.width()  / 2 - 1,
                   cy = tft.height() / 2 - 1;

  tft.fillScreen(ILI9341_BLACK);
  start = micros();
  for(i=min(cx,cy); i>10; i-=5) {
    start = micros();
    tft.fillTriangle(cx, cy - i, cx - i, cy + i, cx + i, cy + i,
      tft.color565(0, i*10, i*10));
    t += micros() - start;
    tft.drawTriangle(cx, cy - i, cx - i, cy + i, cx + i, cy + i,
      tft.color565(i*10, i*10, 0));
    yield();
  }

  return t;
}

unsigned long testRoundRects() {
  unsigned long start;
  int           w, i, i2,
                cx = tft.width()  / 2 - 1,
                cy = tft.height() / 2 - 1;

  tft.fillScreen(ILI9341_BLACK);
  w     = min(tft.width(), tft.height());
  start = micros();
  for(i=0; i<w; i+=6) {
    i2 = i / 2;
    tft.drawRoundRect(cx-i2, cy-i2, i, i, i/8, tft.color565(i, 0, 0));
  }

  return micros() - start;
}

unsigned long testFilledRoundRects() {
  unsigned long start;
  int           i, i2,
                cx = tft.width()  / 2 - 1,
                cy = tft.height() / 2 - 1;

  tft.fillScreen(ILI9341_BLACK);
  start = micros();
  for(i=min(tft.width(), tft.height()); i>20; i-=6) {
    i2 = i / 2;
    tft.fillRoundRect(cx-i2, cy-i2, i, i, i/8, tft.color565(0, i, 0));
    yield();
  }

  return micros() - start;
}

```

edit 3: - ili9341 header file

```
/*!
 * @file Adafruit_ILI9341.h
 *
 * This is the documentation for Adafruit's ILI9341 driver for the
 * Arduino platform.
 *
 * This library works with the Adafruit 2.8" Touch Shield V2 (SPI)
 *    http://www.adafruit.com/products/1651
 * Adafruit 2.4" TFT LCD with Touchscreen Breakout w/MicroSD Socket - ILI9341
 *    https://www.adafruit.com/product/2478
 * 2.8" TFT LCD with Touchscreen Breakout Board w/MicroSD Socket - ILI9341
 *    https://www.adafruit.com/product/1770
 * 2.2" 18-bit color TFT LCD display with microSD card breakout - ILI9340
 *    https://www.adafruit.com/product/1770
 * TFT FeatherWing - 2.4" 320x240 Touchscreen For All Feathers
 *    https://www.adafruit.com/product/3315
 *
 * These displays use SPI to communicate, 4 or 5 pins are required
 * to interface (RST is optional).
 *
 * Adafruit invests time and resources providing this open source code,
 * please support Adafruit and open-source hardware by purchasing
 * products from Adafruit!
 *
 *
 * This library depends on <a href="https://github.com/adafruit/Adafruit_GFX">
 * Adafruit_GFX</a> being present on your system. Please make sure you have
 * installed the latest version before using this library.
 *
 * Written by Limor "ladyada" Fried for Adafruit Industries.
 *
 * BSD license, all text here must be included in any redistribution.
 *
 */

#ifndef _ADAFRUIT_ILI9341H_
#define _ADAFRUIT_ILI9341H_

#include "Adafruit_GFX.h"
#include "Arduino.h"
#include "Print.h"
#include <Adafruit_SPITFT.h>
#include <Adafruit_SPITFT_Macros.h>
#include <SPI.h>

#define ILI9341_TFTWIDTH 240  ///< ILI9341 max TFT width
#define ILI9341_TFTHEIGHT 320 ///< ILI9341 max TFT height

#define ILI9341_NOP 0x00     ///< No-op register
#define ILI9341_SWRESET 0x01 ///< Software reset register
#define ILI9341_RDDID 0x04   ///< Read display identification information
#define ILI9341_RDDST 0x09   ///< Read Display Status

#define ILI9341_SLPIN 0x10  ///< Enter Sleep Mode
#define ILI9341_SLPOUT 0x11 ///< Sleep Out
#define ILI9341_PTLON 0x12  ///< Partial Mode ON
#define ILI9341_NORON 0x13  ///< Normal Display Mode ON

#define ILI9341_RDMODE 0x0A     ///< Read Display Power Mode
#define ILI9341_RDMADCTL 0x0B   ///< Read Display MADCTL
#define ILI9341_RDPIXFMT 0x0C   ///< Read Display Pixel Format
#define ILI9341_RDIMGFMT 0x0D   ///< Read Display Image Format
#define ILI9341_RDSELFDIAG 0x0F ///< Read Display Self-Diagnostic Result

#define ILI9341_INVOFF 0x20   ///< Display Inversion OFF
#define ILI9341_INVON 0x21    ///< Display Inversion ON
#define ILI9341_GAMMASET 0x26 ///< Gamma Set
#define ILI9341_DISPOFF 0x28  ///< Display OFF
#define ILI9341_DISPON 0x29   ///< Display ON

#define ILI9341_CASET 0x2A ///< Column Address Set
#define ILI9341_PASET 0x2B ///< Page Address Set
#define ILI9341_RAMWR 0x2C ///< Memory Write
#define ILI9341_RAMRD 0x2E ///< Memory Read

#define ILI9341_PTLAR 0x30    ///< Partial Area
#define ILI9341_VSCRDEF 0x33  ///< Vertical Scrolling Definition
#define ILI9341_MADCTL 0x36   ///< Memory Access Control
#define ILI9341_VSCRSADD 0x37 ///< Vertical Scrolling Start Address
#define ILI9341_PIXFMT 0x3A   ///< COLMOD: Pixel Format Set

#define ILI9341_FRMCTR1                                                        \
  0xB1 ///< Frame Rate Control (In Normal Mode/Full Colors)
#define ILI9341_FRMCTR2 0xB2 ///< Frame Rate Control (In Idle Mode/8 colors)
#define ILI9341_FRMCTR3                                                        \
  0xB3 ///< Frame Rate control (In Partial Mode/Full Colors)
#define ILI9341_INVCTR 0xB4  ///< Display Inversion Control
#define ILI9341_DFUNCTR 0xB6 ///< Display Function Control

#define ILI9341_PWCTR1 0xC0 ///< Power Control 1
#define ILI9341_PWCTR2 0xC1 ///< Power Control 2
#define ILI9341_PWCTR3 0xC2 ///< Power Control 3
#define ILI9341_PWCTR4 0xC3 ///< Power Control 4
#define ILI9341_PWCTR5 0xC4 ///< Power Control 5
#define ILI9341_VMCTR1 0xC5 ///< VCOM Control 1
#define ILI9341_VMCTR2 0xC7 ///< VCOM Control 2

#define ILI9341_RDID1 0xDA ///< Read ID 1
#define ILI9341_RDID2 0xDB ///< Read ID 2
#define ILI9341_RDID3 0xDC ///< Read ID 3
#define ILI9341_RDID4 0xDD ///< Read ID 4

#define ILI9341_GMCTRP1 0xE0 ///< Positive Gamma Correction
#define ILI9341_GMCTRN1 0xE1 ///< Negative Gamma Correction
//#define ILI9341_PWCTR6     0xFC

// Color definitions
#define ILI9341_BLACK 0x0000       ///<   0,   0,   0
#define ILI9341_NAVY 0x000F        ///<   0,   0, 123
#define ILI9341_DARKGREEN 0x03E0   ///<   0, 125,   0
#define ILI9341_DARKCYAN 0x03EF    ///<   0, 125, 123
#define ILI9341_MAROON 0x7800      ///< 123,   0,   0
#define ILI9341_PURPLE 0x780F      ///< 123,   0, 123
#define ILI9341_OLIVE 0x7BE0       ///< 123, 125,   0
#define ILI9341_LIGHTGREY 0xC618   ///< 198, 195, 198
#define ILI9341_DARKGREY 0x7BEF    ///< 123, 125, 123
#define ILI9341_BLUE 0x001F        ///<   0,   0, 255
#define ILI9341_GREEN 0x07E0       ///<   0, 255,   0
#define ILI9341_CYAN 0x07FF        ///<   0, 255, 255
#define ILI9341_RED 0xF800         ///< 255,   0,   0
#define ILI9341_MAGENTA 0xF81F     ///< 255,   0, 255
#define ILI9341_YELLOW 0xFFE0      ///< 255, 255,   0
#define ILI9341_WHITE 0xFFFF       ///< 255, 255, 255
#define ILI9341_ORANGE 0xFD20      ///< 255, 165,   0
#define ILI9341_GREENYELLOW 0xAFE5 ///< 173, 255,  41
#define ILI9341_PINK 0xFC18        ///< 255, 130, 198

/**************************************************************************/
/*!
@brief Class to manage hardware interface with ILI9341 chipset (also seems to
work with ILI9340)
*/
/**************************************************************************/

class Adafruit_ILI9341 : public Adafruit_SPITFT {
public:
  Adafruit_ILI9341(int8_t _CS, int8_t _DC, int8_t _MOSI, int8_t _SCLK,
                   int8_t _RST = -1, int8_t _MISO = -1);
  Adafruit_ILI9341(int8_t _CS, int8_t _DC, int8_t _RST = -1);
#if !defined(ESP8266)
  Adafruit_ILI9341(SPIClass *spiClass, int8_t dc, int8_t cs = -1,
                   int8_t rst = -1);
#endif // end !ESP8266
  Adafruit_ILI9341(tftBusWidth busWidth, int8_t d0, int8_t wr, int8_t dc,
                   int8_t cs = -1, int8_t rst = -1, int8_t rd = -1);

  void begin(uint32_t freq = 0);
  void setRotation(uint8_t r);
  void invertDisplay(bool i);
  void scrollTo(uint16_t y);
  void setScrollMargins(uint16_t top, uint16_t bottom);

  // Transaction API not used by GFX
  void setAddrWindow(uint16_t x, uint16_t y, uint16_t w, uint16_t h);

  uint8_t readcommand8(uint8_t reg, uint8_t index = 0);
};

#endif // _ADAFRUIT_ILI9341H_

```

# Answer
> 1 votes
The critical part, assuming your hardware works, is getting the software going. Not all OLEDs are the same, and different ones need different commands to get them working.

You can't just take a random OLED and use a random library - it needs a driver to make it work.

In this case it's the DA8620 that is the main chip that you want to worry about, and your chosen library has to implement the commands and methodologies for that specific chip.

Now, you have a file that contains those commands (all the "hex commands"), and if you can't find an existing library to work with the DA8620 then you will have to write or adapt one while referring to those commands. You can find out more about what the commands all mean by referencing the datasheet, which lists all the commands and their parameters (from page 78 onwards), so you should be able to relate those to what an existing library needs and map things accordingly while keeping the right power-up sequences.

# Answer
> 2 votes
Is the SPI communication method feasible? I have found a chip at present, and it seems that the driver can be transplanted directly. You can look at this chip. https://nl.mouser.com/ProductDetail/Newhaven-Display/NHD-169-BREAKOUT?qs=wnTfsH77Xs6v7mYjAGElxw%3D%3D

# Answer
> 1 votes
Your `initial code.txt` file is flawed.

The pdf file has the code in multiple columns on each page, and not all the columns are filled.

This is the code (i think it is correct)

18. Example of Initial Code

```
Command(0x11);
Data(0x00);

Delay_ms(255);   // Delay 255ms or more

Command(0xC5);
Data(0x01);

Command(0xC4);
Data(0x2F);

Command(0xC0);
Data(0x10);
Data(0x00);

Command(0x26);
Data(0x00);

Command(0x2A);
Data(0x00);
Data(0x00);
Data(0x00);
Data(0xEF);

Command(0x2B);
Data(0x00);
Data(0x00);
Data(0x01);
Data(0x3F);

Command(0x36);
Data(0x08);

Command(0xC0);
Data(0x50);
Data(0x00);

Command(0x3A);
Data(0x65);    //Pixel Format 16bit data
//Data(0x67);  //Pixel Format 24bit data

Command(0xBB);
Data(0x4D);
Data(0x97);
Data(0x1C);

Command(0xC1);
Data(0x01);

Command(0xC6);
Data(0x6B);
Data(0x02);
Data(0x00);
Data(0x06);
Data(0x06);
Data(0x06);

Command(0xC9);
Data(0xF0);

Command(0xE0);
Data(0xC0);
Data(0x00);

Command(0xE2);
Data(0x00);

Command(0xE8);
Data(0x23);
Data(0x00);
Data(0x00);

Command(0xEB);
Data(0xC0);

Command(0xD9);
Data(0x40);
Data(0x00);

Command(0xD1);
Data(0x00);
Data(0x00);
Data(0x00);
Data(0x00);
Data(0x00);
Data(0x00);
Data(0x00);
Data(0x00);
Data(0x00);
Data(0x00);
Data(0x00);
Data(0x00);
Data(0x00);
Data(0x00);
Data(0x00);
Data(0x00);
Data(0x00);
Data(0x00);
Data(0x00);
Data(0x00);
Data(0x00);
Data(0x00);
Data(0x00);
Data(0x00);
Data(0x00);
Data(0x00);
Data(0x00);
Data(0x00);
Data(0x00);
Data(0x00);
Data(0x00);
Data(0x00);
Data(0x00);
Data(0x00);
Data(0x00);
Data(0x00);
Data(0x00);
Data(0x00);
Data(0x00);
Data(0x00);
Data(0x00);
Data(0x00);
Data(0x00);
Data(0x00);
Data(0x00);
Data(0x00);
Data(0x00);
Data(0x00);

Command(0xDF);
Data(0x35);
Data(0xAD);
Data(0x1C);
Data(0xE7);
Data(0x18);
Data(0xC6);
Data(0x14);
Data(0xA5);
Data(0x18);
Data(0xC6);
Data(0x14);
Data(0xA5);
Data(0x18);
Data(0xC6);
Data(0x14);
Data(0xA5);
Data(0x18);
Data(0xC6);
Data(0x14);
Data(0xA5);
Data(0x18);
Data(0xC6);
Data(0x14);
Data(0xA5);
Data(0x14);
Data(0xA5);
Data(0x18);
Data(0xC6);
Data(0x14);
Data(0xA5);
Data(0x18);
Data(0xC6);
Data(0x14);
Data(0xA5);
Data(0x18);
Data(0xC6);
Data(0x10);
Data(0x84);
Data(0x1C);
Data(0xE7);
Data(0x14);
Data(0xA5);
Data(0x10);
Data(0x84);
Data(0x1C);
Data(0xE7);
Data(0x08);
Data(0x42);
Data(0x0C);
Data(0x63);
Data(0x08);
Data(0x42);
Data(0x0C);
Data(0x63);
Data(0x10);
Data(0x84);
Data(0x08);
Data(0x42);
Data(0x0C);
Data(0x63);
Data(0x08);
Data(0x42);
Data(0x0C);
Data(0x63);
Data(0x10);
Data(0x84);
Data(0x14);
Data(0xA5);
Data(0x08);
Data(0x42);
Data(0x08);
Data(0x42);
Data(0x14);
Data(0xA5);
Data(0x0C);
Data(0x63);
Data(0x08);
Data(0x42);
Data(0x14);
Data(0xA5);
Data(0x08);
Data(0x42);
Data(0x08);
Data(0x42);
Data(0x0C);
Data(0x63);
Data(0x08);
Data(0x42);
Data(0x14);
Data(0xA5);
Data(0x14);
Data(0xA5);
Data(0x08);
Data(0x42);
Data(0x0C);
Data(0x63);

Command(0xD0);
Data(0x9F);
Data(0x19);
Data(0x00);
Data(0x00);
Data(0xFF);
Data(0x00);
Data(0x00);
Data(0x0D);
Data(0xFF);
Data(0x00);
Data(0x00);
Data(0x0D);
Data(0xFF);
Data(0x00);
Data(0x00);
Data(0x0D);
Data(0x9F);
Data(0x19);
Data(0x00);
Data(0x00);
Data(0xFF);
Data(0x00);
Data(0x00);
Data(0x0D);
Data(0xFF);
Data(0x00);
Data(0x00);
Data(0x0D);
Data(0xFF);
Data(0x00);
Data(0x00);
Data(0x0D);
Data(0x9F);
Data(0x19);
Data(0x00);
Data(0x00);
Data(0xFF);
Data(0x00);
Data(0x00);
Data(0x0D);
Data(0xFF);
Data(0x00);
Data(0x00);
Data(0x0D);
Data(0xFF);
Data(0x00);
Data(0x00);
Data(0x0D);
Data(0x9F);
Data(0x19);
Data(0x00);
Data(0x00);
Data(0xFF);
Data(0x00);
Data(0x00);
Data(0x0D);
Data(0xFF);
Data(0x00);
Data(0x00);
Data(0x0D);
Data(0xFF);
Data(0x00);
Data(0x00);
Data(0x0D);
Data(0x94);
Data(0x28);
Data(0x00);
Data(0x00);
Data(0xFF);
Data(0x00);
Data(0x04);
Data(0x16);
Data(0xFF);
Data(0x00);
Data(0x04);
Data(0x16);
Data(0xFF);
Data(0x00);
Data(0x04);
Data(0x16);
Data(0x8F);
Data(0x35);
Data(0x00);
Data(0x00);
Data(0xFF);
Data(0x00);
Data(0x04);
Data(0x20);
Data(0xFF);
Data(0x00);
Data(0x04);
Data(0x20);
Data(0xFF);
Data(0x00);
Data(0x04);
Data(0x20);
Data(0x8C);
Data(0x42);
Data(0x00);
Data(0x00);
Data(0xFF);
Data(0x00);
Data(0x04);
Data(0x2A);
Data(0xFF);
Data(0x00);
Data(0x04);
Data(0x2A);
Data(0xFF);
Data(0x00);
Data(0x04);
Data(0x2A);
Data(0x8A);
Data(0x50);
Data(0x00);
Data(0x00);
Data(0xFF);
Data(0x00);
Data(0x08);
Data(0x33);
Data(0x88);
Data(0x64);
Data(0x00);
Data(0x00);
Data(0xFF);
Data(0x00);
Data(0x08);
Data(0x46);
Data(0xFF);
Data(0x00);
Data(0x08);
Data(0x46);
Data(0xFF);
Data(0x00);
Data(0x08);
Data(0x46);
Data(0x7C);
Data(0x67);
Data(0x00);
Data(0x00);
Data(0xFF);
Data(0x00);
Data(0x0C);
Data(0x44);
Data(0xFF);
Data(0x00);
Data(0x0C);
Data(0x44);
Data(0xFF);
Data(0x00);
Data(0x0C);
Data(0x44);
Data(0x6E);
Data(0x74);
Data(0x00);
Data(0x00);
Data(0xFF);
Data(0x00);
Data(0x0C);
Data(0x54);
Data(0xFF);
Data(0x00);
Data(0x0C);
Data(0x54);
Data(0xFF);
Data(0x00);
Data(0x0C);
Data(0x54);
Data(0x64);
Data(0x90);
Data(0x00);
Data(0x00);
Data(0xFF);
Data(0x00);
Data(0x10);
Data(0x5E);
Data(0xFF);
Data(0x00);
Data(0x10);
Data(0x5E);
Data(0xFF);
Data(0x00);
Data(0x10);
Data(0x5E);
Data(0x5A);
Data(0x92);
Data(0x00);
Data(0x00);
Data(0xFF);
Data(0x00);
Data(0x10);
Data(0x5F);
Data(0xFF);
Data(0x00);
Data(0x10);
Data(0x5F);
Data(0xFF);
Data(0x00);
Data(0x10);
Data(0x5F);
Data(0x52);
Data(0x94);
Data(0x00);
Data(0x00);
Data(0xFF);
Data(0x00);
Data(0x10);
Data(0x61);
Data(0xFF);
Data(0x00);
Data(0x10);
Data(0x61);
Data(0xFF);
Data(0x00);
Data(0x10);
Data(0x61);
Data(0x4C);
Data(0x95);
Data(0x00);
Data(0x00);
Data(0xFF);
Data(0x00);
Data(0x10);
Data(0x65);
Data(0xFF);
Data(0x00);
Data(0x10);
Data(0x65);
Data(0xFF);
Data(0x00);
Data(0x10);
Data(0x65);
Data(0x47);
Data(0x97);
Data(0x00);
Data(0x00);
Data(0xFF);
Data(0x00);
Data(0x10);
Data(0x62);
Data(0xFF);
Data(0x00);
Data(0x10);
Data(0x62);
Data(0xFF);
Data(0x00);
Data(0x10);
Data(0x62);
Data(0x42);
Data(0x99);
Data(0x00);
Data(0x00);
Data(0xFF);
Data(0x00);
Data(0x10);
Data(0x64);
Data(0xFF);
Data(0x00);
Data(0x10);
Data(0x64);
Data(0xFF);
Data(0x00);
Data(0x10);
Data(0x64);
Data(0x3E);
Data(0x9A);
Data(0x00);
Data(0x00);
Data(0xFF);
Data(0x00);
Data(0x10);
Data(0x66);
Data(0xFF);
Data(0x00);
Data(0x10);
Data(0x66);
Data(0xFF);
Data(0x00);
Data(0x10);
Data(0x66);
Data(0x3A);
Data(0x9C);
Data(0x00);
Data(0x00);
Data(0xFF);
Data(0x00);
Data(0x10);
Data(0x65);
Data(0xFF);
Data(0x00);
Data(0x10);
Data(0x65);
Data(0xFF);
Data(0x00);
Data(0x10);
Data(0x65);
Data(0x37);
Data(0x9D);
Data(0x00);
Data(0x00);
Data(0xFF);
Data(0x00);
Data(0x10);
Data(0x68);
Data(0xFF);
Data(0x00);
Data(0x10);
Data(0x68);
Data(0xFF);
Data(0x00);
Data(0x10);
Data(0x68);
Data(0x34);
Data(0x9F);
Data(0x00);
Data(0x00);
Data(0xFF);
Data(0x00);
Data(0x10);
Data(0x6A);
Data(0xFF);
Data(0x00);
Data(0x10);
Data(0x6A);
Data(0xFF);
Data(0x00);
Data(0x10);
Data(0x6A);
Data(0x32);
Data(0xA0);
Data(0x00);
Data(0x00);
Data(0xFF);
Data(0x00);
Data(0x10);
Data(0x6B);
Data(0xFF);
Data(0x00);
Data(0x10);
Data(0x6B);
Data(0xFF);
Data(0x00);
Data(0x10);
Data(0x6B);
Data(0x2F);
Data(0xA2);
Data(0x00);
Data(0x00);
Data(0xFF);
Data(0x00);
Data(0x10);
Data(0x70);
Data(0xFF);
Data(0x00);
Data(0x10);
Data(0x70);
Data(0xFF);
Data(0x00);
Data(0x10);
Data(0x70);
Data(0x2D);
Data(0xA4);
Data(0x00);
Data(0x00);
Data(0xFF);
Data(0x00);
Data(0x0C);
Data(0x72);
Data(0xFF);
Data(0x00);
Data(0x0C);
Data(0x72);
Data(0xFF);
Data(0x00);
Data(0x0C);
Data(0x72);
Data(0x2B);
Data(0xA6);
Data(0x00);
Data(0x00);
Data(0xFF);
Data(0x00);
Data(0x0C);
Data(0x75);
Data(0xFF);
Data(0x00);
Data(0x0C);
Data(0x75);
Data(0xFF);
Data(0x00);
Data(0x0C);
Data(0x75);
Data(0x29);
Data(0xA7);
Data(0x00);
Data(0x00);
Data(0xFF);
Data(0x00);
Data(0x0C);
Data(0x76);
Data(0xFF);
Data(0x00);
Data(0x0C);
Data(0x76);
Data(0xFF);
Data(0x00);
Data(0x0C);
Data(0x76);
Data(0x28);
Data(0xA8);
Data(0x00);
Data(0x00);
Data(0xFF);
Data(0x00);
Data(0x0C);
Data(0x79);
Data(0xFF);
Data(0x00);
Data(0x0C);
Data(0x79);
Data(0xFF);
Data(0x00);
Data(0x0C);
Data(0x79);
Data(0x26);
Data(0xAA);
Data(0x00);
Data(0x00);
Data(0xFF);
Data(0x00);
Data(0x0C);
Data(0x81);
Data(0xFF);
Data(0x00);
Data(0x0C);
Data(0x81);
Data(0xFF);
Data(0x00);
Data(0x0C);
Data(0x81);
Data(0x25);
Data(0xAC);
Data(0x00);
Data(0x00);
Data(0xFF);
Data(0x00);
Data(0x0C);
Data(0x81);
Data(0xFF);
Data(0x00);
Data(0x0C);
Data(0x81);
Data(0xFF);
Data(0x00);
Data(0x0C);
Data(0x81);
Data(0x23);
Data(0xAE);
Data(0x00);
Data(0x00);
Data(0xFF);
Data(0x00);
Data(0x0C);
Data(0x87);
Data(0xFF);
Data(0x00);
Data(0x0C);
Data(0x87);
Data(0xFF);
Data(0x00);
Data(0x0C);
Data(0x87);
Data(0x22);
Data(0xAF);
Data(0x00);
Data(0x00);
Data(0xFF);
Data(0x00);
Data(0x0C);
Data(0x89);
Data(0xFF);
Data(0x00);
Data(0x0C);
Data(0x89);
Data(0xFF);
Data(0x00);
Data(0x0C);
Data(0x89);
Data(0x21);
Data(0xB1);
Data(0x00);
Data(0x00);
Data(0xFF);
Data(0x00);
Data(0x0C);
Data(0x8D);
Data(0xFF);
Data(0x00);
Data(0x0C);
Data(0x8D);
Data(0xFF);
Data(0x00);
Data(0x0C);
Data(0x8D);
Data(0x20);
Data(0xB2);
Data(0x00);
Data(0x00);
Data(0xFF);
Data(0x00);
Data(0x0C);
Data(0x89);
Data(0xFF);
Data(0x00);
Data(0x0C);
Data(0x89);
Data(0xFF);
Data(0x00);
Data(0x0C);
Data(0x89);
Data(0x1F);
Data(0xB4);
Data(0x00);
Data(0x00);
Data(0xFF);
Data(0x00);
Data(0x0C);
Data(0x8E);
Data(0xFF);
Data(0x00);
Data(0x0C);
Data(0x8E);
Data(0xFF);
Data(0x00);
Data(0x0C);
Data(0x8E);
Data(0x1E);
Data(0xB6);
Data(0x00);
Data(0x00);
Data(0xFF);
Data(0x00);
Data(0x0C);
Data(0x93);
Data(0xFF);
Data(0x00);
Data(0x0C);
Data(0x93);
Data(0xFF);
Data(0x00);
Data(0x0C);
Data(0x93);
Data(0x1D);
Data(0xB8);
Data(0x00);
Data(0x00);
Data(0xFF);
Data(0x00);
Data(0x0C);
Data(0x98);
Data(0xFF);
Data(0x00);
Data(0x0C);
Data(0x98);
Data(0xFF);
Data(0x00);
Data(0x0C);
Data(0x98);
Data(0x1C);
Data(0xBA);
Data(0x00);
Data(0x00);
Data(0xFF);
Data(0x00);
Data(0x0C);
Data(0x95);
Data(0xFF);
Data(0x00);
Data(0x0C);
Data(0x95);
Data(0xFF);
Data(0x00);
Data(0x0C);
Data(0x95);
Data(0x1B);
Data(0xBC);
Data(0x00);
Data(0x00);
Data(0xFF);
Data(0x00);
Data(0x0C);
Data(0x95);
Data(0xFF);
Data(0x00);
Data(0x0C);
Data(0x95);
Data(0xFF);
Data(0x00);
Data(0x0C);
Data(0x95);
Data(0x1B);
Data(0xBC);
Data(0x00);
Data(0x00);
Data(0xFF);
Data(0x00);
Data(0x0C);
Data(0x91);
Data(0xFF);
Data(0x00);
Data(0x0C);
Data(0x91);
Data(0xFF);
Data(0x00);
Data(0x0C);
Data(0x91);
Data(0x1A);
Data(0xBE);
Data(0x00);
Data(0x00);
Data(0xFF);
Data(0x00);
Data(0x0C);
Data(0x9A);
Data(0xFF);
Data(0x00);
Data(0x0C);
Data(0x9A);
Data(0xFF);
Data(0x00);
Data(0x0C);
Data(0x9A);
Data(0x19);
Data(0xC0);
Data(0x00);
Data(0x00);
Data(0xFF);
Data(0x00);
Data(0x0C);
Data(0xA8);
Data(0xFF);
Data(0x00);
Data(0x0C);
Data(0xA8);
Data(0xFF);
Data(0x00);
Data(0x0C);
Data(0xA8);
Data(0x19);
Data(0xC0);
Data(0x00);
Data(0x00);
Data(0xFF);
Data(0x00);
Data(0x0C);
Data(0xA0);
Data(0xFF);
Data(0x00);
Data(0x0C);
Data(0xA0);
Data(0xFF);
Data(0x00);
Data(0x0C);
Data(0xA0);
Data(0x17);
Data(0xC6);
Data(0x00);
Data(0x00);
Data(0xFF);
Data(0x00);
Data(0x02);
Data(0x2C);
Data(0xFF);
Data(0x00);
Data(0x02);
Data(0x2C);
Data(0xFF);
Data(0x00);
Data(0x02);
Data(0x2C);
Data(0x16);
Data(0xC9);
Data(0x00);
Data(0x00);
Data(0xFF);
Data(0x00);
Data(0x02);
Data(0x45);
Data(0xFF);
Data(0x00);
Data(0x02);
Data(0x45);
Data(0xFF);
Data(0x00);
Data(0x02);
Data(0x45);
Data(0x14);
Data(0xD0);
Data(0x00);
Data(0x00);
Data(0xFF);
Data(0x00);
Data(0x02);
Data(0x7F);
Data(0xFF);
Data(0x00);
Data(0x02);
Data(0x7F);
Data(0xFF);
Data(0x00);
Data(0x02);
Data(0x7F);
Data(0x11);
Data(0xDE);
Data(0x00);
Data(0x00);
Data(0xFF);
Data(0x00);
Data(0x02);
Data(0xF0);
Data(0xFF);
Data(0x00);
Data(0x02);
Data(0xF0);
Data(0xFF);
Data(0x00);
Data(0x02);
Data(0xF0);
Data(0x0F);
Data(0xEB);
Data(0x00);
Data(0x00);
Data(0xFF);
Data(0x00);
Data(0x03);
Data(0x54);
Data(0xFF);
Data(0x00);
Data(0x03);
Data(0x54);
Data(0xFF);
Data(0x00);
Data(0x03);
Data(0x54);

Command(0xDD);
Data(0x0B);
Data(0x0B);
Data(0x0B);
Data(0x00);
Data(0x00);
Data(0x00);
Data(0x00);
Data(0x00);
Data(0x00);
Data(0x00);
Data(0x00);
Data(0x00);

Command(0xDE);
Data(0x1C);

Command(0xE4);
Data(0x7F);
Data(0x7F);
Data(0x7F);
Data(0xEF);
Data(0xEF);
Data(0xEF);
Data(0x00);
Data(0x00);
Data(0x00);
Data(0xFF);
Data(0xFF);
Data(0xFF);
Data(0x00);
Data(0x00);
Data(0x00);

Command(0xED);
Data(0x0F);

Command(0xC7);
Data(0x00);

Command(0xC8);
Data(0xA4);

Command(0xD2);
Data(0xA7);

Command(0xE2);
Data(0x09);

Delay_ms(255);
Delay_ms(255);
Delay_ms(255);

Command(0xF0);
Data(0x7E);
Data(0x54);
Data(0x45);
Data(0x53);
Data(0x54);
Data(0x21);

Command(0x51);
Data(0x16);

Command(0x50);
Data(0x00);

Command(0xCE);
Data(0x80);
Data(0x00);
Data(0xE0);
Data(0x00);
Data(0x00);
Data(0x00);

Command(0xCD);
Data(0x06);
Data(0xC7);

Delay_ms(16);   //Delay 16ms or more

Command(0xCE);
Data(0x80);
Data(0x00);
Data(0x00);
Data(0x00);
Data(0x00);
Data(0x00);

Command(0xCD);
Data(0x06);
Data(0xC7);

Command(0xCD);
Data(0x00);
Data(0x00);

Command(0x35);
Data(0x00);

Command(0xE0);
Data(0xD0);
Data(0x00);

Command(0x29);
Data(0x00);

```

---
Tags: display, oled
---


title: RFID reading function returning null

text:
# Question
Title: RFID reading function returning null
I have a function that reads an RFID card and returns the RFID string. The function reads the string well but I am using the ArduinoJson library to generate JSON.

This is the function that I am using to read RFID cards:

```
String rfidOku() {
  String kartid= "";
  if (mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial()) {
    for (byte i = 0; i < mfrc522.uid.size; i++) {
      kartid.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));
      kartid.concat(String(mfrc522.uid.uidByte[i], HEX));
    }
    kartid.toUpperCase();
    //Serial.println(kartid);
  }
  kartid.trim();
  return kartid;
}

```

And in the loop function, if a button is pressed I am getting an RFID and I am creating json using it.

```
const size_t capacity = JSON_OBJECT_SIZE(4);
DynamicJsonDocument doc(capacity);
const String str_rfid = rfidOku();
doc["id"] = odeme.id;
doc["fiyat"] = odeme.fiyat;
doc["rfid"] = str_rfid;
serializeJson(doc, Serial);

```

When I look at serial monitor the RFID field is null. Why does this happen? I tried to write another string there, and it works well with the other string. Why doesn't it work with str\_rfid?

I also printed the value of str\_rfid using Serial.print, str\_rfid is getting the RFID card id from the function well.

# Answer
It could be that your JSON object capacity is too small because of *string duplication* when you deserialise it to print it.

You should try a capacity like `JSON_OBJECT_SIZE(3) + 500` for deserialising, and see what happens.

Also, try: `doc["rfid"] = str_rfid.c_str();` to see if that works better (CString instead of String object).

More information on object capacity can be found here; there's a calculator here.
> 0 votes

---
Tags: arduino-mega, json
---


title: ATMEGA328P-U vs ATMEGA328-PU

text:
# Question
Title: ATMEGA328P-U vs ATMEGA328-PU
On my Arduino UNO the chip part number is ATMEGA328**P-U**, i recently bought a ATMEGA328-**PU** to make a standalone Arduino. realized the part number differences after receiving the package...

I noticed that some arduino UNOs have the chip with part number of ATMEGA328**P-PU**! I'm totally confused!

Those chip are the same? can i use the one that i bought for an standalone Arduino?

If no what are the differences?

# Answer
The main difference is the bit before the `-`. That is, the 328 vs the 328P. The "P" there denotes "Picopower" which allows the chip to run at very low power consumptions.

Basically the P version is a more modern version of the non-P chip. There are probably other internal differences too but you will have to check the datasheets thoroughly for those.

Everything after the `-` is to do with the packaging and environmental grading of the chip. For example PU is a -40C to +85C grade DIP chip. ANR is a -40C to +105C grade TQFP chip, etc.

If you see 328P-U then that's probably a fake chip. There's no such thing as single U suffix.
> 14 votes

# Answer
There are three die types:

328

328P

328PB

all have different signature bytes which may or may not impact loading code into them. Generally tho the programming software needs to know which part type is being used, at a minimum for installing bootloader code. Serial downloading may end up ignoring the signature bytes of a bootloaded part.

They can be had in different packaging, this is what Digikey is showing as available options:

-PU - 28 pin DIP

-AU - 32 pin TQFP

-AN - 32 pin TQFP

-MM - 28 pin leadless package, smaller than 32 pin leadless

-MN - 32 pin leadless package

-MU - 32 pin leadless package

-15AZ - 32 pin TQFP, rated for a higher temperature range

-15MZ - 32 pin leadless package rated for a higher temperature range

Any letters to the right of those seen when ordering indicate the method they are supplied - loose parts, parts in a reel, parts in a tube, etc.

Anything else is either an older part that did not follow the convention, or is a counterfeit part.

Tables 38.7 and 38.8 lists these options for the 328 and 328P for example, with H indicating a type of lead finish, and R indicating Tape & Reel availability:

http://ww1.microchip.com/downloads/en/DeviceDoc/ATmega48A-PA-88A-PA-168A-PA-328-P-DS-DS40002061A.pdf

ATmega328-AU

ATmega328-AUR

ATmega328-MMH

ATmega328-MMHR

ATmega328-MU

ATmega328-MUR

ATmega328-PU

And 328P options:

ATmega328-AU

ATmega328-AUR

ATmega328-MMH

ATmega328-MMHR

ATmega328-MU

ATmega328-MUR

ATmega328-PU

With these rated to 105C

ATmega328P-AN

ATmega328P-ANR

ATmega328P-MN

ATmega328P-MNR

ATmega328P-PN

I think you need to pull up the Automotive data sheet to see the Z numbered parts.

And the PB is a different data sheet as well.
> 6 votes

# Answer
User `line_code` from forum.arduino.cc recently received an `ATMEGA328P-U` (or actually `ATMEGA328P U`) from Mouser (a company which you would not suspect to send out fakes or source from the gray market). He asked Mouser (who contacted the manufacturer Microchip) and got the following response:

> As part of Part marking change due to the migration from Atmel to Microchip, the package identifier has been removed from the device marking as this can be observed visually for different packages. This will be updated in the upcoming revisions of the device datasheet. As per this new marking the ATMEGA328P U are valid devices without any process change. \[...\]

(Source: https://forum.arduino.cc/index.php?topic=561928.msg3890391#msg3890391)

So the P stands for pico power (the low power modern version) and if the package is a 28-pin DIP like in the photo I took then this specific `ATMEGA328P U` is an `ATMEGA328P-PU`.

Note that the Microchip response does say that the packaging is omitted from the marking. Hence we can expect `ATMEGA328P U`s to pop up in other packages. What the `U` stands for is unclear.
> 6 votes

---
Tags: atmega328
---