Podcast #128: We chat with Kent C Dodds about why he loves React and discuss what life was like in the dark days before Git. Listen now.
2 edited body
source | link

in step 8. "build the programmer circuit" R1 2.2K is set on arduino rx pin. Why? Another thing i can't understand is that SoftwareSerial baud rate is set to 3849938400 but BT module baud rate is set 115200 using "AT" command. why?

in step 8. "build the programmer circuit" R1 2.2K is set on arduino rx pin. Why? Another thing i can't understand is that SoftwareSerial baud rate is set to 38499 but BT module baud rate is set 115200 using "AT" command. why?

in step 8. "build the programmer circuit" R1 2.2K is set on arduino rx pin. Why? Another thing i can't understand is that SoftwareSerial baud rate is set to 38400 but BT module baud rate is set 115200 using "AT" command. why?

1
source | link

Uploading over Bluetooth Low Energy - bootloader not responding

I'm working on sketches uploading over BLE. I had to write my own uploader (looking at avrdude sources with one eye) so i can change uploading behaviour as needed and it's working over USB just perfect but it does not get response from bootloader if trying over Bluetooth LE.

My hardware:

  • Arduino Uno (and i'm having Arduino Mega2560)
  • HM-10 BLE module

As HM-10 does not support DTR/RTS i had to add my own software reboot:

In brief: it reads incoming bytes on interrupt event and compares to reset command passed in ble_setup. If it's equal then it uses watchdog timer to reboot the board. If it's not equal it stores byte in byffer, then sketch loop() just returns incoming byes back ("echo").

#include <avr/wdt.h>

const char *ble_reset_cmd;
int ble_reset_index = 0;
int ble_available = 0;       // chars available
int ble_byte;                // income buffer as 1 char
int *ble_bytes = &ble_byte;  // income buffer
boolean delete_ble_bytes = false;

//#define BLE_DEBUG

// reboot Arduino board using Watchdog timer
void reboot() {
//    #ifdef BLE_DEBUG
    Serial.println("rebooting ...");
//    #endif

//    digitalWrite(13, HIGH);
//    delay(2000);

    wdt_enable(WDTO_15MS);
    while(1) { };
}

void ble_setup(int baud, const char *reset_cmd) {
    Serial.begin(baud);
    ble_reset_cmd = reset_cmd;
}

int Serial_available() {
    return ble_available;
}

int Serial_read() {
    if (ble_available < 0)
        return -1;

    int inByte = ble_bytes[--ble_available];
    if (ble_available == 0 && delete_ble_bytes) {
        // restore buffer as 1 char buffer
        delete[] ble_bytes;
        ble_bytes = &ble_byte;
        delete_ble_bytes = false;
    }
    return inByte;
}

void serialEvent() {
    if (Serial.available() <= 0)
        return;

    int inByte = Serial.read();
    if (inByte == ble_reset_cmd[ble_reset_index]) {
        // entered char is cmd character

        if (ble_reset_cmd[++ble_reset_index] == 0)
            reboot();

        #ifdef BLE_DEBUG  
        Serial.write("ble_index = ");
        Serial.print((byte)ble_reset_index);
        Serial.write('\n');
        #endif 

    } else {
        // entered char is NOT cmd character

        if (ble_reset_index > 0) {
            // got character not from cmd, so we should to return characters
            // starting ble_reset_cmd until current index and then this character

            ble_available = ble_reset_index + 1;
            ble_reset_index = 0;

            #ifdef BLE_DEBUG
            Serial.print("Copy ");
            Serial.print((byte)(ble_available - 1));
            Serial.println(" bytes");
            #endif

            // recreate input buffer using cmd characters
            ble_bytes = new int[ble_available + 1];
            delete_ble_bytes = true;
            ble_bytes[0] = inByte;
            for (int i=0; i<(ble_available-1); i++) {
              ble_bytes[i + 1] = ble_reset_cmd[ble_available - i - 2];
            }
            ble_bytes[ble_available] = 0; // null-terminated array

            #ifdef BLE_DEBUG
            Serial.print("input buffer now contains ");
            Serial.print(ble_available);
            Serial.println(" bytes");
            #endif

        } else {

            #ifdef BLE_DEBUG
            Serial.println("ble_index = 0");
            #endif

            // pass inByte next ...
            ble_available++;
            ble_byte = inByte;
        }

    }
} 

// ----------------------------------- 

int led = 13;
int ledHIGH = 0;

void setup() {
  ble_setup(9600, "AT+RESET");
  Serial.print("ready\n");
  pinMode(led, OUTPUT);
}

void loop() {
  while (Serial_available() > 0) {
    int inByte = Serial_read();

//    Serial.write('>');
//    Serial.write(inByte);
//    Serial.write('\n');
    ledHIGH = 1- ledHIGH;
    digitalWrite(led, ledHIGH);
    Serial.write(inByte); // echo
  }
}

As i said it's working good for USB uploading: right after rebooting bootloader waits for upload commands and start to reply:

015-04-07 21:22:10.860 Apploader[11226:303] Apploader v0.1
2015-04-07 21:22:12.772 Apploader[11226:303] DTR/RTS supported by Serial, resetting
2015-04-07 21:22:13.075 Apploader[11226:303] draining ...
2015-04-07 21:22:13.327 Apploader[11226:303] drain done
2015-04-07 21:22:13.328 Apploader[11226:303] Send: 0 [0x30]   [0x20] 
2015-04-07 21:22:13.328 Apploader[11226:303] draining ...
2015-04-07 21:22:13.723 Apploader[11226:303] drain done
2015-04-07 21:22:13.724 Apploader[11226:303] Send: 0 [0x30]   [0x20] 
2015-04-07 21:22:13.724 Apploader[11226:303] draining ...
2015-04-07 21:22:13.977 Apploader[11226:303] drain done
2015-04-07 21:22:13.978 Apploader[11226:303] Send: 0 [0x30]   [0x20] 
2015-04-07 21:22:13.979 Apploader[11226:303] Recv: . [0x14] 
2015-04-07 21:22:13.980 Apploader[11226:303] Recv: . [0x10] 
2015-04-07 21:22:13.980 Apploader[11226:303] Send: A [0x41]  . [0x81]   [0x20] 
2015-04-07 21:22:13.984 Apploader[11226:303] Recv: . [0x14] 
2015-04-07 21:22:13.984 Apploader[11226:303] Recv: . [0x04] 
2015-04-07 21:22:13.985 Apploader[11226:303] Recv: . [0x10] 
2015-04-07 21:22:13.985 Apploader[11226:303] Send: A [0x41]  . [0x82]   [0x20] 
2015-04-07 21:22:13.988 Apploader[11226:303] Recv: . [0x14] 
2015-04-07 21:22:13.988 Apploader[11226:303] Recv: . [0x04] 
2015-04-07 21:22:13.989 Apploader[11226:303] Recv: . [0x10] 
2015-04-07 21:22:13.989 Apploader[11226:303] Send: B [0x42]  . [0x86]  . [0x00]  . [0x01]  . [0x00]  . [0x01]  . [0x01]  . [0x01]  . [0x03]  . [0xff]  . [0xff]  . [0xff]  . [0xff]  . [0x00]  . [0x80]  . [0x04]  . [0x00]  . [0x00]  . [0x00]  . [0x80]  . [0x00]   [0x20] 
2015-04-07 21:22:13.996 Apploader[11226:303] Recv: . [0x14] 
2015-04-07 21:22:13.997 Apploader[11226:303] Recv: . [0x10] 
2015-04-07 21:22:13.997 Apploader[11226:303] Send: E [0x45]  . [0x05]  . [0x04]  . [0xd7]  . [0xc2]  . [0x00]   [0x20] 
2015-04-07 21:22:14.000 Apploader[11226:303] Recv: . [0x14] 
2015-04-07 21:22:14.001 Apploader[11226:303] Recv: . [0x10] 
2015-04-07 21:22:14.003 Apploader[11226:303] Send: P [0x50]   [0x20] 
2015-04-07 21:22:14.004 Apploader[11226:303] Recv: . [0x14] 
2015-04-07 21:22:14.008 Apploader[11226:303] Recv: . [0x10] 

But when trying over BLE bootloader stops listening in 200ms and then launches sketch, i can see sketch setup() started as it prints "ready". Also i can see it actually reboots the board as it sends "rebooting".

015-04-07 21:23:30.287 Apploader[11253:303] Apploader v0.1
2015-04-07 21:23:30.296 Apploader[11253:1503] CBCentralManager state is 5
2015-04-07 21:23:31.297 Apploader[11253:303] BleSerialDevice: open()
2015-04-07 21:23:31.298 Apploader[11253:303] Waiting for peripheral to be discovered ...
2015-04-07 21:23:31.591 Apploader[11253:1503] Found peripheral: <CBPeripheral: 0x100401940 identifier = D92ECAAB-51A5-44D5-8C6C-536CD797867E, Name = "Ardu", state = disconnected>
2015-04-07 21:23:31.593 Apploader[11253:1503] Stop scanning
2015-04-07 21:23:31.595 Apploader[11253:1503] Connecting to <CBPeripheral: 0x100401940 identifier = D92ECAAB-51A5-44D5-8C6C-536CD797867E, Name = "Ardu", state = disconnected>
2015-04-07 21:23:32.025 Apploader[11253:1503] Connected to peripheral <CBPeripheral: 0x100401940 identifier = D92ECAAB-51A5-44D5-8C6C-536CD797867E, Name = "Ardu", state = connected>
2015-04-07 21:23:32.041 Apploader[11253:1503] Discovered services for peripheral <CBPeripheral: 0x100401940 identifier = D92ECAAB-51A5-44D5-8C6C-536CD797867E, Name = "Ardu", state = connected>
2015-04-07 21:23:32.042 Apploader[11253:1503] Discovered service <CBService: 0x103701450>
2015-04-07 21:23:32.043 Apploader[11253:1503] Discovered service <CBService: 0x1037015f0>
2015-04-07 21:23:32.043 Apploader[11253:1503] Discovered service <CBService: 0x103701630>
2015-04-07 21:23:32.044 Apploader[11253:1503] Discovered characteristics for service <CBService: 0x103701630>
2015-04-07 21:23:32.044 Apploader[11253:1503] Discovered characteristic <CBCharacteristic: 0x1037005c0>
2015-04-07 21:23:32.045 Apploader[11253:1503] Subscribed to Rx value
2015-04-07 21:23:32.046 Apploader[11253:303] Connected successfully
2015-04-07 21:23:33.342 Apploader[11253:303] BleSerialDevice: open()
2015-04-07 21:23:33.343 Apploader[11253:303] already connected, exiting
2015-04-07 21:23:33.343 Apploader[11253:303] DTR/RTS supported by Serial, resetting
2015-04-07 21:23:33.594 Apploader[11253:303] Within interval
2015-04-07 21:23:33.595 Apploader[11253:303] Perform reset
2015-04-07 21:23:33.596 Apploader[11253:303] Send: A [0x41] T [0x54] + [0x2b] R [0x52] E [0x45] S [0x53] E [0x45] T [0x54] 
2015-04-07 21:23:33.647 Apploader[11253:303] Skip draining after reset
2015-04-07 21:23:33.648 Apploader[11253:303] Send: 0 [0x30]   [0x20] 
2015-04-07 21:23:33.648 Apploader[11253:303] Draining for 200 ms ...
2015-04-07 21:23:33.649 Apploader[11253:303] Start reading
2015-04-07 21:23:33.712 Apploader[11253:1503] Rx value received 15 bytes: r [0x72] e [0x65] b [0x62] o [0x6f] o [0x6f] t [0x74] i [0x69] n [0x6e] g [0x67]   [0x20] . [0x2e] . [0x2e] . [0x2e] . [0x0d] . [0x0a] 
2015-04-07 21:23:33.713 Apploader[11253:1503] _characterRead = true
2015-04-07 21:23:33.780 Apploader[11253:1503] Rx value received 6 bytes: r [0x72] e [0x65] a [0x61] d [0x64] y [0x79] . [0x0a] 
2015-04-07 21:23:33.780 Apploader[11253:1503] _characterRead = true
2015-04-07 21:23:33.850 Apploader[11253:303] Finish reading
2015-04-07 21:23:33.851 Apploader[11253:303] Drained 21 bytes
2015-04-07 21:23:33.852 Apploader[11253:303] Send: 0 [0x30]   [0x20] 
2015-04-07 21:23:33.853 Apploader[11253:303] Draining for 200 ms ...
2015-04-07 21:23:33.853 Apploader[11253:303] Start reading
2015-04-07 21:23:33.982 Apploader[11253:1503] Rx value received 2 bytes: 0 [0x30]   [0x20] 
2015-04-07 21:23:33.983 Apploader[11253:1503] _characterRead = true
2015-04-07 21:23:34.054 Apploader[11253:303] Finish reading
2015-04-07 21:23:34.055 Apploader[11253:303] Drained 2 bytes
2015-04-07 21:23:34.056 Apploader[11253:303] Send: 0 [0x30]   [0x20] 
2015-04-07 21:23:34.056 Apploader[11253:303] Reading 1 bytes ...
2015-04-07 21:23:34.057 Apploader[11253:303] Start reading
2015-04-07 21:23:34.057 Apploader[11253:303] _characterRead = false
2015-04-07 21:23:34.184 Apploader[11253:1503] Rx value received 1 bytes: . [0x00] 
2015-04-07 21:23:34.185 Apploader[11253:1503] _characterRead = true
2015-04-07 21:23:34.186 Apploader[11253:303] Finish reading
2015-04-07 21:23:34.186 Apploader[11253:1503] Rx value received 2 bytes: 0 [0x30]   [0x20] 
2015-04-07 21:23:34.186 Apploader[11253:1503] _characterRead = true
2015-04-07 21:23:34.186 Apploader[11253:303] Recv: . [0x00] 
2015-04-07 21:23:34.187 Apploader[11253:303] stk500_getsync() attempt 1 of 5: not in sync: resp=0x00

Once again - bootloader stops listening in 200 ms instead of 1-1.5 secons as over USB:

2015-04-07 21:23:33.596 Apploader[11253:303] Send: A [0x41] T [0x54] + [0x2b] R [0x52] E [0x45] S [0x53] E [0x45] T [0x54] 
...
2015-04-07 21:23:33.780 Apploader[11253:1503] Rx value received 6 bytes: r [0x72] e [0x65] a [0x61] d [0x64] y [0x79] . [0x0a]

I expect bootloader to reply with 0x14 0x10 as over USB:

2015-04-07 21:22:13.978 Apploader[11226:303] Send: 0 [0x30]   [0x20] 
2015-04-07 21:22:13.979 Apploader[11226:303] Recv: . [0x14] 
2015-04-07 21:22:13.980 Apploader[11226:303] Recv: . [0x10] 

As you can see later communication over Bluetooth is working good, as i receive exactly what was sent (0x30 0x20)

So when sketch is launched it's ok.

My ideas what's wrong:

  1. baud rate

Since serial.begin(N) is invoked after bootloader stops and launch sketch bootloader by default uses another baud rate? Is it correct? HM-10 default daud rate is 9600 and in sketch i also use 9600.

  1. wrong wire connection?

Bluetooth-arduino: rx -> tx tx -> rx Since its working for sketch i believe it's ok. Do i need any capacitors or resistors?

Any thoughts are highly appreciated!

UPDATE:

It seems i've found Uno bootloader source code and bootloader baud rate is 19200 by default

/* set the UART baud rate */
/* 20060803: hacked by DojoCorp */
//#define BAUD_RATE   115200
#ifndef BAUD_RATE
#define BAUD_RATE   19200
#endif

UPDATE2:

I'm in stuck as in this tutorial 115200 is used: http://makezine.com/projects/diy-arduino-bluetooth-programming-shield/

in step 8. "build the programmer circuit" R1 2.2K is set on arduino rx pin. Why? Another thing i can't understand is that SoftwareSerial baud rate is set to 38499 but BT module baud rate is set 115200 using "AT" command. why?