body:
I'm working on [nRF52832 Bluefruit Adafruit Module][1]. I want the BLE connection to disconnect using a function and can call whenever required. But the issue is the disconnect function needs "conn_handle" to disconnect from the current connected Client.

Can anyone help me find where I can get the "conn_handle" of the connected client?

    /**
     * Callback invoked when a connection is dropped
     * @param conn_handle
     * @param reason is a BLE_HCI_STATUS_CODE which can be found in ble_hci.h
     */
    void disconnect_callback(uint16_t conn_handle, uint8_t reason)
    {
      (void) conn_handle;
      (void) reason;

      connection_num--;

      // Mark the ID as invalid
      int id  = findConnHandle(conn_handle);

      // Non-existant connection, something went wrong, DBG !!!
      if ( id < 0 ) return;

      // Mark conn handle as invalid
      prphs[id].conn_handle = BLE_CONN_HANDLE_INVALID;

      Serial.print(prphs[id].name);
      Serial.println(" disconnected!");
    }

The below complete code is for "Central Bleuart Multi"-

    /*********************************************************************

     This is an example for our nRF52 based Bluefruit LE modules

     Pick one up today in the adafruit shop!

     Adafruit invests time and resources providing this open source code,
     please support Adafruit and open-source hardware by purchasing
     products from Adafruit!

     MIT license, check LICENSE for more information
     All text above, and the splash screen below must be included in
     any redistribution
    *********************************************************************/

    /* This sketch demonstrates the central API() that allows you to connect
     * to multiple peripherals boards (Bluefruit nRF52 in peripheral mode, or
     * any Bluefruit nRF51 boards).
     *
     * One or more Bluefruit boards, configured as a peripheral with the
     * bleuart service running are required for this demo.
     *
     * This sketch will:
     *  - Read data from the HW serial port (normally USB serial, accessible
     *    via the Serial Monitor for example), and send any incoming data to
     *    all other peripherals connected to the central device.
     *  - Forward any incoming bleuart messages from a peripheral to all of
     *    the other connected devices.
     *
     * It is recommended to give each peripheral board a distinct name in order
     * to more easily distinguish the individual devices.
     *
     * Connection Handle Explanation
     * -----------------------------
     * The total number of connections is BLE_MAX_CONNECTION (20)
     *
     * The 'connection handle' is an integer number assigned by the SoftDevice
     * (Nordic's proprietary BLE stack). Each connection will receive it's own
     * numeric 'handle' starting from 0 to BLE_MAX_CONNECTION-1, depending on the order
     * of connection(s).
     *
     * - E.g If our Central board connects to a mobile phone first (running as a peripheral),
     * then afterwards connects to another Bluefruit board running in peripheral mode, then
     * the connection handle of mobile phone is 0, and the handle for the Bluefruit
     * board is 1, and so on.
     */

    /* LED PATTERNS
     * ------------
     * LED_RED   - Blinks pattern changes based on the number of connections.
     * LED_BLUE  - Blinks constantly when scanning
     */

    #include <bluefruit.h>

    // Struct containing peripheral info
    typedef struct
    {
      char name[16+1];

      uint16_t conn_handle;

      // Each prph need its own bleuart client service
      BLEClientUart bleuart;
    } prph_info_t;

    /* Peripheral info array (one per peripheral device)
     *
     * There are 'BLE_MAX_CONNECTION' central connections, but the
     * the connection handle can be numerically larger (for example if
     * the peripheral role is also used, such as connecting to a mobile
     * device). As such, we need to convert connection handles <-> the array
     * index where appropriate to prevent out of array accesses.
     *
     * Note: One can simply declares the array with BLE_MAX_CONNECTION and use connection
     * handle as index directly with the expense of SRAM.
     */
    prph_info_t prphs[BLE_MAX_CONNECTION];

    // Software Timer for blinking the RED LED
    SoftwareTimer blinkTimer;
    uint8_t connection_num = 0; // for blink pattern

    void setup()
    {
      Serial.begin(115200);
      while ( !Serial ) delay(10);   // for nrf52840 with native usb

      // Initialize blinkTimer for 100 ms and start it
      blinkTimer.begin(100, blink_timer_callback);
      blinkTimer.start();

      Serial.println("Bluefruit52 Central Multi BLEUART Example");
      Serial.println("-----------------------------------------\n");

      // Initialize Bluefruit with max concurrent connections as Peripheral = 0, Central = 4
      // SRAM usage required by SoftDevice will increase with number of connections
      Bluefruit.begin(0, 4);

      // Set Name
      Bluefruit.setName("Bluefruit52 Central");

      // Init peripheral pool
      for (uint8_t idx=0; idx<BLE_MAX_CONNECTION; idx++)
      {
        // Invalid all connection handle
        prphs[idx].conn_handle = BLE_CONN_HANDLE_INVALID;

        // All of BLE Central Uart Serivce
        prphs[idx].bleuart.begin();
        prphs[idx].bleuart.setRxCallback(bleuart_rx_callback);
      }

      // Callbacks for Central
      Bluefruit.Central.setConnectCallback(connect_callback);
      Bluefruit.Central.setDisconnectCallback(disconnect_callback);

      /* Start Central Scanning
       * - Enable auto scan if disconnected
       * - Interval = 100 ms, window = 80 ms
       * - Filter only accept bleuart service in advertising
       * - Don't use active scan (used to retrieve the optional scan response adv packet)
       * - Start(0) = will scan forever since no timeout is given
       */
      Bluefruit.Scanner.setRxCallback(scan_callback);
      Bluefruit.Scanner.restartOnDisconnect(true);
      Bluefruit.Scanner.setInterval(160, 80);       // in units of 0.625 ms
      Bluefruit.Scanner.filterUuid(BLEUART_UUID_SERVICE);
      Bluefruit.Scanner.useActiveScan(false);       // Don't request scan response data
      Bluefruit.Scanner.start(0);                   // 0 = Don't stop scanning after n seconds
    }

    /**
     * Callback invoked when scanner picks up an advertising packet
     * @param report Structural advertising data
     */
    void scan_callback(ble_gap_evt_adv_report_t* report)
    {
      // Since we configure the scanner with filterUuid()
      // Scan callback only invoked for device with bleuart service advertised
      // Connect to the device with bleuart service in advertising packet
      Bluefruit.Central.connect(report);
    }

    /**
     * Callback invoked when an connection is established
     * @param conn_handle
     */
    void connect_callback(uint16_t conn_handle)
    {
      // Find an available ID to use
      int id  = findConnHandle(BLE_CONN_HANDLE_INVALID);

      // Eeek: Exceeded the number of connections !!!
      if ( id < 0 ) return;

      prph_info_t* peer = &prphs[id];
      peer->conn_handle = conn_handle;

      Bluefruit.Connection(conn_handle)->getPeerName(peer->name, sizeof(peer->name)-1);

      Serial.print("Connected to ");
      Serial.println(peer->name);

      Serial.print("Discovering BLE UART service ... ");

      if ( peer->bleuart.discover(conn_handle) )
      {
        Serial.println("Found it");
        Serial.println("Enabling TXD characteristic's CCCD notify bit");
        peer->bleuart.enableTXD();

        Serial.println("Continue scanning for more peripherals");
        Bluefruit.Scanner.start(0);

        Serial.println("Enter some text in the Serial Monitor to send it to all connected peripherals:");
      } else
      {
        Serial.println("Found ... NOTHING!");

        // disconnect since we couldn't find bleuart service
        Bluefruit.disconnect(conn_handle);
      }

      connection_num++;
    }

    /**
     * Callback invoked when a connection is dropped
     * @param conn_handle
     * @param reason is a BLE_HCI_STATUS_CODE which can be found in ble_hci.h
     */
    void disconnect_callback(uint16_t conn_handle, uint8_t reason)
    {
      (void) conn_handle;
      (void) reason;

      connection_num--;

      // Mark the ID as invalid
      int id  = findConnHandle(conn_handle);

      // Non-existant connection, something went wrong, DBG !!!
      if ( id < 0 ) return;

      // Mark conn handle as invalid
      prphs[id].conn_handle = BLE_CONN_HANDLE_INVALID;

      Serial.print(prphs[id].name);
      Serial.println(" disconnected!");
    }

    /**
     * Callback invoked when BLE UART data is received
     * @param uart_svc Reference object to the service where the data
     * arrived.
     */
    void bleuart_rx_callback(BLEClientUart& uart_svc)
    {
      // uart_svc is prphs[conn_handle].bleuart
      uint16_t conn_handle = uart_svc.connHandle();

      int id = findConnHandle(conn_handle);
      prph_info_t* peer = &prphs[id];

      // Print sender's name
      Serial.printf("[From %s]: ", peer->name);

      // Read then forward to all peripherals
      while ( uart_svc.available() )
      {
        // default MTU with an extra byte for string terminator
        char buf[20+1] = { 0 };

        if ( uart_svc.read(buf,sizeof(buf)-1) )
        {
          Serial.println(buf);
          sendAll(buf);
        }
      }
    }

    /**
     * Helper function to send a string to all connected peripherals
     */
    void sendAll(const char* str)
    {
      Serial.print("[Send to All]: ");
      Serial.println(str);

      for(uint8_t id=0; id < BLE_MAX_CONNECTION; id++)
      {
        prph_info_t* peer = &prphs[id];

        if ( peer->bleuart.discovered() )
        {
          peer->bleuart.print(str);
        }
      }
    }

    void loop()
    {
      // First check if we are connected to any peripherals
      if ( Bluefruit.Central.connected() )
      {
        // default MTU with an extra byte for string terminator
        char buf[20+1] = { 0 };

        // Read from HW Serial (normally USB Serial) and send to all peripherals
        if ( Serial.readBytes(buf, sizeof(buf)-1) )
        {
          sendAll(buf);
        }
      }
    }

    /**
     * Find the connection handle in the peripheral array
     * @param conn_handle Connection handle
     * @return array index if found, otherwise -1
     */
    int findConnHandle(uint16_t conn_handle)
    {
      for(int id=0; id<BLE_MAX_CONNECTION; id++)
      {
        if (conn_handle == prphs[id].conn_handle)
        {
          return id;
        }
      }

      return -1;
    }

    /**
     * Software Timer callback is invoked via a built-in FreeRTOS thread with
     * minimal stack size. Therefore it should be as simple as possible. If
     * a periodically heavy task is needed, please use Scheduler.startLoop() to
     * create a dedicated task for it.
     *
     * More information http://www.freertos.org/RTOS-software-timer.html
     */
    void blink_timer_callback(TimerHandle_t xTimerID)
    {
      (void) xTimerID;

      // Period of sequence is 10 times (1 second).
      // RED LED will toggle first 2*n times (on/off) and remain off for the rest of period
      // Where n = number of connection
      static uint8_t count = 0;

      if ( count < 2*connection_num ) digitalToggle(LED_RED);
      if ( count % 2 && digitalRead(LED_RED)) digitalWrite(LED_RED, LOW); // issue #98

      count++;
      if (count >= 10) count = 0;
    }

[GitHub Source code][2]

I want to invoke this disconnect function, but I don't know where to get conn_handle. If anyone has any idea please help me.

I have already tried going into libraries; the best it shows is just the definition of the callback function:

    1: Bluefruit.Central.setDisconnectCallback(disconnect_callback);

    2: void BLECentral::setDisconnectCallback( ble_disconnect_callback_t fp )
       {
         _disconnect_cb = fp;
       }

    3: class BLECentral
       {
         ...
         private:
           ble_disconnect_callback_t _disconnect_cb;
       }

    4: typedef void (*ble_disconnect_callback_t ) (uint16_t conn_hdl, uint8_t reason);

This is all I got regarding this disconnect function in different libraries following the definition but nothing related to conn_handle.

  [1]: https://www.adafruit.com/product/3406
  [2]: https://github.com/adafruit/Adafruit_nRF52_Arduino/blob/master/libraries/Bluefruit52Lib/examples/Central/central_bleuart/central_bleuart.ino

title: nRF52832 BLE "conn_handle" to disconnect the current connected devices

Answers: 1

body:
Idk if its a right or not but it works.

When there's is a new connection established, "connect" gets revoked, with "conn_handle" as its argument. If someone knows please tell how is this function revoke itself.

But what I did is make a global variable `uint16_t conn_handle`

    uint16_t g_conn_handle;
    void connect_callback(uint16_t conn_handle)
        {
          g_conn_handle=conn_handle;
          // Find an available ID to use
          int id  = findConnHandle(BLE_CONN_HANDLE_INVALID);

          // Eeek: Exc
          ...

Now I can call the Disconnect function with this `g_conn_handle` global variable.


body:
I'm using an ESP8266 for IOT devices.

I wish to work with an ESP32 and harvest its benefits - for my uses managing WiFi and MQTT connectivity.

Most tasks examples are *very* basic and quite the same (blinking LEDs). But for a real time application, more data is needed for which I can't find a guide.

For example:
1) when to use `core0` or `core1`?
2) How to evaluate stack size needed for a task?
3) Are there any limitation for a task? Is a `mqtt.loop()`  for example, ligit, memory wise?

I'd be happy to read about real life-implementations for tasks (especially "dos" and "don'ts")

Example usage from [ESP32 DOCS][1]

     // Dimensions the buffer that the task being created will use as its stack.
     // NOTE:  This is the number of bytes the stack will hold, not the number of
     // words as found in vanilla FreeRTOS.
    #define STACK_SIZE 200

     // Structure that will hold the TCB of the task being created.
     StaticTask_t xTaskBuffer;

     // Buffer that the task being created will use as its stack.  Note this is
     // an array of StackType_t variables.  The size of StackType_t is dependent on
     // the RTOS port.
     StackType_t xStack[ STACK_SIZE ];

     // Function that implements the task being created.
     void vTaskCode( void * pvParameters )
     {
         // The parameter value is expected to be 1 as 1 is passed in the
         // pvParameters value in the call to xTaskCreateStatic().
         configASSERT( ( uint32_t ) pvParameters == 1UL );

         for( ;; )
         {
             // Task code goes here.
         }
     }

     // Function that creates a task.
     void vOtherFunction( void )
     {
         TaskHandle_t xHandle = NULL;

         // Create the task without using any dynamic memory allocation.
         xHandle = xTaskCreateStatic(
                       vTaskCode,       // Function that implements the task.
                       "NAME",          // Text name for the task.
                       STACK_SIZE,      // Stack size in bytes, not words.
                       ( void * ) 1,    // Parameter passed into the task.
                       tskIDLE_PRIORITY,// Priority at which the task is created.
                       xStack,          // Array to use as the task's stack.
                       &xTaskBuffer );  // Variable to hold the task's data structure.

         // puxStackBuffer and pxTaskBuffer were not NULL, so the task will have
         // been created, and xHandle will be the task's handle.  Use the handle
         // to suspend the task.
         vTaskSuspend( xHandle );
     }

  [1]: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/freertos.html

title: Tasks in ESP32: guidelines rather than blink example

Answers: 1

body:
> in a real time application, more data is needed which I can't find a guide for it

That is because there isn't one. The amount of memory needed is completely defined by the application and the task you want to run, so no "guide" can tell you what that will be.

You will have to analyze the actual software you want to run to see what it does and how it works to estimate the likely size of stack needed (note: stack is used for local (non-static) variables as well as storage for registers when calling functions). It's entirely up to you to work it out. The basic assumption (since the SDK is aimed at professional users not hobbyists like typical Arduino users) is that you know what your software is doing since it's you writing that software.

> when to use core0 or core1?

When you need to balance your processing load. Again that's entirely down to your software and how you need it to work. Maybe you have one task that has to have almost exclusive use of a core - in which case you bind everything except that task to the same core, and place that task on its own core. Or maybe you just want to spread the tasks out evenly. It's your choice.

> Are there any limitation for task?

Yes. The chip only has finite memory. You can't give a task more memory than there is. Also be aware that there may be a watchdog monitoring your tasks so you have to be sure to "kick" it regularly and not block too long.


body:
I've old Nanos that to program (upload) with Arduino IDE I have to select "ATMEGA328P Old Bootloader".   The programming is via the standard Nano USB cable, and I need the CH340 driver under Windows 7.

With mblock (ide) I've selected the nano device package, but when I go to program the nano with the scratch program, the COM port is available, but the device is never found.   I suspect this is due to the old bootloader.  Is there a way to make use of the old bootloader under mblock?

[At this time not looking to re-flash my Nanos with a separate programmer.]
TIA.

title: Is it possible to use Nano with mblock and oldbootler?

Answers: 0


body:
This sounds straightforward enough, but I'm struggling to find a good answer.

Suppose I declare a C++ class with private members that collectively occupy an odd number of bytes. Say...

~~~
class Foo {
private:
    uint8_t bitflags;
    uint32_t millis;
}
~~~

or

~~~
class Foo {
private:
    uint8_t rawData[3];
}
~~~

If I compile it using GCC or Clang (possibly, wrapped inside the Arduino IDE, or multiply-wrapped inside PlatformIO, CMake, and an IDE like CLion), is there any likely scenario where the compiler (when targeting 8-bit AVR... specifically, the ATmega2560 on an Arduino Mega2560) would be inclined to add padding bytes to the portion of the class stored in SRAM? Say... between `bitflags` and `millis`, or between an instance of `Foo` and a `uint64_t` right after it?

If yes, what do I need to use to tell the compiler, "absolutely, positively ***DO NOT*** pad variables in SRAM (and, if you find yourself in a situation where it's seemingly unavoidable, at least output a prominent compile-time warning, if not an outright compilation-stopping error)?

Then... if I do that... are there any negative *consequences* to doing that with code that's targeting (and ultimately running upon) an 8-bit AVR?

As far as I know, 8-bit AVR has *never* had specific opcodes for copying a *pair* of consecutive bytes between registers and SRAM (I think, because Atmel literally ran out of opcode mapping space, and had nowhere to *put* hypothetical new opcodes like, "ldw rz, $f00d"), and `movw` only applied to pairs of *registers*... so, in theory, there's no reason *for* the compiler to "optimize" SRAM access to be word-aligned.

That said... I suppose it's not inconceivable that a compiler might *default* to word-alignment (even on platforms where it doesn't *matter*), just for the sake of ABI consistency between different platforms.

Before someone suggests, "try it and see!"... I've gotten far enough into learning C++ to know that with C++, you ***can't trust*** "compiles without errors and passes unit tests on *my computer*, with *{this} IDE*" as a general-purpose proof-of-correctness for C++ involving "implementation-defined" or "undefined" behavior. AFAIK, padding behavior is "implementation-defined".

title: Does avr-libc have any reason to word-align C++ class member variables?

Answers: 1

body:
GCC has an extension to add attributes to types, which you can use to tell it your alignment requirements.

Additionally it has a `#pragma` to define the alignment, which could be used alternatively.

But as you already suspect, for this 8-bit target there should be no reason to insert padding bytes.

---

So your question boils down to find a method to detect unwanted padding. You can do this in a standard compliant way, which I show below. Yes, it does introduce additional types, one per structure. But it does not generate any unnecessary objects that eat your precious resources.

The "trick" is to use the `sizeof` operator to calculate a valid array size only, if the size of the checked type meets the expectation. If not, a compiler error safely breaks the generation of code. Granted, the error message is misleading an unsuspecting user, so it is really necessary to name the macro and the type accordingly.

This example compiles successfully with a PC as target, but not with an AVR as target. This is intentionally to demonstrate the working, because with an AVR target the type `UP` should have no padding bytes.

```c
#define ASSERT_TYPE_SIZE(Type, size) \
    typedef char Assert##Type##Size[2 * (sizeof(Type) == (size)) - 1]

typedef struct {
    char c;
    long l;
} UP;
ASSERT_TYPE_SIZE(UP, sizeof (long) + sizeof(long));

typedef struct __attribute__((packed)) {
    char c;
    long l;
} P1;
ASSERT_TYPE_SIZE(P1, sizeof (char) + sizeof(long));

#pragma pack(1)
typedef struct {
    char c;
    long l;
} P2;
ASSERT_TYPE_SIZE(P2, sizeof (char) + sizeof(long));
#pragma pack()
```


body:
I have only one pin available and I'd need to use it both for a digitalRead and for sending serial messages (assigning it the Tx role within a SoftwareSerial). I can alternate these two operations, but I don't seem to succeed. I could be interested in other pairs as well (digitalRead+Rx, digitalWrite+Tx and digitalWrite+Rx) and I hope that understanding one will solve them all, but for now I'd be happy to get the first one working. My first naive attempt would be something like:

```
 #include <SoftwareSerial.h>

SoftwareSerial swSerial(7,6);
int val;

void setup() {

  pinMode(6, INPUT_PULLUP);

}

void loop() {

  val = digitalRead(6);

  delay(2000);

  swSerial.begin(19200);
  swSerial.print("myData");
  swSerial.end();

  delay(2000);

}
```

But I've made other experiments, for example with a digitalWrite, hoping that combining two forms of output would be feasible, but again no way. I know I can alternate a pin role between output and input as long as common digital read/write operations are involved, but SoftwareSerial appears to be less flexible. It seems to me it refuses to work as soon as the pin is declared/used for common digital purposes. Is there a way to accomplish my goal?

I guess that similar requirements and fixes (make a pin role more flexible) led to the [Software Serial with Half Duplex][1] library, but I'd refrain from adopting it because I feel it is overcomplicated and seems like overkill for my purpose, moreover it doesn't seem actively supported.

To avoid a XY problem, my very initial need (I may have further ones, requiring the different pairs mentioned at the beginning) would be to check whether this pin is floating or connected to something (I can chose between Vcc or Gnd, setting up the pull-up or an external pull-down accordingly) and to send back some information (obviously this is useful if the pin is actually connected, but I have no reason not to send data anyway) alternating the tasks a few times per second at least.

  [1]: https://forum.arduino.cc/t/software-serial-with-half-duplex-for-a-shared-serial-bus/112131

title: Use same pin for two purposes

Answers: 1

body:
First of all, for using the Software Serial you need to set your tx and rx pins to OUTPUT, that what the library does under the hood.

What you may try to do is to set a millis timer (forget about delay(), never ever use it) and change pin mode to INPUT once every 200ms let's say. And after your measurements put it back to output as soon as you can.

200ms delay is normally ok for some readings like button click. If you can read the value more rare do it (for example you may read some sensor value only once per hour). Here is an example:

        #include <SoftwareSerial.h>

    SoftwareSerial swSerial(7,6);
    int val;

    byte timer = 200; // Read value every 200ms
    uint32_t prevTime = 0;

    void setup() {

     // Don't change pin mode here
     swSerial.begin(19200);

    }

    void loop() {

     if (millis() - prevTime > timer) {
      // you could try swSerial.flush(); here...
      prevTime = millis(); // reset timer
      pinMode(6, INPUT_PULLUP); // changing pin mode and reading value
      val = digitalRead(6);
      pinMode(6, OUTPUT); // changing pin mode back
     }

     swSerial.print("myData");
     // swSerial.end(); // I don't think you need this line;

    }

It may be a solution from a programming point of view. But another task is to organize an electric multiplexing for 2 different devices on the same pin as was mentioned by @the busybee


body:
I purchased https://www.jaycar.co.nz/medias/sys_master/images/images/9677365510174/XC4426-dataSheetMain.pdf, which seems identical to https://arduinomodules.info/ky-005-infrared-transmitter-sensor-module/.

I connected the module according to the diagram:
[![enter image description here][1]][1]

I then copied the following Sketch:

    #include <IRremote.h>
    IRsend irsend;
    void setup()
    {
        Serial.begin(9600); // Initialize serial interface
    }
    void loop()
    {
        for (int i = 0; i < 10; i++) {
           irsend.sendSony(0xa90, 12); // code for Sony TV power command
           delay(5000); // wait 5 seconds
       }
    }

When I compiled the above, I got the following warning:

> warning: 'void IRsend::sendSony(long unsigned int, int)' is deprecated: This old function sends MSB first! Please use sendSony(aAddress, aCommand, aNumberOfRepeats).

So, I modified the code and added a `3` for the `aNumberOfRepeats` parameter. Thus, my final Sketch was this:

    #include <IRremote.h>
    IRsend irsend;
    void setup()
    {
        Serial.begin(9600); // Initialize serial interface
    }
    void loop()
    {
        for (int i = 0; i < 10; i++) {
           irsend.sendSony(0xa90, 12, 3); // code for Sony TV power command
           delay(5000); // wait 5 seconds
       }
    }

When I ran the Sketch on my Uno and viewed the module through my camera phone, I did not see the module blinking. My assumption is that this is not working for some reason. Any ideas why?

Also, I'm measuring about 4.5 volts between GND and the middle pin. That seems right. When I measure GND and the signal out pin, I get a steady 0.64 volts. Shouldn't that be toggling between 0 and some number?

**UPDATE per @orithena's comment:**

I've updated the code as per suggested, but the transmitter still doesn't blink when viewed through my camera phone:

    #include <IRremote.h>

    IRsend irsend;

    #define IR_SEND_PIN 5

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

    void loop()
    {
        for (int i = 0; i < 10; i++) {
           irsend.sendSony(0xa90, 12, 255);
           delay(1000);
       }
    }

Just a few notes about this new code:

 1. I tested connecting `S` to pins 3 and 5; neither worked
 2. `255` is the highest number I could set for `aNumberOfRepeats`, otherwise I would get a compile warning: "warning: large integer implicitly truncated to unsigned type"

**UPDATE per @jsotola's comment:**

[![enter image description here][2]][2][![enter image description here][3]][3][![enter image description here][4]][4]

  [1]: https://i.stack.imgur.com/smgTj.png
  [2]: https://i.stack.imgur.com/LiTBf.jpg
  [3]: https://i.stack.imgur.com/DdRgq.jpg
  [4]: https://i.stack.imgur.com/DNHhC.jpg

title: Uno: Infrared Transmitter Module Not Transmitting

Answers: 0


body:
I took a look at a barebones Arduino schematic.
It had three different ways of programming the chip.
[![enter image description here][1]][1]

The first interface is for programming through SPI (For example with "Pocket AVR Programmer", or "USBTinyISP").

The second interface is for programming through an FTDI to USB module.

What is the third programming interface? It only has `MOSI, MISO and SCK`.

EDIT: This is a picture of the full schematic. Unfortunately, I could not find the link from which I downloaded it. I am sure it was from Github though.

[![enter image description here][2]][2]

  [1]: https://i.stack.imgur.com/0SyYs.png
  [2]: https://i.stack.imgur.com/vhAVD.png

title: Methods of programming the Arduino

Answers: 2

body:
The 2x2 pin JP2 is connected to the Atmel 16U2 or 32U2 processor (whichever the manufacturer used) which provides the USB I/O interface to/from the Atmel 328p, the one we usually consider to be the Uno's processor. When pins are actually installed on that pad, jumpers may be placed across either or both pairs to connect the xxU2's pin-4 to pin-6, and/or pin-5 to pin-7, which connect to that processor's interrupts (numbered the same as those pins).

My searches have not yielded any answer to the question of why it was provided, other than to suggest that they may have been intended for a feature that was never implemented. You can see JP2 and its connections to the xxU2 processor in the center of [this schematic][1].

Update:

I was looking at the 3-pin connector(?) marked '???' in your question, and JP4 on the schematic in your update. Since your schematic does not show the xxU2 chip, and the connections of '???' are marked D11, D12, and D13, I'm going to guess instead that these are either auxilliary pins to access the 328's SPI interface, or is showing half of the ICSP hardware programming interface (the 3x2 pin block just above the '328 on the schematic I linked).

  [1]: https://electrosome.com/wp-content/uploads/2014/07/Arduino-Uno-R3-Schematic-Diagram.jpg

body:
JP2 and JP8 are both serial pin headers suitable for programming -- they connect to the same pins of the chip: RXD, TXD and RST. This is programming via UART: A bootloader software (which has to be "pre-burnt" in the chip's flash memory) is the first thing that is run after a reset (RST) signal. It waits a little moment for data to arrive on RXD. If data arrives, the bootloader goes into programming mode: the data is written to flash memory, making it the firmware to be executed after the next RST. (If no data arrives: well, then the firmware that already is there is executed.)

Programming the chip via JP4 would use "hardware-supported" programming interface via SPI, recognizeable by the pins MISO, MOSI and SCK. That is the only way to get the first bootloader into the flash memory. It also provides you with a way to flash and re-flash a firmware without a pre-burnt bootloader (making the bootloader space available to your firmware). That method is described in [the ATmega328P datasheet, chapter 27.8][1] and is the primary method employed by "ISP programmer boards". You could use those from the Arduino IDE using the menu option "Upload using programmer".

If this "barebone Arduino" circuit is meant to use an ATmega328P with the Arduino bootloader, however, I would assume that JP4 is meant to provide a pin header for some SPI sensor module (even though you could program and even un-brick the chip using this interface).

NB: "FTDI" is a red herring here. One of the most-used ISP programmer boards employs an chip made by FTDI, so you could call this method "programming via FTDI" ... but a specific USB-to-Serial cable using an chip made by FTDI and an 1x5 pin header is also called an "FTDI cable". (For a while, FTDI made the best USB-to-Serial chips. Clones just did not work that reliable. Today, CH340G and CP2104 are reliable enough for hobby projects, but somehow, "FTDI" stuck as a name.)

  [1]: https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf


body:
Besides the standard upload button that burns the code using FTDI, I want to then be able to provide custom AVRDude commands for burning fuses, when the external programmer is used.

Is this possible to do from the IDE? Maybe if I can edit some configuration files?

The idea is to have the IDE supply the upload command when the standard upload option is selected, but when `external programmer` is selected, i want to have custom behavior.

The custom behavior that I want is to preserve the EEPROM and set the lock bit.

These two actions can be performed with the following AVRDude commands:

    avrdude -c usbtiny -p m328p -U hfuse:w:0xd2:m
    avrdude -c usbtiny -p m328p -U lock:w:0x00:m

The external programmer i use is Sparkfun's "Pocket AVR Programmer" which is an SPI programmer.

So can I have custom behavior (supported by AVRDude) when I select program using external programmer?

EDIT:
I opened file `boards.txt` and i found these specifications of interest:

    pro.name=Arduino Pro or Pro Mini

    pro.upload.tool=avrdude
    pro.upload.protocol=arduino

    pro.bootloader.tool=avrdude
    pro.bootloader.unlock_bits=0x3F
    pro.bootloader.lock_bits=0x0F

    pro.build.board=AVR_PRO
    pro.build.core=arduino
    pro.build.variant=eightanaloginputs

and

    ## Arduino Pro or Pro Mini (3.3V, 8 MHz) w/ ATmega328P
    ## ---------------------------------------------------
    pro.menu.cpu.8MHzatmega328=ATmega328P (3.3V, 8 MHz)

    pro.menu.cpu.8MHzatmega328.upload.maximum_size=30720
    pro.menu.cpu.8MHzatmega328.upload.maximum_data_size=2048
    pro.menu.cpu.8MHzatmega328.upload.speed=57600

    pro.menu.cpu.8MHzatmega328.bootloader.low_fuses=0xFF
    pro.menu.cpu.8MHzatmega328.bootloader.high_fuses=0xDA
    pro.menu.cpu.8MHzatmega328.bootloader.extended_fuses=0xFD
    pro.menu.cpu.8MHzatmega328.bootloader.file=atmega/ATmegaBOOT_168_atmega328_pro_8MHz.hex

    pro.menu.cpu.8MHzatmega328.build.mcu=atmega328p
    pro.menu.cpu.8MHzatmega328.build.f_cpu=8000000L

I am using Arduino Pro Mini.
In the second specification, there is the option for setting the fuse bits I want. However, there is no option for the lock bits.
The option for the lock bits are in the first specification - but there is no option for the fuses.

My new questions are these:
 1. Should I specify the lock bits in the first specs and the fuses in the second? Will this work? I have to ask before trying anything stupid. Will the second specs "inherit" from the first specs?
 2. Will the parameters I insert here only work for the `Upload Using Programmer` option? I want the regular upload (via bootloader) to work normally.
 3. What happens if I ditch the Arduino platform and use a standalone AVR? If I use the same AVR that the Pro Mini platform had. Will the same settings work?

title: Provide custom AVR dude commands through the Arduino IDE

Answers: 1

body:
You can add the fuse parameters to the "Upload using programmer" command pattern `tools.avrdude.program.pattern` in platform.txt. Copy them from the `tools.avrdude.erase.pattern`. (The fuse values are from boards.txt)

the modified upload command pattern:
> tools.avrdude.program.pattern="{cmd.path}" "-C{config.path}" {program.verbose} {program.verify} -p{build.mcu} -c{protocol} {program.extra_params} "-Uflash:w:{build.path}/{build.project_name}.hex:i" -Ulock:w:{bootloader.lock_bits}:m


body:
I have recently switched to an ArduinoMega2560 (authentic) from the Arduino Uno and have been having a bit of trouble with uploading sketches after the reset button has been pressed a few times. This is the sketch I am using to test:

```
void setup() {
  Serial.begin(115200);
  Serial.println("hello world");
}

void loop() {
  Serial.println("testing");
  delay(1000);
}
```

When I was using the Uno, the sketch would automatically run when the sketch is uploaded. When the reset button is pressed the sketch restarts ("hello world" is printed followed by "testing" every second). I can press the reset button any number of times and the sketch restarts with no issue. This is what I believe to be the expected behavior.

With the Mega however things have been unpredictable. When the sketch is uploaded it sometimes runs but other times not (haven't figured out the pattern if there is one) and after pressing the reset button it sometimes works, sometimes not. I have noticed that after the reset button a few times (3-5 times on average) then the following com-state error occurs:

```
avrdude: Version 6.3-20190619
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2014 Joerg Wunsch

         System wide configuration file is "C:\Users\Crustus\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino17/etc/avrdude.conf"

         Using Port                    : COM3
         Using Programmer              : wiring
         Overriding Baud Rate          : 115200
avrdude: ser_open(): can't set com-state for "\\.\COM3"
avrdude: ser_drain(): read error: The handle is invalid.

avrdude: ser_send(): write error: sorry no info avail
avrdude: stk500_send(): failed to send command to serial port
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: ser_send(): write error: sorry no info avail
avrdude: stk500_send(): failed to send command to serial port
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: ser_send(): write error: sorry no info avail
avrdude: stk500_send(): failed to send command to serial port
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: ser_send(): write error: sorry no info avail
avrdude: stk500_send(): failed to send command to serial port
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: ser_send(): write error: sorry no info avail
avrdude: stk500_send(): failed to send command to serial port
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: ser_send(): write error: sorry no info avail
avrdude: stk500_send(): failed to send command to serial port
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_getsync(): timeout communicating with programmer

avrdude done.  Thank you.

Failed uploading: uploading error: exit status 1
```

If I try upload a sketch again after this it just times out.

Any idea what the issue could be? I have changed COM ports and tried but don't think it is a  COM port issue as the Uno works but perhaps that assumption is wrong.

Does the reset button work differently on the Uno and Mega perhaps?

I am using the ArduinoIDE (2.0.0-rc9.3).I have found a few instances of variations of this issue across the forums but have not found one resolved or relating to the reset button and it working intermittently.

title: ArduinoMega2560 throws avrdude: com-state error after pressing the reset button a few times

Answers: 0


body:
I am new to programming so bear with me.
I am writing a simple code to control a motor such that the motor will turn at full speed as long as the sensor does not detect an object within 5" of the sensor. If it does see something at 5 inches or less, then I want  to motor to stop.
My question is this: When using an IF statement, do you have to have the ELSE, or can you simply do two IF statements with no ELSE?

Here is my example:
______________________________________________________________

    int motorpin1 = 10 , motorpin2 = 11;
    int trig = 12;
    int echo = 9;
    float distance;
    float time;

    void setup()
    {
      pinMode (motorpin1, OUTPUT);
      //yellow wire
      pinMode (motorpin2, OUTPUT);
      //blue wire

      pinMode (trig, OUTPUT);
      pinMode (echo, INPUT);
      Serial.begin (9600);

    }

    void loop()
    {
     // setup ultrasonic sensor to control
     //motor
      digitalWrite(trig, LOW);
      delayMicroseconds(2);
      digitalWrite(trig, HIGH);
      delayMicroseconds(10);
      digitalWrite(trig, LOW);
      time = pulseIn(echo, HIGH);
      distance = time/148.1;

      Serial.println(distance);

     if distance <5,digitalWrite (motorpin1, LOW);
     digitalWrite (motorpin2, LOW);

     if distance >=5, digitalWrite (motorpin1, HIGH);
     digitalWrite (motorpin2, LOW);
     delay (1000); //wait for 1 second

_______________________________________________________________

Is there a better way to do this with an ELSE statement? I want to capture the parameter where the code controls the specific parameters of >5  and then <or=5. Also, my next thing is to pause, and reverse the motor if after 1 second, the sensor still sees an object <=5.

Definitely a learning curve for this old brain of mine!

title: Motor with ultrasonic sensor

Answers: 1

body:
You can do something along the line of

    if (distance < 5) {
        digitalWrite (motorpin1, LOW);
    }
    else {
        digitalWrite (motorpin1, HIGH);
    }

It seems like you only set `motorpin2` to `LOW` and never to `HIGH`. If you don't want to set it `HIGH`, move that line to the `setup()` section. There is no need to keep setting it `LOW`.


body:
I just wrote some code that just sends a string from Arduino to [Processing][1].

Processing prints the string and displays the number of characters in the buffer...
After uploading the sketch to the Arduino and starting Processing for the first time, the serial buffer is initially filled with a few things (it turns out that these are nulls; 0 in ASCII). Why is this happening?

And this **mostly** happens after uploading and starting Processing **for the first time**. When I start Processing for the second time, the buffer is initially free as it should be. I am using a genuine Arduino Uno. I also tested on another Arduino and another laptop, but there is still the same problem. So it should not be a hardware problem.

**Arduino Code**

```
void setup() {
  Serial.begin(9600);
  //delay(1000)
  Serial.println("the quick brown fox jumps over the lazy dog");
  delay(1000);
}

void loop() {
}
```

**Processing Code**

```
import processing.serial.*;
Serial myPort;

void setup() {
  myPort = new Serial(this, "COM3", 9600);
}

void draw() {
  if (myPort.available()>0) {
    println("Buffer:"+myPort.available());
    String string = myPort.readStringUntil('\n');
    if (string!=null) {
      println("String:"+string);
    }
  }
}
```

In the image is other code just to show that the buffer contains nulls.

[![Enter image description here][2]][2]

  [1]: https://en.wikipedia.org/wiki/Processing_(programming_language)
  [2]: https://i.stack.imgur.com/fGa7U.png

title: Arduino filling serial buffer with nulls

Answers: 0


body:
Parameter file containing MQTT topics as shown below, is read into `StaticJsonDocument<1250> DOC` variable.

Size of some groups may differ between MCU's, for example `sub_topics_win` may contain more topics, if MCU is 8 relay unit. For that I need the flexibility to read a specific topic that can differ in size.

What is the rifht way to do it?

    {
        "pub_gen_topics": [
            "myHome/Messages",
            "myHome/log",
            "myHome/debug"
        ],
        "pub_topics": [
            "myHome/Cont_A/Avail",
            "myHome/Cont_A/State"
        ],
        "sub_topics": [
            "myHome/Cont_A",
            "myHome/All",
            "myHome/lockdown"
        ],
        "sub_topics_win": [
            "myHome/Windows/gFloor/TwinWindow",
            "myHome/Windows/gFloor/Pergola"
        ],
        "sub_topics_SW": [
            "myHome/Light/int/gFloor/SalAmbient1",
            "myHome/Light/int/gFloor/SalAmbient2",
            "myHome/Light/int/gFloor/Lobby",
            "myHome/Light/int/gFloor/Corridor"
        ],
        "sub_topics_win_g": [
            "myHome/Windows",
            "myHome/Windows/gFloor"
        ],
        "sub_topics_SW_g": [
            "myHome/Light",
            "myHome/Light/int",
            "myHome/Light/int/gFloor/"
        ],
        "ver": 0.1
    }

title: ArduinoJSON :: How to determine Array's size in a DOC conatinaing not only Arrays

Answers: 2

body:
As I understand, your question is *How can I determine the best capacity for a `JsonDocument` when my input varies?*

If that's the case, I recommend that you read [How to determine the capacity of the JsonDocument?](https://arduinojson.org/v6/how-to/determine-the-capacity-of-the-jsondocument). Here is an extract from the section "What if my input varies?":

> If your program must deserialize a JSON document that changes, you must allocate a `JsonDocument` that is large enough for the largest valid input. I insist on the term *valid* because your program doesn't need to support any JSON document, but only the ones relevant to your use case.

Applying this to your problem, you need to put eight topics in each list and pass this document to the [ArduinoJson Assistant](https://arduinojson.org/v6/assistant/), which results in a recommended capacity of 3027 bytes on ESP8266. Now, this is a bit large for a `StaticJsonDocument`, so consider switching to a `DynamicJsonDocument.`

body:
If your question is *How can I read each element of an array when I don't know its size?*, then simply use a for-loop, like so:

```c++
JsonArray sub_topics_win = doc["sub_topics_win"];

for (const char* topic : pub_gen_topics) {
  Serial.println(topic);
}
```

See also: [JsonArray::begin() / end()](https://arduinojson.org/v6/api/jsonarray/begin_end/), [JsonArray::size()](https://arduinojson.org/v6/api/jsonarray/size/).


body:
I fetch RGB values via I2C - which works (with a splitting function).

Now I have a problem:
- When I write values directly into strip.color() like strip.Color(255,0,0,0) the NeoPixels turn red when receiving the values.
- When I use the values from the I2C connection it won't work anymore. But the values are correct if I have a look in the Serial Monitor.

Maybe the data type is wrong or something?

```
#include <Wire.h>
#include <Adafruit_NeoPixel.h>

#define LED_PIN   4
#define LED_COUNT 4

static const int SLAVE_ADDRESS = 0x08;

uint32_t currentColor;
int currentBrightness = 50;
int flashState = 0;
String ledRed, ledGreen, ledBlue, ledWhite;

String temp;
String payload;

Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRBW + NEO_KHZ800);

void setup() {
  Serial.begin(9600);

  strip.begin();
  strip.show(); // Turn off all pixels asap
  strip.setBrightness(50); // Set brightness

  pinMode(3, OUTPUT);
  digitalWrite(3, HIGH);

  Wire.begin(SLAVE_ADDRESS);
  Wire.onReceive(change);
}

// Set all pixels to color
void setPixelColors(uint32_t color) {
  for(int p = 0; p < LED_COUNT; p++) {
    strip.setPixelColor(p, color);
  }
  strip.show();

  delay(1000);
  digitalWrite(3, HIGH);
}

// Split the I2C message
String split(String s, char parser, int index) {
  String rs="";
  int parserIndex = index;
  int parserCnt=0;
  int rFromIndex=0, rToIndex=-1;
  while (index >= parserCnt) {
    rFromIndex = rToIndex+1;
    rToIndex = s.indexOf(parser,rFromIndex);
    if (index == parserCnt) {
      if (rToIndex == 0 || rToIndex == -1) return "";
      return s.substring(rFromIndex,rToIndex);
    } else parserCnt++;
  }
  return rs;
}

void loop() {
  // ...
}

void change(int howMany) {
  digitalWrite(3, LOW);
  temp = "";
  if (Wire.available()) {
    // Fetch the string
    while(Wire.available()) {
      char c = Wire.read();
      temp.concat(c);
    }

    payload = String(temp);
    flashState = split(payload, ',', 0).toInt();
    ledRed = split(payload, ',', 1);
    ledGreen = split(payload, ',', 2);
    ledBlue = split(payload, ',', 3);
    ledWhite = split(payload, ',', 4);

    byte bufRed[3];
    ledRed.toCharArray(bufRed, 3);

    byte bufGreen[3];
    ledGreen.toCharArray(bufGreen, 3);

    byte bufBlue[3];
    ledBlue.toCharArray(bufBlue, 3);

    byte bufWhite[3];
    ledWhite.toCharArray(bufWhite, 3);

    //setPixelColors(strip.Color(255, 0, 255, 0)); // WORKING

    currentColor = strip.Color(bufRed, bufGreen, bufBlue, bufWhite);
    setPixelColors(currentColor); // NOT WORKING
  }

  // Proof the I2C reading is finished
  delay(10);
}
```

I tried different data types, attached a status LED so I know it the I2C connection is working. When I test it with my UNO I get for R=255 G=0 B=255 W=0; like intended.

"Fun fact": On my UNO it works like a charm. It's just the ATTiny85 that won't accept that values(?)

---

New Code:

```
#include <Wire.h>
#include <Adafruit_NeoPixel.h>

#define LED_PIN   4
#define LED_COUNT 20

static const int SLAVE_ADDRESS = 0x08;

int currentBrightness = 50;
int flashState = 0;
int ledRed, ledGreen, ledBlue, ledWhite;

volatile bool recvFlag = false;
volatile uint32_t currentColor = 0;
String temp;

String payload;

Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRBW + NEO_KHZ800);

void setup() {
  Serial.begin(9600);

  strip.begin();
  strip.show(); // Turn OFF all pixels ASAP
  strip.setBrightness(50); // Set BRIGHTNESS to about 1/5 (max = 255)

  Wire.begin(SLAVE_ADDRESS);
  Wire.onReceive(change);
}

void setPixelColors(uint32_t color) {
  for (int p = 0; p < LED_COUNT; p++) {
    strip.setPixelColor(p, color);
    strip.show();
  }
}

String split(String s, char parser, int index) {
  String rs = "";
  int parserIndex = index;
  int parserCnt = 0;
  int rFromIndex = 0, rToIndex = -1;
  while (index >= parserCnt) {
    rFromIndex = rToIndex + 1;
    rToIndex = s.indexOf(parser, rFromIndex);
    if (index == parserCnt) {
      if (rToIndex == 0 || rToIndex == -1) return "";
      return s.substring(rFromIndex, rToIndex);
    } else parserCnt++;
  }
  return rs;
}

void loop() {
  if (recvFlag) {
    payload = String(temp);
    flashState = split(payload, ',', 0).toInt();
    ledRed = split(payload, ',', 1).toInt();
    ledGreen = split(payload, ',', 2).toInt();
    ledBlue = split(payload, ',', 3).toInt();
    ledWhite = split(payload, ',', 4).toInt();

    currentColor = strip.Color(ledRed, ledGreen, ledBlue, ledWhite);
    setPixelColors(currentColor);

    recvFlag = false;
  }
}

void change(int howMany) {
  temp = "";
  if (Wire.available()) {
    // Fetch the string
    while (Wire.available()) {
      char c = Wire.read();
      temp.concat(c);
    }

    // Proof the I2C reading is finished
    recvFlag = true;
  }
}
```

title: ATTiny84 I2C with NeoPixels not working

Answers: 1

body:
Honestly I don't know, why exactly this works on your Uno. You need to know, that the `onReceive` callback function is called from an ISR (Interrupt Service Routine). And inside an ISR you cannot do things, that rely on interrupts to work (like `delay()`), since only one interrupt can run at a time. I'm not sure, how the Neopixel library works in its core, but its probably not a good idea to run the `show()` method inside an ISR. Also generally you don't want to do long things inside an ISR, since it will block all the other interrupt powered functions of your microcontroller (for example I2C, Serial, time keeping via `delay()` or `millis()`...).

Instead the best practice is to only set a flag and then do these things in the main code (aka in `loop()`). So something like this:

    volatile bool recv_flag = false;
    volatile uint32_t current_color = 0;

    void setup(){
        // Initiating everything like you already did in your code
        ...
    }

    void loop(){
        if(recv_flag){
            setPixelColors(currentColor);
            recv_flag = false;
        }
    }
    void change(int howMany) {
      digitalWrite(3, LOW);
      temp = "";
      if (Wire.available()) {
        // Doing all the data parsing like you already did
        ...
        // save current color in global variable
        currentColor = strip.Color(bufRed, bufGreen, bufBlue, bufWhite);
        // set flag
        recv_flag = true;
      }
    }

Note that every variable, that will be written to inside an ISR should be declared as `volatile`. This prevents the compiler from optimizing it out, since it cannot know when the interrupts will happen. So it might think that this variable will never change and just replace it with a literal. The `volatile` keyword prevents that.

---

As mentioned above I'm even wondering, why your code works on the Uno. Though the main difference between the Uno and the Attiny84 is, that the Uno as a full fledged I2C hardware interface, while the Attiny84 only has an USI (Universal Serial interface). So the Uno has most of the I2C communication implemented in hardware, while the Attiny84 needs to run (probably interrupt based) code to do the communication.


body:
I was trying to use two Arduino Nano connected to two RF24 modules to build a remote control boat. I self-assembled both the remote and the receiver circuit following the skematic suggested in that page (https://arduino.stackexchange.com/questions/85341/nrf24-and-arduino-nano-every-usage).

VCC - 5V (via adapter)

GND - GND

10 pin - CE

A3 - CSN

11 pin - MOSI

12 pin - MISO

13 pin - SCK

not connected - IRQ

(I double and triple checked that I connected all the cables as in the skematic)

Then, as always suggested in the link above, I checked my connection using that sketch:

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

RF24 radio(10,A3);  // for arduino nano every
//RF24 radio(9,10); // for arduino uno

const uint8_t num_channels = 128;
uint8_t values[num_channels];
void setup(void)
{
  Serial.begin(9600);
  printf_begin();
  radio.begin();
  radio.setAutoAck(false);
  radio.startListening();

  radio.printDetails();
  delay(5000);

  radio.stopListening();
  int i = 0;
  while ( i < num_channels )  {
    printf("%x",i>>4);
    ++i;
  }
  printf("\n\r");
  i = 0;
  while ( i < num_channels ) {
    printf("%x",i&0xf);
    ++i;
  }
  printf("\n\r");
}
const int num_reps = 100;

void loop(void)
{
  memset(values,0,sizeof(values));
  int rep_counter = num_reps;
  while (rep_counter--) {
    int i = num_channels;
    while (i--) {
      radio.setChannel(i);
      radio.startListening();
      delayMicroseconds(128);
      radio.stopListening();
      if ( radio.testCarrier() )
        ++values[i];
    }
  }
  int i = 0;
  while ( i < num_channels ) {
    printf("%x",min(0xf,values[i]&0xf));
    ++i;
  }
  printf("\n\r");
}
int serial_putc( char c, FILE * ) {
  Serial.write( c );
  return c;
}

void printf_begin(void) {
  fdevopen( &serial_putc, 0 );
}
```
And that's what I found for the RX:

```
STATUS   = 0xff RX_DR=1 TX_DS=1 MAX_RT=1 RX_P_NO=7 TX_FULL=1
RX_ADDR_P0-1  = 0xffffffffff 0xffffffffff
RX_ADDR_P2-5  = 0xff 0xff 0xff 0xff
TX_ADDR   = 0xffffffffff
RX_PW_P0-6  = 0xff 0xff 0xff 0xff 0xff 0xff
EN_AA   = 0xff
EN_RXADDR  = 0xff
RF_CH   = 0xff
RF_SETUP  = 0xff
CONFIG   = 0xff
DYNPD/FEATURE  = 0xff 0xff
Data Rate  = 1MBPS
Model   = nRF24L01
CRC Length  = 16 bits
PA Power  = PA_MAX
00000000000000001111111111111111222222222222222233333333333333334444444444444444555555555555555566666666666666667777777777777777

0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
```
So that means the RF24 module isn't connected properly to the board, the correct output in the second line would be something like that: RX_ADDR_P0-1 = 0xf0f0f0f0d2 0xc2c2c2c2c2

I used a tester to check the power supply and the antenna receives 3.3V as it should.
I checked also the soldering and I didn't find any poor connections nor short circuits.
I tried all the analog pins between the A0 and A5 for the CSN for perhaps the A3 was not working.

Well, now I ran out of ideas and I'm tempted to think that my radio module is broken, but maybe I overlooked something, can you please write any ideas that you think could help?
Thankyou in advance

title: Is my nrf24l01 radio module broken?

Answers: 0


body:
I am currently sending temperature and humidity readings to a Thingspeak channel via a nodemcu esp8266 wifi module using serial communication between the arduino and esp. I have set the time between sending data to Thingspeak to 30s, however the time stamps I receive on my Thingspeak channel are very inconsistent even though the data has been supposedly sent (ranging from 3 minutes to 15 minutes). I suspect this could be due to some timing error as I receive many deserialization errors when I convert the Json string (deserialize it on the NodeMCU side). Any help would be appreciated! Note, this is only a part of the project, there are multiple relays added, thus using the nodemcu on its own would be insufficient. I have also added some images, which shows the outputs.

Arduino Uno code:

    //Arduino side code
    #include <DHT.h>

    #include <avr/wdt.h>                //Watchdog Timer

    #include <SoftwareSerial.h>         //Arduino to NodeMCU Lib
    #include <ArduinoJson.h>

    SoftwareSerial nodemcu(5, 6);       //Initialise Arduino to NodeMCU (5=Rx & 6=Tx)

    //Initialisation of DHT22 Sensor
    #define DHTPIN 4
    DHT dht(DHTPIN, DHT22);
    float tempC;
    float humidity;
    float VPD;

    void setup() {
      Serial.begin(9600);
      dht.begin();
      nodemcu.begin(9600);
      delay(2000);

      wdt_enable(WDTO_4S);              //Enable Watchdog timer

      Serial.println("Program started");
    }

    void loop() {
      StaticJsonDocument<1000> doc;

      dht22_func();                          //Obtain Temp and Hum data

      doc["humidity"] = humidity;            //Assign collected data to JSON Object
      doc["temperature"] = tempC;
      doc["VPD"] = VPD;

      serializeJson(doc, nodemcu);           //Send data to NodeMCU

      wdt_reset();                           //Reset for WDT
    }

    void dht22_func() {

      humidity = dht.readHumidity();
      tempC = dht.readTemperature();
      Serial.print("Humidity: ");
      Serial.println(humidity);
      Serial.print("Temperature: ");
      Serial.println(tempC);

      if (isnan(humidity) || isnan(tempC) || humidity == 0.0 || tempC == 0.0) {
        while (1) {}
      }
    }

NodeMCU code:

    #include <SoftwareSerial.h>
    #include <ArduinoJson.h>

    #include <ESP8266WiFi.h>
    #include <ThingSpeak.h>

    SoftwareSerial nodemcu(D6, D5);                 //D6 = Rx & D5 = Tx

    unsigned long previousMillis = 0;
    unsigned long currentMillis;
    const unsigned long period = 10000;             //Upload interval in ms

    float tempC;
    float humidity;
    float VPD;

    String apiKey = "";             //Write API key

    unsigned long channelID = ;              //Thingspeak channel ID
    const char *ssid =  "";             //Local network ssid
    const char *pass =  "";                 //Local network password
    const char* server = "api.thingspeak.com";      //Thingspeak server

    boolean state1 = false;                         //Boolean variables
    boolean state2 = false;

    WiFiClient client;

    void setup() {
      Serial.begin(9600);
      nodemcu.begin(9600);
      ThingSpeak.begin(client);
      while (!Serial) continue;
      delay(2000);

      Serial.println("Program Started");

      wifi_connect();                                      //Establish wifi connection
    }

    void loop() {
      currentMillis = millis();                                  //Get current time

      if ((currentMillis - previousMillis >= period)) {

        if (WiFi.status() != WL_CONNECTED) {                    //Check if connected to wifi, else
    connect
          wifi_connect();
    }
    else {
      Serial.println("Currently Connected to WiFi");
    }

    while (state1 == false) {                                //Connect to Thingspeak and push data

      while (state2 == false) {
        parseJsonObject();
      }

      cloud_connect();
    }

    state1 = false;
    state2 = false;
    Serial.println("Cloud Connect Succesful");
    Serial.println("-----------------------------------------");
    previousMillis = previousMillis + period;                     //Update counter
      }
    }

    void wifi_connect() {
      Serial.println("Connecting to ");
      Serial.println(ssid);

      WiFi.begin(ssid, pass);

      while (WiFi.status() != WL_CONNECTED)
      {
        delay(500);
        Serial.print(".");
      }
      Serial.println("");
      Serial.println("WiFi Connected");
    }

    void cloud_connect() {
      if (client.connect(server, 80)) {           //80 is the standard port number used for web access
        String postStr = apiKey;
        postStr += "&field1=";
        postStr += String(tempC);
        postStr += "&field2=";
        postStr += String(humidity);
        postStr += "\r\n\r\n";

        client.print("POST /update HTTP/1.1\n");
        client.print("Host: api.thingspeak.com\n");
        client.print("Connection: close\n");
        client.print("X-THINGSPEAKAPIKEY: " + apiKey + "\n");
        client.print("Content-Type: application/x-www-form-urlencoded\n");
        client.print("Content-Length: ");
        client.print(postStr.length());
        client.print("\n\n");
        client.print(postStr);

        Serial.print("Temperature: ");
        Serial.print(tempC);
        Serial.print(" || Humidity: ");
        Serial.println(humidiy);
        Serial.println("Sent to Thingspeak");

        //Change state to true to break while loop
      state1 = true;
      }
      client.stop();
    }

    void parseJsonObject() {
      //Parse JSON object from serial port
      StaticJsonDocument<1000> doc;
      DeserializationError error = deserializeJson(doc, nodemcu);

      // Test if parsing succeeds
      if (error) {
        Serial.println("deserializeJson error");
        return;
      }

      //Parse Json values and store in variable
      humidity = doc["humidity"];
      tempC = doc["temperature"];

      if (isnan(humidity) || isnan(tempC) || humidity == 0.0 || tempC == 0.0) {
        Serial.println("Invalid Sensor Readings");
        return;
      }

      state2 = true;
      Serial.println("JSON Object Recieved");
    }

[![Serial Monitor Output][1]][1]

[![Thingspeak Result][2]][2]

  [1]: https://i.stack.imgur.com/QHOWY.png
  [2]: https://i.stack.imgur.com/LHQmD.png

title: Deserialization error arduino uno and nodemcu esp8266 to Thingspeak

Answers: 0


body:
I am working on a project using the WSB2812B LED strip, with a ATmega644A using the MCUdude/MightyCore plug in (https://github.com/MCUdude/MightyCore).

I am using Fastled 3.3.3 with Ardunio 1.8.13 on Windows 10 and is using code based on "ColourWavesWithPalettes" (https://gist.github.com/kriegsman/8281905786e8b2632aeb).

This project as 2 button inputs  `Solid` & `Palette` and 2 outputs, `LED DI` & `Mosfet gate`. With the sequence being the following:

1. Power on and start running a set of colour palettes with fade (STANDARD_COLOUR_PALETTE). This could be anything from 5-15 colours, with transitioning colours from red to green to blue to purple to yellow... etc.

2. If `Palette` button is pressed, then change state to run 1 colour palette with fade (SINGLE_COLOUR_PALETTE) on repeat. E.G just purple with fade.

3. While in SINGLE_COLOUR_PALETTE state, if `Palette` button is pressed then change colour to another 1 colour palette e.g blue but still in the SINGLE_COLOUR_PALETTE state.

4. If in either "STANDARD_COLOUR_PALETTE" or "SINGLE_COLOUR_PALETTE" state and `Solid` button is pressed, then change state to run 1 solid colour (SOLID_COLOUR) e.g just blue with no fade.

5. While in "STANDARD_COLOUR_PALETTE" if `Solid` button is pressed, then change to another solid colour e.g Red with no fade.

6. While in "STANDARD_COLOUR_PALETTE" if `Palette` button is pressed then change state to colour palettes with fade (STANDARD_COLOUR_PALETTE).

In summary, the code is made up of 3 states with `for` loops and `if` statements. I have most of this sequence working but I am struggling a lot with step 2 & 3, as there is only 1 colour palette "Playlist" that I am trying to use as STANDARD_COLOUR_PALETTE but also trying to pull indivduial colour palettes from (SINGLE_COLOUR_PALETT).

One solution I thought of was to generate multiple separate a colour playlists one with the 5-15 colours that would fade to one another and many more that would just have the single colour palette.

How to code that into the exiting "ColourWavesWithPalettes" I used as a base?

```lang-cpp

#include "FastLED.h"
#if FASTLED_VERSION < 3001000
#error "Requires FastLED 3.1 or later; check github for latest code."
#endif

#define DATA_PIN    16
#define LED_TYPE    WS2812B
#define COLOR_ORDER GRB
#define NUM_LEDS    276
#define BRIGHTNESS  250
#define SECONDS_PER_PALETTE 10 // ten seconds per color palette makes a good demo but 20-120 is better for deployment
CRGB leds[NUM_LEDS];

enum State{STANDARD_COLOUR_PALETTE, SINGLE_COLOUR_PALETTE, SOLID_COLOUR};
uint8_t State = STANDARD_COLOUR_PALETTE;
int SOLID_COLOUR_POSITION;
int SOLID_COLOUR_COUNT;
int SINGLE_COLOUR_PALETTE_COUNT;

// ten seconds per color palette makes a good demo
// 20-120 is better for deployment
#define SECONDS_PER_PALETTE 10

void setup() {
  delay(1000); // 1 second delay for recovery
  pinMode(14, INPUT); // pin #14 Solid
  pinMode(13, INPUT); // pin #13 Palette Colour
  pinMode(17, OUTPUT); // Pin #17 MOSFET gate
  digitalWrite(17,HIGH);

  // tell FastLED about the LED strip configuration
  FastLED.addLeds<LED_TYPE,DATA_PIN,COLOR_ORDER>(leds, NUM_LEDS)
    //.setCorrection(TypicalLEDStrip) // cpt-city palettes have different color balance //TEST THIS!!!!!!
    .setDither(BRIGHTNESS < 255);

  // set master brightness control
  FastLED.setBrightness(BRIGHTNESS);
}

// Forward declarations of an array of cpt-city gradient palettes, and
// a count of how many there are.  The actual color palette definitions
// are at the bottom of this file.
extern const TProgmemRGBGradientPalettePtr gGradientPalettes[];
extern const uint8_t gGradientPaletteCount;

// Current palette number from the 'playlist' of color palettes
uint8_t gCurrentPaletteNumber = 0;

CRGBPalette16 gCurrentPalette( CRGB::Black);
CRGBPalette16 gTargetPalette( gGradientPalettes[0] );
CRGBPalette16 gTargetPalette1( gGradientPalettes[0] );

void loop()
{

  switch (State)
  {
    case STANDARD_COLOUR_PALETTE:
        EVERY_N_SECONDS( SECONDS_PER_PALETTE ) {
        gCurrentPaletteNumber = addmod8( gCurrentPaletteNumber, 1, gGradientPaletteCount);
        gTargetPalette = gGradientPalettes[ gCurrentPaletteNumber ];
        }

        EVERY_N_MILLISECONDS(40) {
        nblendPaletteTowardPalette( gCurrentPalette, gTargetPalette, 16);
        }

        colorwaves( leds, NUM_LEDS, gCurrentPalette);

        FastLED.show();
        FastLED.delay(20);

        if (digitalRead(13)==HIGH) // Colour palette pressed
        {
          delay(400);
          State = SINGLE_COLOUR_PALETTE; // Change state to single colour palettes

        }

        if (digitalRead(14)==HIGH) // Solid colour button pressed
        {
          delay(400);
          State = SOLID_COLOUR; // Change state to solid colours
          SINGLE_COLOUR_PALETTE_COUNT =++SINGLE_COLOUR_PALETTE_COUNT;
        }
    break; //End STANDARD_COLOUR_PALETTE

    case SINGLE_COLOUR_PALETTE:
//        if (SINGLE_COLOUR_PALETTE_COUNT==1)
//        {
//        EVERY_N_SECONDS( SECONDS_PER_PALETTE ) {
//        gCurrentPaletteNumber = addmod8( gCurrentPaletteNumber, 1, gGradientPaletteCount);
//        gTargetPalette1 = gGradientPalettes[ gCurrentPaletteNumber ];
//        }
//
//        EVERY_N_MILLISECONDS(40) {
//        nblendPaletteTowardPalette( gCurrentPalette, gTargetPalette1, 16);
//        }
//
//        colorwaves( leds, NUM_LEDS, gCurrentPalette);
//
//        FastLED.show();
//        FastLED.delay(20);
//        }

        if (digitalRead(14)==HIGH) // Solid colour button pressed
        {
          delay(400);
          State = SOLID_COLOUR; // Change state to solid colours
          SINGLE_COLOUR_PALETTE_COUNT =++SINGLE_COLOUR_PALETTE_COUNT;
        }
//
//        if (SOLID_COLOUR_COUNT==1)
//        {
//          for (int i = 0; i < NUM_LEDS; i++)
//          {
//            leds[i].setRGB(255, 255, 0);
//          }
//        }
//
//        if(digitalRead(14)==HIGH)
//        {
//          delay(100);
//          SOLID_COLOUR_COUNT=++SOLID_COLOUR_COUNT;
//        }
//        FastLED.show();
//        FastLED.delay(20);
//    break; //End SINGLE_COLOUR_PALETTE

    case SOLID_COLOUR:
         if (SOLID_COLOUR_COUNT==1)
        {
          for (int i = 0; i < NUM_LEDS; i++)
          {
            leds[i].setRGB(255, 0, 0);
          }
        }

        if (SOLID_COLOUR_COUNT==2)
        {
          for (int i = 0; i < NUM_LEDS; i++)
          {
            leds[i].setRGB(0, 255, 0);
          }
        }
        FastLED.show();
        FastLED.delay(20);

        if(digitalRead(14)==HIGH)
        {
          delay(400);
          SOLID_COLOUR_COUNT=++SOLID_COLOUR_COUNT;
        }

        if(digitalRead(13)==HIGH)
        {
          delay(400);
          SOLID_COLOUR_COUNT=0;
          State = STANDARD_COLOUR_PALETTE;
        }

    break; // End SOLID_COLOUR
    }// switch end

} // Main end

// This function draws color waves with an ever-changing,
// widely-varying set of parameters, using a color palette.
void colorwaves( CRGB* ledarray, uint16_t numleds, CRGBPalette16& palette)
{
  static uint16_t sPseudotime = 0;
  static uint16_t sLastMillis = 0;
  static uint16_t sHue16 = 0;

  uint8_t sat8 = beatsin88( 87, 220, 250);
  uint8_t brightdepth = beatsin88( 341, 96, 224);
  uint16_t brightnessthetainc16 = beatsin88( 203, (25 * 256), (40 * 256));
  uint8_t msmultiplier = beatsin88(147, 23, 60);

  uint16_t hue16 = sHue16;//gHue * 256;
  uint16_t hueinc16 = beatsin88(113, 300, 1500);

  uint16_t ms = millis();
  uint16_t deltams = ms - sLastMillis ;
  sLastMillis  = ms;
  sPseudotime += deltams * msmultiplier;
  sHue16 += deltams * beatsin88( 400, 5,9);
  uint16_t brightnesstheta16 = sPseudotime;

  for( uint16_t i = 0 ; i < numleds; i++) {
    hue16 += hueinc16;
    uint8_t hue8 = hue16 / 256;
    uint16_t h16_128 = hue16 >> 7;
    if( h16_128 & 0x100) {
      hue8 = 255 - (h16_128 >> 1);
    } else {
      hue8 = h16_128 >> 1;
    }

    brightnesstheta16  += brightnessthetainc16;
    uint16_t b16 = sin16( brightnesstheta16  ) + 32768;

    uint16_t bri16 = (uint32_t)((uint32_t)b16 * (uint32_t)b16) / 65536;
    uint8_t bri8 = (uint32_t)(((uint32_t)bri16) * brightdepth) / 65536;
    bri8 += (255 - brightdepth);

    uint8_t index = hue8;
    //index = triwave8( index);
    index = scale8( index, 240);

    CRGB newcolor = ColorFromPalette( palette, index, bri8);

    uint16_t pixelnumber = i;
    pixelnumber = (numleds-1) - pixelnumber;

    nblend( ledarray[pixelnumber], newcolor, 128);
  }
}

// Alternate rendering function just scrolls the current palette
// across the defined LED strip.
void palettetest( CRGB* ledarray, uint16_t numleds, const CRGBPalette16& gCurrentPalette)
{
  static uint8_t startindex = 0;
  startindex--;
  fill_palette( ledarray, numleds, startindex, (256 / NUM_LEDS) + 1, gCurrentPalette, 255, LINEARBLEND);
}

// Gradient palette "yellow_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/h5/tn/yellow.png.index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 8 bytes of program space.

DEFINE_GRADIENT_PALETTE( yellow_gp ) {
    0, 255,255,255,
  255, 255,255,  0};

  // Gradient palette "RK_Yellow_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/lb/mp/tn/RK_Yellow.png.index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 12 bytes of program space.

DEFINE_GRADIENT_PALETTE( RK_Yellow_gp ) {
    0, 239,147,  0,
  155, 247,180,  1,
  255, 252,215,  1};

  // Gradient palette "blues_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/ocal/tn/blues.png.index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 32 bytes of program space.

DEFINE_GRADIENT_PALETTE( blues_gp ) { //Blue
    0,   0,  0, 45,
   25,   0,  0,125,
   51,   0,  0,255,
   76,   7, 12,255,
  127,   7, 55,255,
  178,   0,138,255,
  242,   0,255,255,
  255, 255,255,255};

  // Gradient palette "bhw1_33_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/bhw/bhw1/tn/bhw1_33.png.index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 16 bytes of program space.

DEFINE_GRADIENT_PALETTE( bhw1_33_gp ) { //Purple
    0,   2,  1,  8,
   94,  79,  2,212,
  140, 110, 11,197,
  255,   2,  1,  8};

// Gradient palette "Fuschia_8_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/ds/fuschia/tn/Fuschia-8.png.index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 12 bytes of program space.

DEFINE_GRADIENT_PALETTE( Fuschia_8_gp ) {//Purple
    0,  44,  4,214,
  127, 123,  1,233,
  255, 255,  0,255};

// Gradient palette "Blue_Green_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/ggr/tn/Blue_Green.png.index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 20 bytes of program space.

DEFINE_GRADIENT_PALETTE( Blue_Green_gp ) { //Light blue to green
    0,   0, 51,255,
   34,   1,111,255,
  144,   9,195,255,
  234,   1,225,153,
  255,   0,255, 80};

// Gradient palette "Green_3D_1_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/sd/tn/Green-3D_1.png.index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 28 bytes of program space.

DEFINE_GRADIENT_PALETTE( Green_3D_1_gp ) {
    0, 103,186,106,
   42,  45,147, 48,
   84,  13,114, 14,
  127,   2, 87,  2,
  170,   0, 66,  0,
  212,   0, 23,  0,
  255,   0,  3,  0};

// Gradient palette "Mexican_flag_smooth_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/ggr/tn/Mexican_flag_smooth.png.index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 20 bytes of program space.

DEFINE_GRADIENT_PALETTE( Mexican_flag_smooth_gp ) {
    0,   0,255,  0,
   63,  42,255, 45,
  127, 255,255,255,
  191, 255, 55, 45,
  255, 255,  0,  0};

 // Gradient palette "Fire_2_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/ds/icons/tn/Fire-2.png.index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 12 bytes of program space.

DEFINE_GRADIENT_PALETTE( Fire_2_gp ) { //Red
    0, 255,255,  0,
  127, 255, 55,  0,
  255, 255,  0,  0};

  // Gradient palette "Orange_3D_1_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/sd/tn/Orange-3D_1.png.index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 12 bytes of program space.

DEFINE_GRADIENT_PALETTE( Orange_3D_1_gp ) {// Orange
    0, 255,111, 11,
  127, 255, 92,  2,
  255, 255, 74,  1};

  // Gradient palette "bhw2_grrrrr_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/bhw/bhw2/tn/bhw2_grrrrr.png.index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 32 bytes of program space.

DEFINE_GRADIENT_PALETTE( bhw2_grrrrr_gp ) {
    0, 184, 15,155,
   35,  78, 46,168,
   84,  65,169,230,
  130,   9,127,186,
  163,  77,182,109,
  191, 242,246, 55,
  216, 142,128,103,
  255,  72, 50,168};

// Gradient palette "es_skywalker_12_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/es/skywalker/tn/es_skywalker_12.png.index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 16 bytes of program space.

DEFINE_GRADIENT_PALETTE( es_skywalker_12_gp ) { // Blue
    0,  92,175,255,
   61,  20,100,255,
  153,   1, 10,170,
  255,   0,  1, 29};

// Gradient palette "es_candide_26_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/es/candide/tn/es_candide_26.png.index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 24 bytes of program space.

DEFINE_GRADIENT_PALETTE( es_candide_26_gp ) { //Purple
    0, 104, 10,245,
   89, 155,  0,245,
  165, 249,  2,242,
  208, 249, 51,247,
  249, 247,180,250,
  255, 247,180,250};

// Gradient palette "cool_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/h5/tn/cool.png.index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 8 bytes of program space.

DEFINE_GRADIENT_PALETTE( cool_gp ) { // Blue to purple
    0,   0,255,255,
  255, 255,  0,255};

// Gradient palette "green_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/h5/tn/green.png.index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 8 bytes of program space.

DEFINE_GRADIENT_PALETTE( green_gp ) {
    0, 255,255,255,
  255,   0,255,  0};

// Gradient palette "Pink_3D_2_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/sd/tn/Pink-3D_2.png.index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 12 bytes of program space.

DEFINE_GRADIENT_PALETTE( Pink_3D_2_gp ) { //Pink
    0, 244, 58,242,
  127, 222, 29,226,
  255, 201, 10,210};

// Gradient palette "GoldSunset_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/nd/atmospheric/tn/GoldSunset.png.index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 36 bytes of program space.

DEFINE_GRADIENT_PALETTE( GoldSunset_gp ) { //Yellow and Orange
    0, 229,118,  0,
   41, 227,101,  0,
   82, 224, 86,  0,
  118, 163, 42,  0,
  124, 113, 15,  0,
  129, 167, 68,  2,
  138, 237,164, 16,
  191, 232,139,  2,
  255, 229,118,  0};

// Gradient palette "Sunset_Real_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/nd/atmospheric/tn/Sunset_Real.png.index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 28 bytes of program space.

DEFINE_GRADIENT_PALETTE( Sunset_Real_gp ) { //Orange and blue
    0, 120,  0,  0,
   22, 179, 22,  0,
   51, 255,104,  0,
   85, 167, 22, 18,
  135, 100,  0,103,
  198,  16,  0,130,
  255,   0,  0,160};

// Gradient palette "Blue_Magenta_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/nd/basic/tn/Blue_Magenta.png.index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 12 bytes of program space.

DEFINE_GRADIENT_PALETTE( Blue_Magenta_gp ) { //Blue purple
    0,   0,  0,255,
  127,  42,  0,255,
  255, 255,  0,255};

// Gradient palette "Red_Yellow_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/nd/basic/tn/Red_Yellow.png.index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 12 bytes of program space.

DEFINE_GRADIENT_PALETTE( Red_Yellow_gp ) { //Red to yellow
    0, 255,  0,  0,
  127, 255, 55,  0,
  255, 255,255,  0};

// Gradient palette "Yellow_White_Magenta_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/nd/basic/tn/Yellow_White_Magenta.png.index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 20 bytes of program space.

DEFINE_GRADIENT_PALETTE( Yellow_White_Magenta_gp ) { //Yellow to white
    0, 255,255,  0,
   63, 255,255, 45,
  127, 255,255,255,
  191, 255, 55,255,
  255, 255,  0,255};

// Gradient palette "White_Cyan_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/nd/basic/tn/White_Cyan.png.index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 12 bytes of program space.

DEFINE_GRADIENT_PALETTE( White_Cyan_gp ) { //White to light blue
    0, 255,255,255,
  127,  42,255,255,
  255,   0,255,255};

// Gradient palette "Magenta_White_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/nd/basic/tn/Magenta_White.png.index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 12 bytes of program space.

DEFINE_GRADIENT_PALETTE( Magenta_White_gp ) { //Purple to white
    0, 255,  0,255,
  127, 255, 55,255,
  255, 255,255,255};

// Gradient palette "Magenta_Cyan_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/nd/basic/tn/Magenta_Cyan.png.index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 12 bytes of program space.

DEFINE_GRADIENT_PALETTE( Magenta_Cyan_gp ) { //purple to light blue
    0, 255,  0,255,
  127,  42, 55,255,
  255,   0,255,255};

  // Gradient palette "Green_Cyan_Blue_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/nd/basic/tn/Green_Cyan_Blue.png.index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 20 bytes of program space.

DEFINE_GRADIENT_PALETTE( Green_Cyan_Blue_gp ) { //Greent to light blue
    0,   0,255,  0,
   63,   0,255, 45,
  127,   0,255,255,
  191,   0, 55,255,
  255,   0,  0,255};

// Gradient palette "rhubarb_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/ocal/tn/rhubarb.png.index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 20 bytes of program space.

DEFINE_GRADIENT_PALETTE( rhubarb_gp ) { //purple to red
    0, 255, 55, 45,
   76, 255,  0,  0,
  127, 188, 12, 45,
  191, 255,  0,  0,
  255, 188, 12, 45};

// Gradient palette "YlGnBu_09_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/cb/seq/tn/YlGnBu_09.png.index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 72 bytes of program space.

DEFINE_GRADIENT_PALETTE( YlGnBu_09_gp ) { //Blue
    0, 255,255,170,
   28, 255,255,170,
   28, 210,239,102,
   56, 210,239,102,
   56, 133,209,106,
   84, 133,209,106,
   84,  41,157,117,
  113,  41,157,117,
  113,   7,121,132,
  141,   7,121,132,
  141,   1, 73,125,
  170,   1, 73,125,
  170,   1, 28, 89,
  198,   1, 28, 89,
  198,   1,  7, 65,
  226,   1,  7, 65,
  226,   1,  2, 17,
  255,   1,  2, 17};

  // Gradient palette "Oranges_09_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/cb/seq/tn/Oranges_09.png.index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 72 bytes of program space.

DEFINE_GRADIENT_PALETTE( Oranges_09_gp ) { //Orange
    0, 255,233,207,
   28, 255,233,207,
   28, 252,203,149,
   56, 252,203,149,
   56, 249,162, 82,
   84, 249,162, 82,
   84, 249,109, 29,
  113, 249,109, 29,
  113, 249, 69,  6,
  141, 249, 69,  6,
  141, 220, 36,  1,
  170, 220, 36,  1,
  170, 167, 15,  1,
  198, 167, 15,  1,
  198,  83,  8,  1,
  226,  83,  8,  1,
  226,  41,  4,  1,
  255,  41,  4,  1};

// Gradient palette "bhw1_28_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/bhw/bhw1/tn/bhw1_28.png.index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 32 bytes of program space.

DEFINE_GRADIENT_PALETTE( bhw1_28_gp ) {// Purple blue purple
    0,  75,  1,221,
   30, 252, 73,255,
   48, 169,  0,242,
  119,   0,149,242,
  170,  43,  0,242,
  206, 252, 73,255,
  232,  78, 12,214,
  255,   0,149,242};

  // Gradient palette "bhw2_10_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/bhw/bhw2/tn/bhw2_10.png.index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 28 bytes of program space.

DEFINE_GRADIENT_PALETTE( bhw2_10_gp ) { //Dark green to light green
    0,   0, 12,  0,
   61, 153,239,112,
  127,   0, 12,  0,
  165, 106,239,  2,
  196, 167,229, 71,
  229, 106,239,  2,
  255,   0, 12,  0};
// Gradient palette "bhw2_11_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/bhw/bhw2/tn/bhw2_11.png.index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 20 bytes of program space.

DEFINE_GRADIENT_PALETTE( bhw2_11_gp ) { //Dark grren and blue mixed
    0,   0, 12,  8,
   79,   0, 55, 45,
  130,   0,136,125,
  183,   0, 55, 45,
  255,   0, 12,  8};

// Gradient palette "bhw3_01_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/bhw/bhw3/tn/bhw3_01.png.index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 52 bytes of program space.

DEFINE_GRADIENT_PALETTE( bhw3_01_gp ) { //Pink, to blue, to red, to yellow
    0, 255,146,228,
   25, 152, 43, 65,
   48,  36, 17, 22,
   72,   8, 34, 75,
   81,   1, 58,170,
  104,  42, 49,245,
  124,  15, 15, 95,
  150,   1,  8, 39,
  175,  98, 32, 35,
  204, 123,  9,  2,
  219, 220, 15,  2,
  237, 255, 93,  6,
  255, 244,244,  0};

   // Gradient palette "Deep_Sea_gp", originally from
// http://soliton.vm.bytemark.co.uk/pub/cpt-city/ggr/tn/Deep_Sea.png.index.html
// converted for FastLED with gammas (2.6, 2.2, 2.5)
// Size: 20 bytes of program space.

DEFINE_GRADIENT_PALETTE( Deep_Sea_gp ) { //Dark blue
    0,   0,  1,  2,
  148,   1,  7, 24,
  194,   2, 31, 77,
  226,   1,108,144,
  255,   0,237,235};

// Single array of defined cpt-city color palettes.
// This will let us programmatically choose one based on
// a number, rather than having to activate each explicitly
// by name every time.
// Since it is const, this array could also be moved
// into PROGMEM to save SRAM, but for simplicity of illustration
// we'll keep it in a regular SRAM array.
//
// This list of color palettes acts as a "playlist"; you can
// add or delete, or re-arrange as you wish.
const TProgmemRGBGradientPalettePtr gGradientPalettes[] = {
  GoldSunset_gp,
  //Green_3D_1_gp,
  //GoldSunset_gp,
  //bhw1_33_gp,
  //bhw1_33_gp,
  //bhw1_33_gp,
  //bhw1_33_gp,
  //Green_3D_1_gp,
  //Fire_2_gp,
  yellow_gp,
  RK_Yellow_gp,
  //yellow_gp,
  //yellow_gp,
  //blues_gp,
  //blues_gp,
  //bhw1_33_gp,
  //bhw1_33_gp,
  //bhw1_33_gp,
 Fuschia_8_gp,
  //Blue_Green_gp,
  //Blue_Green_gp,
  //Fire_2_gp,
  //Green_Cyan_Blue_gp,
  //Green_Cyan_Blue_gp,
 //Green_Cyan_Blue_gp,
  //Green_Cyan_Blue_gp,
  //Green_Cyan_Blue_gp,
  //Green_Cyan_Blue_gp,
  //Green_3D_1_gp,
  //Green_3D_1_gp,
  //Mexican_flag_smooth_gp,
  //Mexican_flag_smooth_gp,
  //Fire_2_gp,
  //Fire_2_gp,
  //bhw1_33_gp,
  //es_skywalker_12_gp,
  //Fire_2_gp,
  //es_skywalker_12_gp,
  //es_skywalker_12_gp,
  //Orange_3D_1_gp,
  //Orange_3D_1_gp,
  //bhw2_grrrrr_gp,
  //es_candide_26_gp,
  //cool_gp,
  //cool_gp,
  //green_gp,
  //green_gp,
  //Pink_3D_2_gp,
  //Pink_3D_2_gp,
  //GoldSunset_gp,
  //Green_Cyan_Blue_gp,
  //Sunset_Real_gp,
  //Blue_Magenta_gp,
  //Blue_Magenta_gp,
  //Red_Yellow_gp,
  //Red_Yellow_gp,
  //Yellow_White_Magenta_gp,
  //White_Cyan_gp,
  //White_Cyan_gp,
  //Magenta_White_gp,
  //Magenta_White_gp,
  //Magenta_Cyan_gp,
  //Magenta_Cyan_gp,
  //Green_Cyan_Blue_gp,
  //Green_Cyan_Blue_gp,
  //rhubarb_gp,
  //YlGnBu_09_gp,
  //Oranges_09_gp,
  //bhw1_28_gp,
  //bhw2_10_gp,
  //bhw2_11_gp,
  //bhw3_01_gp,
  //Sunset_Real_gp,
  Sunset_Real_gp,
 };
//
// const TProgmemRGBGradientPalettePtr gGradientPalettes[] = {
// Fuschia_8_gp,
// };

// Count of how many cpt-city gradients are defined:
const uint8_t gGradientPaletteCount =
  sizeof( gGradientPalettes) / sizeof( TProgmemRGBGradientPalettePtr );
```

title: Coding issue with Fast LED Multiple Colour Palettes in a State Machine

Answers: 0


body:
Is it possible to rename, e.g., [cu.usbserial-1410][1] to something else?

I have to connect multiple Arduino's and right now the order is rather important.
Being able to set a fixed name would help a lot.

  [1]: https://stackoverflow.com/questions/8632586/macos-whats-the-difference-between-dev-tty-and-dev-cu

title: Rename cu.usbserial-1410 on macOS

Answers: 1

body:
### Proposal:

Instead of trying to convince the PC's OS (be it macOS, Windows, or Linux) to use a fixed name for interfaces that connect specific Arduinos, add a identifying feature to your Arduino application. Then from the PC application ask each connected Arduino for its name to identify it.


body:
I have a program where I configure my ESP32 as a server and it sent randomly generated data, the problem is that I can only connect 1 client at a time, what I want is that multiple clients can connect and they all receive the same information,

I put the code that I have in my ESP32 as a server

```
#include <WiFi.h>

const char* ssid = "SSID";
const char* password =  "Password";

char data[9];

WiFiServer wifiServer(80);

void setup() {

  Serial.begin(115200);

  delay(1000);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Conectando a WiFi..");
  }

  Serial.println("Conectado a la red WiFi network");
  Serial.println(WiFi.localIP());

  wifiServer.begin();
}

void loop() {

  WiFiClient client = wifiServer.available();

  if (client) {

    while(client.connected()) {
      //Serial.println("Client Connected");

        data[0] = random(30,50);
        data[1] = random(30,50);
        data[2] = random(30,50);
        data[3] = random(30,50);
        data[4] = random(30,50);
        data[5] = random(30,50);
        data[6] = random(30,50);
        data[7] = random(30,50);
        data[8] = random(30,50);

        client.write(data,9);
        Serial.println(int(data[0]));
        Serial.println(int(data[1]));
        Serial.println(int(data[2]));
        Serial.println(int(data[3]));
        Serial.println(int(data[4]));
        Serial.println(int(data[5]));
        Serial.println(int(data[6]));
        Serial.println(int(data[7]));
        Serial.println(int(data[8]));
        delay(1000);
    }
  }
}
```

I am managing the clients with python
the client code is as follows

```
import socket

sock = socket.socket()

host = "192.168.1.68" #ESP32 IP in local network
port = 80             #ESP32 Server Port

sock.connect((host, port))

data = ""
lista = [0,0,0,0,0,0,0,0,0]
x = 0

while True:

    data = sock.recv(1)
    #x = data.decode()
    #y = x.split("p")
    buffer = int.from_bytes(data,"big")
    lista[x] = buffer
    x = x + 1
    if x >=9:
        print(lista)
        x=0
```

the idea is that all clients have the same code and receive the same data
but it only allows me to connect 1 client at a time

title: ESP32 wifi server with multiple clients

Answers: 0