title: OTA-program SPIFFS on the ESP8266

text:
# Question
Title: OTA-program SPIFFS on the ESP8266
Something I'd like information on is whether it is possible to upload a SPIFFS filesystem image to the ESP8266. In theory it might work: It can be uploaded over USB, and according to the logs the flash location changes, but that's about it. PlatformIO also seems to offer an Upload SPIFFS option in a platform that's set to an OTA port, but that could just be it not checking the upload type.

So, what I want to know is how I can configure (or otherwise make) a SPIFFS image OTA-uploadable. I have two main OTA methods: Option One is the default Arduino OTA library, and Option Two is a re-skin of the OTA method-whose-name-is-forgettable where I can upload a file on a webpage hosted by the ESP8266 and it will read the file and update its firmware.

I'm assuming that there's a configuration parameter for this somewhere, but I don't know where to start looking, and the documentation on these libraries has a few very basic examples that don't cover complex or advanced use cases.

(The web server--though essentially unrelated to this issue, it's a great example--is the most egregious of these; the code is complex and now templated too, so I can't make sense of it, and the "examples" consist largely of compressed javascript that doesn't show the user anything. Then you get to the interesting stuff like actually getting the real size of an uploading file, or want to know how uploading things actually works (or why it fails), or you want to serve a file piecemeal by assembling bits of text (in the same way that debug statements usually make use of multiple Serial.print() statements), and there's just *nothing*)

# Answer
Basicly OTA supports the upload of \*.bin files. Wether this contains compiled code or a filesystem (SPIFFS/LittleFS) is irrelevant. **BUT** The space for the OTA (partition) has to be min the size of the \*.bin plus an overhead for processing. So with 4MB at all, you would need 2.5MB OTA for 1.5MB App/SPIFFS.
To tweak partition sizes (or custom partitions) you have to go into the boards.txt file.
OTA - Details and Info here

File system - Details and Info here
> 1 votes

---
Tags: esp8266, programming, spiffs, ota
---


# Question
Title: Arduino /dev/ttyUSB0 permission denied even when user added to group "dialout' on Ubuntu 18.04
I bought Arduino Mega board (CH341 usb) and I am able to connect to /dev/ttyUSB0 (upload to device) only by using sudo.

OS: Ubuntu 18.04

What I've tried:

1. I have downloaded Arduino IDE and added my user to dialout group. Logged out and logged in. Still nothing.
2. Installed Arduino by using apt
3. Installed Arduino by using snap

For all three cases it worked only by running as root (sudo actually). I saw couple of answers for Ubuntu 14.04 but none of answers didn't help.

I guess some other device access permissions are missing but I still didn't find any solution.

# Answer
After some struggle I figured out that I need to add my user to "tty" group as well.

There's another approach that involves udev rules modification for certain vendor:device and update of device's ownership but this seems more sane approach.

To recap:

1. Add your standard user to the group "dialout'

`sudo usermod -a -G dialout your-username`
2. Add your standard user to the group "tty"

`sudo usermod -a -G tty your-username`
3. Logout/Login

Hope this helps
> 6 votes

---
Tags: arduino-mega
---


# Question
Title: Unpredictable behavior on parsing key-value delimited input from serial
I am having trouble with a "simple" command parser; I'm guessing I'm doing something wrong with memory allocation - appreciate any pointers :)

For context: I'm running on an Arduino Uno (if it matters). The commands I expect are of the form `<key1=value1;key2=value2;key3=value3>`. For simplicity here (as well as for my own failed attempts at debugging), I've removed everything extraneous, so that this code just prints back to the serial monitor whatever the current value associated with the key "text" is every time a command enclosed in \< \> is encountered.

This seems to work correctly until after the first time the key is found; then it behaves somewhat unpredictably - haven't yet been able to discern the pattern. But, for instance, if I send:

```
<a=5>
-> EMPTY
<b=7;text=here;d=9>
-> here
<d=abc>
-> here
<d=ghi;e=afds>
-> afds

```

That last displayed value is wrong, since no new key of text was sent over serial. The complete code is here:

```

// command indicators
char START_MARKER = '<';
char END_MARKER = '>';

const int MAX_KEY_VALUE_PAIRS = 3;  // maximum number of key-value pairs in message
const int MAX_ELEMENT_CHARS = 25;  // the maximum number of characters (+1 for terminator) in a key or a value

// message format: <key1=value1;key2=value2;key3=value3>
const int MAX_MESSAGE_CHARS = (MAX_KEY_VALUE_PAIRS * (MAX_ELEMENT_CHARS + 1)) * 2 + (MAX_KEY_VALUE_PAIRS - 1) + 2;  // maximum message size

char received_chars[MAX_MESSAGE_CHARS];  // <- EDIT#1
char received_chars[30] ={'\0'};
bool new_data = false;

char *text;  // the value identified by the "text" keyword, i.e.: in <text=abc;time=814a>, text would be abc.

void ParseData(char *str) {
  // This picks off the ;-delimited key-value pairs and assigns them to a multi-dim array
  char * pch;
  int pairs_count = 0;
  char config[MAX_KEY_VALUE_PAIRS][2][MAX_ELEMENT_CHARS];

  pch = strtok(str, "=");

  while (pch != NULL)
  {
    strcpy(config[pairs_count][0], pch);
    pch = strtok(NULL, ";");
    if (pch == NULL) break;

    strcpy(config[pairs_count][1], pch);
    pairs_count++;
    pch = strtok(NULL, "=");
    if (pch == NULL) break;
  }

  for(int i=0;i<pairs_count;i++) {
    if (strcmp(config[i][0], "text")==0) text = config[i][1];
  }
  Serial.println(text);
}

void ReadSerial(){
  // After calling ReceiveText to empty the buffer, if a complete command has been found,
  // parse that command.
  new_data = ReceiveText();
  if (new_data == true) {
    char temp_chars[MAX_MESSAGE_CHARS];  // temporary array for use when parsing
    strcpy(temp_chars, received_chars);
    received_chars[0] = '\0';  // <- EDIT#2
    ParseData(temp_chars);
  }
}

boolean ReceiveText() {
  // This dumps the characters on the buffer so far received_chars, searching for an END_MARKER
  // along the way; if it finds one, it goes back to find a START_MARKER; if that is also found,
  // the string within is the ;-delimited set of key value pairs
  static boolean recv_in_progress = false;
  static byte ndx = 0;
  char rc;

  boolean new_data = false;
  while (Serial.available() > 0 && new_data == false) {
    rc = Serial.read();

    if (recv_in_progress == true) {
      if (rc != END_MARKER) {
        received_chars[ndx] = rc;
        ndx++;
        if (ndx >= MAX_MESSAGE_CHARS) {
          ndx = MAX_MESSAGE_CHARS - 1;
        }
      } else {
        received_chars[ndx] = '\0'; // terminate the string
        recv_in_progress = false;
        ndx = 0;
        new_data = true;
      }
    } else if (rc == START_MARKER) {
        recv_in_progress = true;
    }
  }
  return new_data;
}

void setup() {
  Serial.begin(9600);
  text = (char*)malloc(25);
  strcpy(text, "EMPTY");
  received_chars[0] = '\0';
}

void loop() {
  ReadSerial();
}

```

Thanks!

# Answer
Welcome to the I forgot to empty my buffer char club (I lost some days finding a simlar problem)

```
 strcpy(temp_chars, received_chars)  // strcpy empties temp_chars and adds the received_chars

```

but you have no (for me) visible routine to empty received\_chars
Do this either by setting

```
received_chars[0] ='\0'; // set the pointer to first index

```

or

```
 received_chars ="0";

```

or

```
strcpy(received_chars,"0");

```

after you used the buffer content. By using

```
static byte ndx = 0;

```

you just set the pointer and then start to write, as a safequard you should first reset the end terminator and then start to write. This is probably the reason you see characters even if no key is pressed due to a still "full" charbuffer.
To prevent heap corruption define your received\_chars as a fixed arraybefore setup:

```
char received_chars[128] ={'\0'}; // 127 chars + terminator

```

if you use malloc you have to use free, but doing that with a lot of dynamic data causes heap fracturing -\> crash in the end

**EDIT**
The program does now the following

* ignores all char not enclosed by \<\>
* check for text and displays everything after = and before;
* ignores everything after ; if its not text= again
* if its text= again ignores the first and only displays the second param

You do not need strtok here as it deletes chars I use a modified substring routne for char arrays. Here is the code working as described above:

```
// command indicators
const char START_MARKER = '<';
const char END_MARKER = '>';

const uint8_t MAX_KEY_VALUE_PAIRS = 3;  // maximum number of key-value pairs in message
const uint8_t MAX_ELEMENT_CHARS = 25;  // the maximum number of characters (+1 for terminator) in a key or a value

// message format: <key1=value1;key2=value2;key3=value3>
const uint8_t MAX_MESSAGE_CHARS = (MAX_KEY_VALUE_PAIRS * (MAX_ELEMENT_CHARS + 1)) * 2 + (MAX_KEY_VALUE_PAIRS - 1) + 2;  // maximum message size

//char received_chars[MAX_MESSAGE_CHARS] = {'\0'};// <- EDIT#1
char received_chars[256] = {'\0'};
bool new_data = false;
char text[25] =  {'\0'};      // the value identified by the "text" keyword, i.e.: in <text=abc;time=814a>, text would be abc.

void ParseData(char *str) {
  // This picks off the ;-delimited key-value pairs and assigns them to a multi-dim array
  char * pch;
  int pairs_count = 0;
  char config[MAX_KEY_VALUE_PAIRS][2][MAX_ELEMENT_CHARS];

  pch = strtok(str, "=");

  while (pch != NULL)  {
    strcpy(config[pairs_count][0], pch);
    pch = strtok(NULL, ";");
    if (pch == NULL) break;

    strcpy(config[pairs_count][1], pch);
    pairs_count++;
    pch = strtok(NULL, "=");
    if (pch == NULL) break;
  }

  for (uint8_t i = 0; i < pairs_count; i++) {
    if (strcmp(config[i][0], "text") == 0) strcpy (text,config[i][1]);
  }
  Serial.println(text);
}

void ReadSerial() {
  // After calling ReceiveText to empty the buffer, if a complete command has been found,
  // parse that command.
  new_data = ReceiveText();
  if (new_data == true) {
    char temp_chars[MAX_MESSAGE_CHARS];  // temporary array for use when parsing
    strcpy(temp_chars, received_chars);
    received_chars[0] = '\0';  // <- EDIT#2
    ParseData(temp_chars);
  }
}

bool ReceiveText() {
  // This dumps the characters on the buffer so far received_chars, searching for an END_MARKER
  // along the way; if it finds one, it goes back to find a START_MARKER; if that is also found,
  // the string within is the ;-delimited set of key value pairs
  static boolean recv_in_progress = false;
  static byte ndx = 0;
  char rc;

  bool new_data = false;
  while (Serial.available() > 0 && new_data == false) {
    rc = Serial.read();

    if (recv_in_progress == true) {
      if (rc != END_MARKER) {
        received_chars[ndx] = rc;
        ndx++;
        if (ndx >= MAX_MESSAGE_CHARS) {
          ndx = MAX_MESSAGE_CHARS - 1;
        }
      } else {
        received_chars[ndx] = '\0'; // terminate the string
        recv_in_progress = false;
        ndx = 0;
        new_data = true;
      }
    } else if (rc == START_MARKER) {
      recv_in_progress = true;
    }
  }
  return new_data;
}

void setup() {
  Serial.begin(115200);
   strcpy (text, "EMPTY");
 //  text = (char*)malloc(25);
//  received_chars[0] = '\0';
}

void loop() {
  ReadSerial();
}

```

If you could describe what you really want in the end I'm sure we can help with some basic routines.
> 0 votes

# Answer
The problem was that, in the variables I wanted to keep (i.e.: text in the code below), I was assigning the value of a pointer to the parsed string which is reused the next time a command is found, rather than copying the string.

Fixed code below - see comment Fig#1. There's also a second fix, although that wasn't causing the problem behavior.

```
// command indicators
char START_MARKER = '<';
char END_MARKER = '>';

const int MAX_KEY_VALUE_PAIRS = 3;  // maximum number of key-value pairs in message
const int MAX_ELEMENT_CHARS = 25;  // the maximum number of characters (+1 for terminator) in a key or a value

// message format: <key1=value1;key2=value2;key3=value3>
const int MAX_MESSAGE_CHARS = (MAX_KEY_VALUE_PAIRS * (MAX_ELEMENT_CHARS + 1)) * 2 + (MAX_KEY_VALUE_PAIRS - 1) + 2;  // maximum message size

char received_chars[MAX_MESSAGE_CHARS];
bool new_data = false;

char *text;  // the value identified by the "text" keyword, i.e.: in <text=abc;time=814a>, text would be abc.

void ParseData(char *str) {
  // This picks off the ;-delimited key-value pairs and assigns them to a multi-dim array
  char * pch;
  int pairs_count = 0;
  char config[MAX_KEY_VALUE_PAIRS][2][MAX_ELEMENT_CHARS];

  pch = strtok(str, "=");

  while (pch != NULL)
  {
    strcpy(config[pairs_count][0], pch);
    pch = strtok(NULL, ";");
    if (pch == NULL) break;

    strcpy(config[pairs_count][1], pch);
    pairs_count++;
    pch = strtok(NULL, "=");
    if (pch == NULL) break;
  }

  for(int i=0;i<pairs_count;i++) {
    if (strcmp(config[i][0], "text")==0) strcpy(text, config[i][1]);  // Fix#1
  }
  Serial.println(text);
}

void ReadSerial(){
  // After calling ReceiveText to empty the buffer, if a complete command has been found,
  // parse that command.
  new_data = ReceiveText();
  if (new_data == true) {
    char temp_chars[MAX_MESSAGE_CHARS];  // temporary array for use when parsing
    strcpy(temp_chars, received_chars);
    received_chars[0] = '\0';  // Fix #2 - wasn't causing this problem, but still was wrong
    ParseData(temp_chars);
  }
}

boolean ReceiveText() {
  // This dumps the characters on the buffer so far received_chars, searching for an END_MARKER
  // along the way; if it finds one, it goes back to find a START_MARKER; if that is also found,
  // the string within is the ;-delimited set of key value pairs
  static boolean recv_in_progress = false;
  static byte ndx = 0;
  char rc;

  boolean new_data = false;
  while (Serial.available() > 0 && new_data == false) {
    rc = Serial.read();

    if (recv_in_progress == true) {
      if (rc != END_MARKER) {
        received_chars[ndx] = rc;
        ndx++;
        if (ndx >= MAX_MESSAGE_CHARS) {
          ndx = MAX_MESSAGE_CHARS - 1;
        }
      } else {
        received_chars[ndx] = '\0'; // terminate the string
        recv_in_progress = false;
        ndx = 0;
        new_data = true;
      }
    } else if (rc == START_MARKER) {
        recv_in_progress = true;
    }
  }
  return new_data;
}

void setup() {
  Serial.begin(9600);
  text = (char*)malloc(25);
  strcpy(text, "EMPTY");
  received_chars[0] = '\0';
}

void loop() {
  ReadSerial();
}

```

Thanks to Codebreaker007 for the help.
> 0 votes

---
Tags: serial, string, memory
---


# Question
Title: MCore(Arduino) - Python bluetooth communication
Pc and Mcore with bluetooth module are paired. The port is COM9 outgoing in PC. However, when I send message Arduino does not get anything. I just disconnect arduino from pc and write simple code in Mcore that turn on LED when input message is 1. However still nothing. These are the codes in python and arduino side:

```
import time
import serial

port="COM9"          #This will be different for various devices,COM port.
bluetooth=serial.Serial(port, 9600)         #Start communications with the bluetooth unit
bluetooth.flushInput()      #This gives the bluetooth a little kick
bluetooth.write(b'1')       #These need to be bytes not unicode
bluetooth.close()          #Otherwise the connection will remain open until a timeout

```

Arduino code:

```
char a;

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

void loop()
{
if(Serial.available()){a = Serial.read();}

if (a == '1'){
  digitalWrite(13, HIGH);
  }

  else{
  digitalWrite(13, LOW);}

  delay(100);
}

```

I have tried to install Pybluez for WIN10, however, there was error. Do you think that this is the reason?

Thanks in advance

# Answer
Probably because you never called `bluetooth.open()`.

What would be much easier to do is use pySerialTransfer and SerialTransfer.h to guarantee reliable and robust serial communication between Python and your Arduino.

pySerialTransfer is pip-installable and cross-platform compatible. SerialTransfer.h runs on the Arduino platform and can be installed through the Arduino IDE's Libraries Manager.

Both of these libraries have highly efficient and robust packetizing/parsing algorithms with easy to use APIs and come with examples.
> 1 votes

# Answer
kindly add a serial print before the if statement(`if (a == '1')`) to see what value of a is recieved so we can debug it
> 0 votes

---
Tags: arduino-uno, bluetooth, mbot
---


title: Arduino voltage connection pins

text:
# Question
Title: Arduino voltage connection pins
On the Arduino power connector jack, which is the positive terminal pin and the negative pin?

# Answer
> 3 votes
Arduino's power connector jack's tip is positive while the sleeve is negative but the more important thing to know is what will you be using in powering Arduino? Please provide more information about your setup and possibly a schematic. This will help us understand more what you're trying to accomplish.

---
Tags: pins, voltage, connector
---


# Question
Title: Arduino Serial Communication with Python: sending an array
I am a bit new to both Arduino and Python. My aim is to send commands to Arduino to run a stepper motor. I need to send an array containing the parameters. After consulting many earlier posts like:

https://stackoverflow.com/questions/27639605/send-a-list-of-data-from-python-to-arduino-using-pyserial

Send multiple int values from Python to Arduino using pySerial

I wrote my Arduino code:

```
long  incoming[3];

void setup() {
  pinMode(13, OUTPUT);
  Serial.begin(9600);
  Serial.println("Ready");
}

void loop() {
  if(Serial.available()) {
    for (int i = 0; i < 3; i++) {
      incoming[i] = Serial.read();
    }
    Serial.println(incoming[0]);
    Serial.println(incoming[0]);
    Serial.println(incoming[2]);
  }
}

```

And the Python(2.7) code:

```
from time import sleep
import serial
import struct
ser = serial.Serial('COM6', 9600)

while True:
     ser.write(struct.pack('>iii',2000,10,220))
     print ser.readline()
     sleep(.5)

```

Now coming to the problem:

1. The values printed on the Python shell are completely wrong, including negative values.
2. If I use \>BBB instead of \>iii, I am getting the correct result, but I can't go beyond 255, the integer limit. There is a small catch here also, the initial two sets are giving minus values and then it becomes alright.
3. Further, is there any way to interrupt a running void loop?

Any help is deeply appreciated.

# Answer
*If I use \>BBB instead of \>iii...* That's because "B" is a byte. So you end up sending 3 bytes:

```
struct.pack("BBB", 1, 2, 3)
\x01\x02\x03

```

"i" is an int and has a size of 4, so you send 4\*3 = 12 bytes:

```
struct.pack("iii", 1, 2, 3)
\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00

```

`Serial.read()` reads 1 byte at a time, so you need to read 4 bytes for each value.

---

Here's a function to read a 32-bit int. The drawbacks of this method are that a) it will block until 4 bytes have been read. And b) there's no way to tell if some data has been lost. There are more robust ways to send data with Start-of-Message, End-of-Message, and Check-sum chars. Also, the function assumes the data is sent with the LSB first. But I'll just put this here as an example.

```
// Helper macro to merge 4 bytes
#define TO_INT32(a,b,c,d) (((d)<<24)|((c)<<16)|((b)<<8)|(a))
int32_t read_int()
{
  uint32_t result[4];
  for (int i = 0; i < 4; i++) {
    // Wait for data at the port
    while (!Serial.available());
    result[i] = Serial.read();
  }
  return TO_INT32(result[0], result[1], result[2], result[3]);
}

```
> 6 votes

# Answer
You can much more easily send an array between Python and Arduino using the inter-compatible libraries SerialTransfer.h and pySerialTransfer. Using libraries like this ensures reliable and robust communication between Python and your Arduino.

SerialTransfer.h is installable via the Arduino IDE's Libraries Manager and comes with many examples. The package pySerialTransfer is pip-installable.
> 1 votes

---
Tags: arduino-uno, serial, python
---


# Question
Title: Finding address of OLED using I2C communication and Arduino
It is known that address of OLED SSD1306 is 3C. The frame format is as follows:

The figure implies that the binary pattern should be 01111000 for the first frame (considering write mode and the second last bit is a dont care).
So I was trying to send the first frame using Wire.h library. The following is a code `Wire.beginTransmission(0b01111001);` But i receive a nack (return value of 2)

However, If I send 00111100, i receive a ack(return value of 0). What is wrong in my interpretation?

# Answer
> 0 votes
You misinterpret how the `Wire` library is used. Though the first byte in the transmission is called the address byte, the actual address consists only of the 7 higher bits in that byte. The direction bit is not in the address.

So the `Wire.beginTransmission()` method wants the address as parameter, without the direction bit. That bit is set corresponding to the used function (0 for `Wire.beginTransmission()` and 1 for `Wire.requestFrom()`).

`0b0111100` is the real address (when connnecting the address pin to ground)(note, that there are only 7 bits, since the address only has 7 bits). The write operation address byte will then be `0b01111000`, though the library is hiding that way from you. You need to provide the 7 bit address to the function.

> the second last bit is a dont care

As mentioned above, that is not correct. This bit (the least significant bit of the address) is set by the address pin SA0. It seems, that you have it tied to ground, which sets the corresponding bit in the address to zero. If you would tie it to Vcc, it would be 1.

# Answer
> 0 votes
I2C has a 7-bit address space. The device's actual address is `0b0111100` (=0x3c). The sequences `0b01111001` and `0b01111000` address the same slave while the first one (least significant bit is `1`) starts a read transmission, the second one starts a write transmission.

Those least significant bits are nothing you need to care about when using `Wire.h`: the mode of operation is automatically set when using `Wire.startTransmission(addr)` (returns `0` when slave ACK'ed write command) and `Wire.requestFrom(addr)` (returns `0` when slave ACK'ed read command).

---
Tags: arduino-uno, ssd1306, oled
---


# Question
Title: Button debounce using millis() in this example
I have been trying to find a way to use millis() instead of delay(), in order to press 2 buttons to turn on and off a blue led.

EDITED:

```
const int right_button = 8, left_button = 9, yellow_led = 7, blue_led = 6, green_led = 5, red_led = 4;
int previous_left_button_status = LOW, previous_right_button_status = LOW, blue_status = LOW, green_status = LOW;
unsigned long time_setup = millis();
const int delay_task = 250;

void setup()
{
  pinMode(right_button, INPUT_PULLUP);
  pinMode(left_button, INPUT_PULLUP);
  pinMode(blue_led, OUTPUT);
  pinMode(green_led, OUTPUT);
  pinMode(red_led, OUTPUT);
  pinMode(yellow_led, OUTPUT);
  Display.clear();
}

void loop()
{
  int right_button_status = digitalRead(right_button);
  int left_button_status = digitalRead(left_button);
  unsigned long time_passes = millis();
  if (time_passes - time_setup >= delay_task)
  {
    time_setup = time_passes;
    if (right_button_status == previous_right_button_status)
    {
      green_status = !green_status;
      digitalWrite(green_led, green_status);
    }
  }
}

```

# Answer
> 1 votes
You've declared the variable for the millis function inside your loop correct and you've declared the delay duration you want to use. Two things you've missed are you've declared 2 variables with the millis function and to use it to control the program flow based on some condition to execute some code, in your case, to press 2 buttons to turn on and off an LED.

The way to to this is to use an if-else statement inside the loop function with one variable declared with the millis function, delay\_duration as your reference, and 1 variable declared with a zero value.

```
unsigned long storeMillis = 0;
const int delay_duration = 500;

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

void loop() {
unsigned long currentMillis = millis();
if (currentMillis - storeMillis > 500) {
storeMillis = currentMillis; //update and store the value of storeMillis for the next iteration
//code you want to do
}

```

---
Tags: arduino-uno, arduino-ide
---


# Question
Title: Arduino-compatible wireless technology which can be suitable for transmitting data
# Introduction

I've been meaning to build a vehicle using arduino components and LEGO. I have a mechanical clamp built with arduino which will be locked on top of a custom LEGO build (It should be made out of LEGO blocks and arduino sensors). In my mind, it resembles a crawler.

# Question

I've been looking for a way of controlling it remotely. I only have experience with IR controllers but I'm not sure if this technology would fit for my project.

What I'm looking for is a technology wich could transmit data to an Arduino board (thus, an emitter and a receiver component) which, in my case, could comfortably handle a veichle.

Plus, it should have a range of action of at least 5 meters (15 ft).

If such technology exists, do you know any controller which could do the job for me?

# Answer
> 1 votes
You can use radio transmitter/receivers, they are typically called RF (Radio Frequency) modules.

Typical examples are nRF24L01+ (2.4 GHz), or RF 315/433 modules (on 315/433 MHz).

There are more possibilities, but these are the most used on Arduino and libraries are available.

# Answer
> 0 votes
Try a pair of Wixels (https://www.pololu.com/product/1336). A pair of Wixels (one at the PC, one on the crawler) act as a fast USB cable emulator. The PC-connected Wixel shows up as a USB port, and the one on the crawler (with a Wixel sheild) emulates the Arduiono end of a USB cable. These are very easy to use, and in addition to remote control will allow you to wirelessly program the Arduino controller.

The ability to remotely program the crawler is a real god-send, as now you don't have to retrieve the crawler and connect it to a hardware USB cable for programming.

Just my $0.02

Frank

---
Tags: wireless, remote-control
---


# Question
Title: Arduino program using i2c stops working after printing to OLED a few times
**A NOTE ON THE PROJECT AND PROGRAM STRUCTURE**

I am developing an open source Smart Watch project using Arduino. The code can be found here: https://github.com/shivangsgangadia/SmartWatch The code is too large and divided into multiple files, hence I cannot paste it here within the question, hence I request you to look into the github repo.

So far I have interfaced an OLED (128 X 64 SSD1306) and RTC (DS3231 in ZS-042). I have written libraries for both, which have been included in Github repo.

The program structure allows to add multiple "Modules" which are basically like apps. There is a static State class that holds the program state such as modules to be serviced, and time from RTC. Each "Module" can be a "App" or "Overlay". Overlays are always visibles, there can be mutiple overlays active, but only 1 app can exist at a time.

**WHAT I AM TRYING TO DO ?**

1. Read RTC into State class's static variables
2. Display once
3. Attach interrupt to set boolean flag when the RTC gives interrupt (alarm set to 1 minute) Service interrupt in loop by:

* Read RTC into State class's static variables
    * Reset alarm for RTC
    * Update display

**WHAT IS THE PROBLEM ?**

The program works fine 2-3 times, i.e. does what's expected after servicing 2-3 interrupts (hence 2-3 minutes), but after that the print on the OLED becomes mangled and the program stops altogether.

**WHAT HAVE I TRIED TO SOLVE IT ?**

With `Serial.println()` in many areas such as before and after `OLED::writeString` is called in respective classes, I concluded that the RTC is not the issue, but the OLED somehow causes the program to stop.

Removing `OLED::writeString` statements does allow the rest of the printing to continue for more than 2-3 times, but the program eventually does stop. I have tried replacing the wires and the breadboard, but nothing seems to have any effect.

# Answer
This is wrong in many ways:

```
String input = Serial.readString();
serialInputBuffer = new char[input.length()];
input.toCharArray(serialInputBuffer, input.length());

```

**What's fatal is that you later don't free the memory allocated with `new`.** Don't use String and `new`. Both use heap memory and will fragment it with these small allocations until there is no space for the next allocation. I see you have dynamic allocation in other parts of the sketch and there it looks like you have a `delete`, but they still cause the fragmentation problem.

Use a global buffer like `char serialInputBuffer[64];` and use:

```
int l = Serial.readBytes(serialInputBuffer, sizeof(serialInputBuffer));
serialInputBuffer[l] = 0;

```

In the scale function, there is a dynamically allocated array. Replace it with a class variable, which acts as a buffer which can hold the maximum number of bytes you expect the use to scale their byte to.

Again, dynamic allocations will cause fragmentation even if the memory is released properly.
> 4 votes

# Answer
Don't use the Wire library. If you look closely at twi.c, you'll find it has blocking calls with (potentially) infinite loops. Eventually a condition will occur that causes one of the blocking calls to hang forever.

See this post and this post for details

Use something like SBWire

Frank
> -1 votes

---
Tags: arduino-nano, i2c, rtc, oled
---


title: NFC library for M24SR64

text:
# Question
Title: NFC library for M24SR64
Im currently working on a project where i build an NFC device and needed some guidance in regards to the library needed for the NFC chip to work on the Arduino IDE. The chip is an M24SR64 chip and i've looked online for the library related to the chip but i couldn't find it. Although i did found a library for the M24SR64-y chip, though i'm not sure if its possible to use it, or whether it will work. If anyone has an idea or any help it would be much appreciated

# Answer
> -1 votes
Here you will find a lib for all M24SR NFC tags
In this test sketch you find details how to connect and test the tag with Arduino.
If it helps mark as accepted to help others.

---
Tags: library, nfc
---


title: Problem sending strings to another ESP

text:
# Question
Title: Problem sending strings to another ESP
I am having some problems with retrieving data from another esp. I have two esp8266, one is the access point which has a nextion lcd hooked up to it. The access point reads button presses from the lcd then sends messages to the other esp(the station point) in order to turn on the respcetive digital pins. The station point has two dht22 sensors hooked up to it. I am now trying to sens the temperature data from one of the sensor to the access point to print the data to the screen but I am having some problems(either sending or retrieving the sensor data, not sure how to test it). Here is the code for the access point:

```
//this is the acces point
#include <doxygen.h>
#include <NexButton.h>
#include <NexCheckbox.h>
#include <NexConfig.h>
#include <NexCrop.h>
#include <NexDualStateButton.h>
#include <NexGauge.h>
#include <NexGpio.h>
#include <NexHardware.h>
#include <NexHotspot.h>
#include <NexNumber.h>
#include <NexObject.h>
#include <NexPage.h>
#include <NexPicture.h>
#include <NexProgressBar.h>
#include <NexRadio.h>
#include <NexRtc.h>
#include <NexScrolltext.h>
#include <NexSlider.h>
#include <NexText.h>
#include <NexTimer.h>
#include <Nextion.h>
#include <NexTouch.h>
#include <NexUpload.h>
#include <NexVariable.h>
#include <NexWaveform.h>

#include <SoftwareSerial.h>
#include <ESP8266WiFi.h>
#include <Nextion.h>

//wifi stuff
WiFiServer server(80);
IPAddress IP(192, 168, 4, 15);
IPAddress mask = (255, 255, 255, 0);

//booleans for check
bool Red1=false;
bool Green1=false;
bool Blue1=false;
bool Red2=false;
bool Green2=false;
bool Blue2=false;
bool Relay1=false;
bool Relay2=false;
bool AmbientTemp=false;
//ints for temp data
//String tempOutside=" ";
String tempInside=" ";
String humOutside=" ";
String humInside=" ";
//buttons
// page id,id,""name"
NexButton b0 = NexButton(1,2,"b0");//red1
NexButton b1 = NexButton(1,3,"b1");//green1
NexButton b2 = NexButton(1,4,"b2");//blue1
NexButton b7 = NexButton(3,2,"b7");//relay1
NexButton b8 = NexButton(3,3,"b8");//relay2
NexButton b9 = NexButton(2, 14, "b9");
NexText t8 = NexText(2,10,"t8");//tremperature inside
NexText t9 = NexText(2,11,"t9");//temperature outside
NexText t10 = NexText(2,12,"t10");//humidity inside
NexText t11 = NexText(2,13,"t11");//humidity outside

NexTouch *nex_listen_list[] = {
  &b0,
  &b1,
  &b2,
  &b7,
  &b8,
  &b9,
  NULL
};
//led strip 1
void b0PushCallback(void *ptr) {
  Red1=true;

  }
void b1PushCallback(void *ptr) {
  Green1=true;
  Serial.println("Green1");
  }
void b2PushCallback(void *ptr) {
  Blue1=true;
  }
//relays
void b7PushCallback(void *ptr) {
  Relay1=true;
  }
void b8PushCallback(void *ptr) {
  Relay2=true;
  }
void b9PushCallback(void *ptr) {
  AmbientTemp=true;
  }

void setup() {
  Serial.begin(9600);
  nexInit();
  b0.attachPush(b0PushCallback,&b0);
  b1.attachPush(b1PushCallback,&b1);
  b2.attachPush(b2PushCallback,&b2);
  b7.attachPush(b7PushCallback,&b7);
  b8.attachPush(b8PushCallback,&b8);
  b9.attachPush(b9PushCallback,&b9);
  //wifi part
  WiFi.mode(WIFI_AP);
  WiFi.softAP("Wemos_AP", "Wemos_comm");
  WiFi.softAPConfig(IP, IP, mask);
  server.begin();
  Serial.println();
  Serial.println("accesspoint_bare_01.ino");
  Serial.println("Server started.");
  Serial.print("IP: "); Serial.println(WiFi.softAPIP());
  Serial.print("MAC:"); Serial.println(WiFi.softAPmacAddress());
}

void loop() {
  nexLoop(nex_listen_list);
  //wifi stuff again
  WiFiClient client = server.available();
  if (!client) {
    return;
  }
  //String request = client.readStringUntil('\r');
  Serial.println("********************************");
  //Serial.println("From the station: " + request);
  client.flush();
  //strip 1
  if (Red1==true){
    client.print("redOne\r");
    Serial.println("Red1");
    Red1=false;
    }
  if (Green1==true){
    client.println("greenOne\r");
    Green1=false;
    }
  if (Blue1==true){
    client.println("blueOne\r");
    Blue1=false;
    }
  //relays
  if (Relay1==true){
    client.println("relayOne\r");
    Relay1=false;
    }
  if (Relay2==true){
    client.println("relayTwo\r");
    Serial.println("Relay2");
    Relay2=false;
    }
  if (AmbientTemp==true){
    client.println("AmbientTemp\r");
    Serial.println("ambient temp");
    AmbientTemp=false;
    }
  String tempOutside=client.readStringUntil('\r');
  Serial.println("tempOutside: ");
  Serial.println(tempOutside);
  //t8.setText(tempOutside);
  //tempInside=client.readStringUntil('\b');
  //t9.setText(tempOutside);
  //humInside=client.readStringUntil('\e');
  //t10.setText(humInside);
  //humOutside=client.readStringUntil('\f');
  //t11.setText (humOutside);//halp
  //Serial.println(humOutside);
  //Serial.println("humoutside: ");
  //Serial.print("t11.txt=");
  //Serial.print(humOutside.toInt());
  //Serial.write(0xff);
  //Serial.write(0xff);
  //Serial.write(0xff);
  Serial.println("Byte sent to the station: ");
  //Serial.println(client.println("reeeeeeeeeeeeeeeeeeeee\r"));
  //Serial.println(client.println("IamAlive\r"));
  }

```

And here is the code for the access point:

```
#include <DHT.h>
#include <DHT_U.h>
#include <ESP8266WiFi.h>

#define DHTPIN 3 //outside
#define DHTPIN2 0 //inside
#define DHTTYPE DHT22//type of sensor that I am using
DHT dht(DHTPIN, DHTTYPE); //outside
DHT dht2(DHTPIN2, DHTTYPE); //inside

//pins
const int Red = 5;
const int Green = 4;
const int Blue = 14;
const int Relay1= 12;
const int Relay2= 13;
//booleans for on/off(state)
bool RedS=false;
bool GreenS=false;
bool BlueS=false;
bool Relay1S=false;
bool Relay2S=false;
bool AmbientTempS=false;

char ssid[] = "Wemos_AP";           // SSID of your AP
char pass[] = "Wemos_comm";         // password of your AP
IPAddress server(192,168,4,15);     // IP address of the AP
WiFiClient client;
void setup() {
  Serial.begin(9600);
  dht.begin();
  dht2.begin();
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, pass);           // connects to the WiFi AP
  Serial.println();
  Serial.println("Connection to the AP");
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(500);
  }
  Serial.println();
  Serial.println("Connected");
  Serial.println("station_bare_01.ino");
  Serial.print("LocalIP:"); Serial.println(WiFi.localIP());
  Serial.println("MAC:" + WiFi.macAddress());
  Serial.print("Gateway:"); Serial.println(WiFi.gatewayIP());
  Serial.print("AP MAC:"); Serial.println(WiFi.BSSIDstr());
  //pins
  pinMode(Red, OUTPUT);
  pinMode(Green, OUTPUT);
  pinMode(Blue, OUTPUT);
  pinMode(Relay1, OUTPUT);
  pinMode(Relay2, OUTPUT);
  digitalWrite(Red, LOW);
  digitalWrite(Green, LOW);
  digitalWrite(Blue, LOW);
  digitalWrite(Relay1, LOW);
  digitalWrite(Relay2, LOW);
}
void loop() {
  client.connect(server, 80);
  Serial.println("********************************");
  Serial.print("Byte sent to the AP: ");
  Serial.println(client.print("Anyo\r"));
  String answer = client.readStringUntil('\r');
  Serial.println("From the AP: "+answer);
  int h = dht.readHumidity(); //humidity for Outside
  int t = dht.readTemperature(); //temperaure for Outside
  int h2 = dht2.readHumidity(); //humidity for Outside
  int t2 = dht2.readTemperature(); //temperaure for Outside
  Serial.println("temp outside: ");
  Serial.println(t);
  Serial.println("Thing: ");
  //Serial.println("temp inside:");
  //Serial.println(t2);
  //client.print(String(t2)+'\b');
  //Serial.println("hum outside:");
  //Serial.println(h);
  //client.print(String(h)+'\e');
  //Serial.println("hum inside:");
  //Serial.println(h2);
  //Serial.println(client.print(String(h2)+"\f"));
  client.flush();
  //stuff
  client.println(String(t)+'\r');
  //stuff again
  if(answer=="redOne"){
    if (RedS==false){
      digitalWrite(Red, HIGH);
      RedS=true;
      Serial.println("Red1 ON");
      }
    else{
      digitalWrite(Red, LOW);
      RedS=false;
      Serial.println("Red1 OFF");
      }
    }
  if(answer=="greenOne") {
    if (GreenS==false){
      Serial.println("Green1 ON");
      GreenS=true;
      digitalWrite(Green, HIGH);
      }
    else{
      Serial.println("Green1 OFF");
      GreenS=false;
      digitalWrite(Green, LOW);
      }

    }
  if(answer=="blueOne") {
    if (BlueS==false){
      Serial.println("Blue1 ON");
      BlueS=true;
      digitalWrite(Blue, HIGH);
      }
    else{
      Serial.println("Blue1 OFF");
      BlueS=false;
      digitalWrite(Blue, LOW);
      }

    }
  if(answer=="relayOne") {
    if (Relay1S==false){
      Serial.println("Relay1 ON");
      Relay1S=true;
      digitalWrite(Relay1, HIGH);
      }
    else{
      Serial.println("Relay1 OFF");
      Relay1S=false;
      digitalWrite(Relay1, LOW);
      }

    }
  if(answer=="relayTwo") {
    if (Relay2S==false){
      Serial.println("Relay2 ON");
      Relay2S=true;
      digitalWrite(Relay2, HIGH);
      }
    else{
      Serial.println("Relay2 OFF");
      Relay2S=false;
      digitalWrite(Relay2, LOW);
      }
  if(answer=="AmbientTemp") {
    if (AmbientTempS==false){
      Serial.println("AmbientTemp ON");
      AmbientTempS=true;
      }
    else{
      Serial.println("AmbientTemp OFF");
      AmbientTempS=false;
      digitalWrite(Red, LOW);
      digitalWrite(Green, LOW);
      digitalWrite(Blue, LOW);
      }
   while(AmbientTempS==true){
    Serial.println("Ambient temp is on!");
    }

    }
  client.stop();
  delay(2000);
  }
}

```

Thank you and sorry for any mistakes, English is not my first language.

# Answer
Figured it out, not too sure what was causing it to not send messages but below is the code that is working.

```
#include <ESP8266WiFi.h>
#include <DHT.h>
#include <DHT_U.h>

#define DHTPIN 3 //outside
#define DHTPIN2 0 //inside
#define DHTTYPE DHT22//type of sensor that I am using
DHT dht(DHTPIN, DHTTYPE); //outside
DHT dht2(DHTPIN2, DHTTYPE); //inside

//pins
const int Red = 5;
const int Green = 4;
const int Blue = 14;
const int Relay1= 12;
const int Relay2= 13;
//booleans for on/off(state)
bool RedS=false;
bool GreenS=false;
bool BlueS=false;
bool Relay1S=false;
bool Relay2S=false;
bool AmbientTempS=false;

char ssid[] = "Wemos_AP";           // SSID of your AP
char pass[] = "Wemos_comm";         // password of your AP
IPAddress server(192,168,4,15);     // IP address of the AP
WiFiClient client;
void setup() {
  Serial.begin(9600);
  dht.begin();
  dht2.begin();
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, pass);           // connects to the WiFi AP
  Serial.println();
  Serial.println("Connection to the AP");
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(500);
  }
  Serial.println();
  Serial.println("Connected");
  Serial.println("station_bare_01.ino");
  Serial.print("LocalIP:"); Serial.println(WiFi.localIP());
  Serial.println("MAC:" + WiFi.macAddress());
  Serial.print("Gateway:"); Serial.println(WiFi.gatewayIP());
  Serial.print("AP MAC:"); Serial.println(WiFi.BSSIDstr());
  //pins
  pinMode(Red, OUTPUT);
  pinMode(Green, OUTPUT);
  pinMode(Blue, OUTPUT);
  pinMode(Relay1, OUTPUT);
  pinMode(Relay2, OUTPUT);
  digitalWrite(Red, LOW);
  digitalWrite(Green, LOW);
  digitalWrite(Blue, LOW);
  digitalWrite(Relay1, LOW);
  digitalWrite(Relay2, LOW);
}
void loop() {
  int h = dht.readHumidity(); //humidity for Outside
  int t = dht.readTemperature(); //temperaure for Outside
  int h2 = dht2.readHumidity(); //humidity for Outside
  int t2 = dht2.readTemperature(); //temperaure for Outside
  client.connect(server, 80);
  Serial.println("********************************");
  Serial.print("Byte sent to the AP: ");
  Serial.println(client.print("Muie PSD\r")); //sending data to esp8266
  String answer = client.readStringUntil('\r');
  Serial.println("From the AP: " + answer);
  if(answer=="redOne"){
    if (RedS==false){
      digitalWrite(Red, HIGH);
      RedS=true;
      Serial.println("Red1 ON");
      }
    else{
      digitalWrite(Red, LOW);
      RedS=false;
      Serial.println("Red1 OFF");
      }
    }
  if(answer=="greenOne") {
    if (GreenS==false){
      Serial.println("Green1 ON");
      GreenS=true;
      digitalWrite(Green, HIGH);
      }
    else{
      Serial.println("Green1 OFF");
      GreenS=false;
      digitalWrite(Green, LOW);
      }

    }
  if(answer=="blueOne") {
    if (BlueS==false){
      Serial.println("Blue1 ON");
      BlueS=true;
      digitalWrite(Blue, HIGH);
      }
    else{
      Serial.println("Blue1 OFF");
      BlueS=false;
      digitalWrite(Blue, LOW);
      }

    }
  if(answer=="relayOne") {
    if (Relay1S==false){
      Serial.println("Relay1 ON");
      Relay1S=true;
      digitalWrite(Relay1, HIGH);
      }
    else{
      Serial.println("Relay1 OFF");
      Relay1S=false;
      digitalWrite(Relay1, LOW);
      }

    }
  if(answer=="relayTwo") {
    if (Relay2S==false){
      Serial.println("Relay2 ON");
      Relay2S=true;
      digitalWrite(Relay2, HIGH);
      }
    else{
      Serial.println("Relay2 OFF");
      Relay2S=false;
      digitalWrite(Relay2, LOW);
      }
  if(answer=="AmbientTemp") {
    if (AmbientTempS==false){
      Serial.println("AmbientTemp ON");
      AmbientTempS=true;
      }
    else{
      Serial.println("AmbientTemp OFF");
      AmbientTempS=false;
      digitalWrite(Red, LOW);
      digitalWrite(Green, LOW);
      digitalWrite(Blue, LOW);
      }
   while(AmbientTempS==true){
    Serial.println("Ambient temp is on!");
    }

    }
  client.flush();
  client.stop();
  delay(2000);
  }
}

```
> 1 votes

---
Tags: esp8266, wifi, communication
---


title: Serial Moniror, '\r' and Realterm

text:
# Question
Title: Serial Moniror, '\r' and Realterm
I'm wanting the results from each of the 6 ultrasound modules to print on their respected line after new results have been generated instead of spitting out a continuous flow (see attached image). I've downloaded Realterm and got the results to show on there as I've read that the serial monitor can't do that but I don't know where to put the '\r' syntax within my script as I have multiple serial.prints to display the data I need.

Here is a section for 1 of the ultrasound modules, they are just repeated for the differing modules.

Thanks in advance for any help!

  //Object Ahead Distance.
  long duration1, distance1;
  digitalWrite(trigPin1, HIGH);
  digitalWrite(trigPin1, LOW);
  duration1 = pulseIn(echoPin1, HIGH);
  distance1 = (duration1/2) / 29.1;

   delay(500);
   if (distance1 >= 40){
    Serial.print("Nothing Ahead, Okay");
    Serial.print(distance1);
    Serial.println("cm");}
   else if (distance1 <= 39 || distance1 >= 29){
    Serial.print("Vehicle Ahead, Slow ");
    Serial.print(distance1);
    Serial.println("cm");}```

# Answer
> 1 votes
`\r` returns the cursor to the start of the current line. You can't use it to go back up to previous lines.

Instead you need to learn ANSI escape sequences to move the cursor around.

For example `Serial.print("\e[2J");` will clear the entire screen. `Serial.print("\e[1;1H");` will move the cursor to the top left corner of the screen (the coordinates are `\e[{Y};{X}H` by the way).

You can also add colour and all sorts of other nice things, none of which the Arduino IDE's "Serial Monitor" can do.

You can find a good reference of ANSI escape codes here.

---
Tags: serial, print
---


# Question
Title: MPU6050 Accelerometer freezes/glitches after acceleration
I am trying to do rotational vector calculation using a MPU6050 chip which actually work really well with not too much drift **when I rotate the MPU slowly**. However, when I accelerate too much, e.g. change direction in my slow rotations or just slightly tap the breadboard with my finger, the values completely go nuts.

I am using an ESP8266 chip to control the chip and I have tried multiple libraries for reading the Gyro/Accelerometer values which all have more or less the same behaviour.

My accelerometer readings from the Serial plotter, before and after the light tap to the breadboard:

Gyroscope does the same thing. The MPU is new (just arrived in the mail few hours ago), I power it using 3.3V and use 3.3V GPIO logic from the ESP chip.

Does anyone know what could be causing this?

# Answer
Your problems are (most likely) related to loose connections in the breadboard. Sudden movements can cause power to be interrupted briefly, or data signals to become corrupted.

Breadboards aren't great for prototyping anything that moves, even slightly.
> 2 votes

---
Tags: mpu6050
---


# Question
Title: Wireless Bluetooth USB HUB using Arduino nano
I have the following problem/idea:

I have a electronics workbench and a separate PC desk. Now I have a USB HUB on the workbench, but it doesn't properly work, because the USB-cable to the pc is too long. My setup doesnt really allow me to put the PC somewhere else and the USB-hub is already mounted in the closest usable location.

A few days ago I remembered that I have a arduino nano with a hc-05 bluetooth module attached to its hardware serial port. And as both bluetooth and USB are serial connections I was wondering if I couldn't use the arduino sort of as a middle man and connect the arduino via bluetooth to the pc. Then have a software on the pc that registers the arduino as a USB hub with one port and run some code on the arduino that basically makes the arduino act as a USB host (I know that this is possible with the arduino nano) and have it just move data between the USB connection and the bluetooth module.

Im quite sure that all this should be possible. The atmega should even be capable of doing so at or close to maximum USB 2.0 data rates as that is only 12 Mbit/s and it can run at 16 MHz when powered with 5V. Im not quite sure about the maximum data rate for the bluetooth module though, but I can work with a little lower speeds...

The software for the pc could also be relatively straight forward. Something like a virtual USB-port and the software just shifting data from the com-port that is the bluetooth to this virtual USB-port.

So thats the idea. I have some experience in both programming microcontrollers and software for pc.

So what I need is a bit of help with this, as I am not quite sure how to accomplish this.

The parts that I will need the most help with are going to be the programming of the USB host on the arduino and the virtual USB-port on the pc.

The rest should be relatively easy as its basically just shifting data from one register into another.

# Answer
> 1 votes
You can't. As simple as that. The mere act of thinking about it belies a desperate lack of understanding about how USB works.

Yes, it's "serial" in that it sends one bit after another, as opposed to multiple bits all together ("parallel"), but it is completely unrelated in any way to the "serial" that the bluetooth module or the Arduino speak ("UART").

# Answer
> 0 votes
I agree with Majenko. The best way for you is to buy an active USB extension cable, so that you can handle the distance easily (the signal gets refreshed in the cable by active electronics, so that you can use USB over longer distances).

You consider this to be easy, because you haven't dug into the depth of these topics yet. Here are some important information on that:

* Bluetooth and USB are fundamentally different. The term "serial" outside of the Arduino world is just a term for one bit after another. It doesn't describe any protocol or working principle. Interfaces as SPI and I2C are also serial interfaces, but that doesn't mean, that they work similarly, not even in their topology and also not in their protocol behavior. A bridge between these different interfaces is better described as a translator. And translation is always difficult.
* Serial in the Arduino world means the UART interface. No similarity to USB or bluetooth.
* The Bluetooth spec is rather big. There are many types of connection interfaces, that can be build with it. Examples are the UART (Arduino Serial), HID (like a mouse or keyboard on a PC) or audio (like headphones) interfaces. Each connection has it's specific function. The USB spec is even bigger, way bigger to be precise. You would need to understand how bluetooth and USB work at their core for implementing something like that.
* The HC-05 is a chip for getting an UART interface over bluetooth. To change that, you would need to reprogram it with a new firmware. I doubt, that any firmware, that you can find in the web, would be sufficient for your case. Not generic enough. Also the chips hardware is limited, so you can only get limited resources out of it. Most likely you have the HC-05 on an adaptor board, which has a voltage regulator on it (since the HC-05 is a 3.3V device). You would need to ditch that board and solder the chip itself.
* The Nano is a bad choice for everything involving USB. The Atmega328p on it, that you program when programming the Arduino, does not have an USB interface. For that the Nano has a second chip, the Atmega32u4, which acts as USB to UART adaptor. You would need to hack it to do anything different than that. Doing it is possible, but you would need to ask yourself, why you are trying to do something so complex with such an incapable board. Also the Nano cannot be an USB host, nor a hub. There is an USB Host shield for the Uno, but that also is limited.
* Getting anything even remotely near to 12Mbit/s is illusionary. You won't be able to process nearly one bit every clock edge. You already need several clock edges to do very primitive processing (going into an ISR and then moving the data into a different register, as you put it). And the translation between the protocols will not be that easy. You will need much processing power and also quite some RAM and flash (you will certainly need to buffer some data and the program itself will also be very big to implement something like USB). "A little lower speeds" don't cut it there. Even if possible, that would be painstakingly slow in comparison to a real USB hub.
* Most of the software, that you would need for such a project, is non-existent. Doing something that complex with such crappy hardware is an edge case. So you would need to write your own USB stack software. As mentioned, the USB interface is very complex and if you need to ask this question, you are currently not capable of doing this (and neither am I).

I don't say it is absolutely impossible to implement a bit USB functionality with the Nano. But you won't get a satisfying result, that you really can use, even if you were an absolute expert on microcontrollers and the USB and bluetooth stacks (which you really would need to be for it). That is at maximum a project, that an expert would do just for the grind, not for real results.

You have a real life problem, that you want to solve. Choose the easiest way and buy an active USB extension cable.

---
Tags: arduino-nano, bluetooth, usb, wireless
---


title: esp8266 OTA issue

text:
# Question
Title: esp8266 OTA issue
I have uploaded the BasicOTA sketch in Esp8266-12e. I am written one program, when i try to upload it first time in Esp using the OTA port it gets uploaded successfully, but when i try to upload any sketch after that it does not work. The console responds with `No Answer`.

After searching on internet many people have asked to check the sketch size. To check if size matters or not i tried with blinking sketch, and same issue happens there too.

The sketch only gets uploaded in first time.

Can anyone guide me resolving this issue.

# Answer
> 2 votes
Things to check:

1. Partition arrangement selected. You have to make sure to keep the same partition arrangement between uploads.
2. Partition arrangement selected. You have to make sure that the partition arrangement you have chose supports OTA uploads.
3. You have to reset the ESP8266 manually after your USB upload. You can only do an OTA update to a sketch that has booted in "run" mode, not "boot" mode.
4. You have the right IP address / hostname selected? (I don't know how that is handled in the Arduino IDE...)
5. You must upload an OTA-enabled sketch for OTA to continue working.

---
Tags: esp8266, flash, espressif, upload, ota
---


# Question
Title: Debugging different serial receive / send behavior between Uno & Mega
I have a simple text parser (as a component of a larger project) coded up and seemingly working correctly. It parses a key-value delimited command like the following: `<key1=value1;key2=value2;key3=value3>`.

At present, the functionality is very silly just to test it out: when the Arduino finds a key named "text", it composes a response of a similar form, but just with one key "text\_return" and the same value, and sends it back via serial. That is, when the command `<key1=value1;text=123;key3=value3>` is sent, I expect a response from the Arduino of `<text_return=123>`.

I then am connecting the board to my laptop via USB, and testing it out, both with the Serial Monitor in Arduino's IDE, and with a simple program coded in python.

So here's the confusing part:

1. Serial Monitor with Uno: works
2. Python with Uno: works
3. Serial Monitor with Mega: works
4. Python with Mega: does **NOT** work

Specifically, by "does not work", I mean that the Mega seems to receive the serial input from the program, but does not issue a response.

Here's the terminal output from test #2 as displayed by the python program, showing the command-response I'd expect (I parsed the received command into a dict):

```
SENT: <text=1953>
SENT: <text=1954>
SENT: <text=1954>
SENT: <text=1954>
SENT: <text=1954>
SENT: <text=1954>
SENT: <text=1954>
SENT: <text=1954>
RECD: {'text_return': 1954}
SENT: <text=1954>
RECD: {'text_return': 1954}
SENT: <text=1954>
RECD: {'text_return': 1954}
SENT: <text=1954>
RECD: {'text_return': 1954}

```

And here's the terminal output from the non-working test#4 - i.e.: no response.

```
SENT: <text=2001>
SENT: <text=2002>
SENT: <text=2002>
SENT: <text=2002>
SENT: <text=2002>
SENT: <text=2002>
SENT: <text=2002>
SENT: <text=2002>
SENT: <text=2002>
SENT: <text=2002>
SENT: <text=2002>
SENT: <text=2003>
SENT: <text=2003>
SENT: <text=2003>
SENT: <text=2003>
SENT: <text=2003>
SENT: <text=2003>
SENT: <text=2003>
SENT: <text=2003>

```

In all cases, I'm using 9600 Baud; the only change between the two tests is that I select the Uno vs. Mega / Mega 2560 board in the Arduino IDE.

The Mega board is an Elegoo Mega2560 R3. The code may be extraneous, but to help:

**Opening the port to the arduino from python**

```
def FindArduino(baud=9600, timeout=0):
  initial_time = time.time()
  arduino_found = False
  attempted = False
  while not attempted or time.time() - initial_time < timeout and not arduino_found:
    attempted = True
    ports = serial.tools.list_ports.comports(include_links=False)
    for port in ports:
      manufacturer = port.manufacturer
      if manufacturer and 'arduino' in manufacturer.lower():
        arduino_port = port
        arduino_found = True

  if arduino_found:
    try:
      arduino = serial.Serial(arduino_port.device, baud, timeout=0)
      arduino.reset_input_buffer()
      arduino.reset_output_buffer()
    except serial.SerialException:
      arduino_found = False

  if arduino_found:
    return arduino
  else:
    return None

```

**Sending the serial in python, to Arduino**

```
  cmd = '<text=%d>' % (time.time() - 1586218411)
  print('SENT: %s' %cmd)
  cmd = bytes(cmd, 'ascii')
  arduino.write(cmd)
  time.sleep(.1)

```

**Receiving the serial in python, from Arduino**

```
  cmds = []

  if (arduino.in_waiting>0):
    buffer += arduino.read(arduino.in_waiting).decode('ascii')
    while COMMAND_END_CHAR in buffer:
      end_char_pos = buffer.find(COMMAND_END_CHAR)
      potential_command = buffer[:end_char_pos]
      if COMMAND_START_CHAR in potential_command:
        cmds.append(potential_command[potential_command.find(COMMAND_START_CHAR)+1:])
      buffer = buffer[end_char_pos+1:]

  return (buffer, cmds)

```

**And the full code on the Arduino itself**

```
// command indicators
char START_MARKER = '<';
char END_MARKER = '>';

const int MAX_KEY_VALUE_PAIRS = 3;  // maximum number of key-value pairs in message
const int MAX_ELEMENT_CHARS = 30;  // the maximum number of characters (+1 for terminator) in a key or a value

// message format: <key1=value1;key2=value2;key3=value3>
const int MAX_MESSAGE_CHARS = (MAX_KEY_VALUE_PAIRS * (MAX_ELEMENT_CHARS + 1)) * 2 + (MAX_KEY_VALUE_PAIRS - 1) + 2;  // maximum message size

char received_chars[MAX_MESSAGE_CHARS];
bool new_data = false;
char written_chars[MAX_MESSAGE_CHARS];

char *text =  {'\0'};

void ParseData(char *str) {
  // This picks off the ;-delimited key-value pairs and assigns them to a multi-dim array
  char * pch;
  int pairs_count = 0;
  char config[MAX_KEY_VALUE_PAIRS][2][MAX_ELEMENT_CHARS];

  pch = strtok(str, "=");

  while (pch != NULL)
  {
    strcpy(config[pairs_count][0], pch);
    pch = strtok(NULL, ";");
    if (pch == NULL) break;

    strcpy(config[pairs_count][1], pch);
    pairs_count++;
    pch = strtok(NULL, "=");
    if (pch == NULL) break;
  }

  for(int i=0;i<pairs_count;i++) {
    if (strcmp(config[i][0], "text")==0)
      strcpy(text, config[i][1]);
    WriteSerial();
  }
}

void ReadSerial(){
  // After calling ReceiveText to empty the buffer, if a complete command has been found,
  // parse that command.
  new_data = ReceiveText();
  if (new_data == true) {
    char temp_chars[MAX_MESSAGE_CHARS];  // temporary array for use when parsing
    strcpy(temp_chars, received_chars);
    received_chars[0] = '\0';
    ParseData(temp_chars);
  }
}

void WriteSerial(){
  sprintf(written_chars, "<text_return=%s>\n", text);
  Serial.write(written_chars);
  written_chars[0] = '\0';
}

boolean ReceiveText() {
  // This dumps the characters on the buffer so far received_chars, searching for an END_MARKER
  // along the way; if it finds one, it goes back to find a START_MARKER; if that is also found,
  // the string within is the ;-delimited set of key value pairs
  static boolean recv_in_progress = false;
  static byte ndx = 0;
  char rc;

  boolean new_data = false;
  while (Serial.available() > 0 && new_data == false) {
    rc = Serial.read();

    if (recv_in_progress == true) {
      if (rc != END_MARKER) {
        received_chars[ndx] = rc;
        ndx++;
        if (ndx >= MAX_MESSAGE_CHARS) {
          ndx = MAX_MESSAGE_CHARS - 1;
        }
      } else {
        received_chars[ndx] = '\0'; // terminate the string
        recv_in_progress = false;
        ndx = 0;
        new_data = true;
      }
    } else if (rc == START_MARKER) {
        recv_in_progress = true;
    }
  }
  return new_data;
}

void setup() {
  Serial.begin(9600);
  text = (char*)malloc(25);

  received_chars[0] = '\0';

}

void loop() {
  ReadSerial();
}

```

# UPDATE

Using the suggested libraries, I updated the code. The comms in both directions for simple test data are working, though I can't seem to convert the packet received by the Arduino into a string correctly. Here is the output I see from my python terminal; I'd expect to receive back the first character of what was sent (i.e.: the "0", then "1"), rather than just the initialized value of "S".

```
SENT: 0.20
RCVD: S
SENT: 0.41
RCVD: S
SENT: 0.61
RCVD: S
SENT: 0.82
RCVD: S
SENT: 1.02
RCVD: S
SENT: 1.23
RCVD: S
SENT: 1.43
RCVD: S
SENT: 1.64
RCVD: S

```

**Python code**

```
import time
from pySerialTransfer import pySerialTransfer as txfer

if __name__ == '__main__':
  try:
    link = txfer.SerialTransfer('/dev/cu.usbmodem14201')

    link.open()
    time.sleep(2) # allow some time for the Arduino to completely reset
    base = time.time()

    while True:
      time.sleep(0.2)
      s = '%.2f' % (time.time() - base)
      l = len(s)
      for i in range(l):
        link.txBuff[i] = s[i]

      link.send(l)

      while not link.available():
        if link.status < 0:
          print('ERROR: {}'.format(link.status))

      response = ''
      for index in range(link.bytesRead):
        response += chr(link.rxBuff[index])

      print('SENT: %s' % s)
      print('RCVD: %s' % response)

  except KeyboardInterrupt:
    link.close()

```

**Arduino code**

```
#include "SerialTransfer.h"

char str[100];

SerialTransfer myTransfer;
int LED = 13;

void blinkLED(int n)
{
  for (int i = 0; i < n; i++) {
    digitalWrite(LED, HIGH);
    delay(150);
    digitalWrite(LED, LOW);
    delay(150);
  }
}

void setup()
{
  pinMode(LED, OUTPUT);
  digitalWrite(LED, LOW);
  str[0] = 'S';
  str[1] = '\n';
  Serial.begin(115200);
  myTransfer.begin(Serial);
}

void loop()
{
  blinkLED(2);
  delay(500);

  // send bytes
  myTransfer.txBuff[0] = str[0];
  myTransfer.sendData(1);
  if(myTransfer.available())
  {
    blinkLED(60);

    // receive bytes
    byte bytes_to_read = myTransfer.bytesRead;
    for(byte i = 0; i < bytes_to_read; i++)
      strncpy(str + i, myTransfer.rxBuff[i], 1);

  }
  else if(myTransfer.status < 0)
  {
    Serial.print("ERROR: ");

    if(myTransfer.status == -1)
      Serial.println(F("CRC_ERROR"));
    else if(myTransfer.status == -2)
      Serial.println(F("PAYLOAD_ERROR"));
    else if(myTransfer.status == -3)
      Serial.println(F("STOP_BYTE_ERROR"));
  }
}

```

Thank you!

# Answer
> 1 votes
It would be easier if you used Arduino \<--\> Python compatible libraries to ensure the communication between the two is robust and reliable. An example of such libraries would be pySerialTransfer and SerialTransfer.h.

pySerialTransfer is pip-installable and cross-platform compatible. SerialTransfer.h runs on the Arduino platform and can be installed through the Arduino IDE's Libraries Manager.

Both of these libraries have highly efficient and robust packetizing/parsing algorithms with easy to use APIs.

**Example Python Script:**

```
from time import sleep
from pySerialTransfer import pySerialTransfer as txfer

if __name__ == '__main__':
    try:
        link = txfer.SerialTransfer('COM17')

        link.open()
        sleep(2) # allow some time for the Arduino to completely reset

        while True:
            link.txBuff[0] = 'h'
            link.txBuff[1] = 'i'
            link.txBuff[2] = '\n'

            link.send(3)

            while not link.available():
                if link.status < 0:
                    print('ERROR: {}'.format(link.status))

            print('Response received:')

            response = ''
            for index in range(link.bytesRead):
                response += chr(link.rxBuff[index])

            print(response)

    except KeyboardInterrupt:
        link.close()

```

**Example Arduino Sketch:**

```
#include "SerialTransfer.h"

SerialTransfer myTransfer;

void setup()
{
  Serial.begin(115200);
  myTransfer.begin(Serial);
}

void loop()
{
  myTransfer.txBuff[0] = 'h';
  myTransfer.txBuff[1] = 'i';
  myTransfer.txBuff[2] = '\n';

  myTransfer.sendData(3);
  delay(100);

  if(myTransfer.available())
  {
    //do stuff with received packet data
  }
  else if(myTransfer.status < 0)
  {
    Serial.print("ERROR: ");

    if(myTransfer.status == -1)
      Serial.println(F("CRC_ERROR"));
    else if(myTransfer.status == -2)
      Serial.println(F("PAYLOAD_ERROR"));
    else if(myTransfer.status == -3)
      Serial.println(F("STOP_BYTE_ERROR"));
  }
}

```

Note that you can send more than just individual chars with these libraries. It is possible to transfer floats, ints, bytes, arrays, and even structs (or any combination of the like) within your program using the libraries! See the examples in SerialTransfer.h for more info

**For theory behind robust serial communication,** check out the tutorials Serial Input Basics and Serial Input Advanced.

# EDIT:

---

Applying the above example to your case, you can use the following code:

**Python:**

```
import time
import struct
from pySerialTransfer import pySerialTransfer as txfer

def stuff_float(txfer_obj, val, start_pos=0):
    '''
    Description:
    ------------
    Insert a 32-bit floating point value into the (pySerialtxfer) TX
    buffer starting at the specified index

    :param txfer_obj: txfer - Transfer class instance to communicate over serial
    :param val:       float - value to be inserted into TX buffer
    :param start_pos: int   - index of TX buffer where the first byte of
                              the float is to be stored in

    :return start_pos: int - index of the last byte of the float in the TX
                             buffer + 1
    '''

    val_bytes = struct.pack('f', val)

    txfer_obj.txBuff[start_pos] = val_bytes[0]
    start_pos += 1
    txfer_obj.txBuff[start_pos] = val_bytes[1]
    start_pos += 1
    txfer_obj.txBuff[start_pos] = val_bytes[2]
    start_pos += 1
    txfer_obj.txBuff[start_pos] = val_bytes[3]
    start_pos += 1

    return start_pos

if __name__ == '__main__':
  try:
    link = txfer.SerialTransfer('COM17')

    link.open()
    time.sleep(2) # allow some time for the Arduino to completely reset
    base = time.time()

    while True:
      time.sleep(0.2)

      sent = time.time() - base
      stuff_float(link, sent)
      link.send(4)

      while not link.available():
        if link.status < 0:
          print('ERROR: {}'.format(link.status))

      response = ''
      for index in range(link.bytesRead):
        response += chr(link.rxBuff[index])

      print('SENT: {}'.format(sent))
      print('RCVD: {}'.format(response))
      print(' ')

  except KeyboardInterrupt:
    link.close()

```

**Arduino:**

```
#include "SerialTransfer.h"

SerialTransfer myTransfer;

char buff[25];
char str[] = "I got this: %s%d.%04d";
float fromPython = 0;

void setup()
{
  Serial.begin(115200);
  myTransfer.begin(Serial);
}

void loop()
{
  if(myTransfer.available())
  {
    //////////////////////////////////////////////
    // handle call from Python
    myTransfer.rxObj(fromPython, sizeof(fromPython));

    char sign = (fromPython < 0) ? '-' : ' ';
    uint16_t integer = fromPython;
    float tmpFrac = fromPython - integer;
    uint16_t decimal = trunc(tmpFrac * 10000);
    sprintf(buff, str, sign, integer, decimal);
    //////////////////////////////////////////////

    //////////////////////////////////////////////
    // send response
    myTransfer.txObj(buff, sizeof(buff));
    myTransfer.sendData(sizeof(buff));
    //////////////////////////////////////////////
  }
}

```

**Verified Python Output:**

```
SENT: 0.20032477378845215
RCVD: I got this: 0.2003

SENT: 0.4077117443084717
RCVD: I got this: 0.4077

SENT: 0.61326003074646
RCVD: I got this: 0.6132

```

# Yet another edit:

---

Inspired by the answer submitted by OP, I updated the library (1.2.0) to include the member functions `tx_obj()` and `rx_obj()`. These will allow you to automatically send and receive nearly any standard Python object types (including lists and dictionaries).

**Example Python Code:**

```
import time
from pySerialTransfer import pySerialTransfer as txfer

if __name__ == '__main__':
    try:
        link = txfer.SerialTransfer('COM17')

        link.open()
        time.sleep(2) # allow some time for the Arduino to completely reset

        while True:
            send_size = 0

            ###################################################################
            # Send a list
            ###################################################################
            list_ = [1, 3]
            list_size = link.tx_obj(list_)
            send_size += list_size

            ###################################################################
            # Send a string
            ###################################################################
            str_ = 'hello'
            str_size = link.tx_obj(str_, send_size) - send_size
            send_size += str_size

            ###################################################################
            # Send a float
            ###################################################################
            float_ = 5.234
            float_size = link.tx_obj(float_, send_size) - send_size
            send_size += float_size

            ###################################################################
            # Transmit all the data to send in a single packet
            ###################################################################
            link.send(send_size)

            ###################################################################
            # Wait for a response and report any errors while receiving packets
            ###################################################################
            while not link.available():
                if link.status < 0:
                    if link.status == -1:
                        print('ERROR: CRC_ERROR')
                    elif link.status == -2:
                        print('ERROR: PAYLOAD_ERROR')
                    elif link.status == -3:
                        print('ERROR: STOP_BYTE_ERROR')

            ###################################################################
            # Parse response list
            ###################################################################
            rec_list_  = link.rx_obj(obj_type=type(list_),
                                     obj_byte_size=list_size,
                                     list_format='i')

            ###################################################################
            # Parse response string
            ###################################################################
            rec_str_   = link.rx_obj(obj_type=type(str_),
                                     obj_byte_size=str_size,
                                     start_pos=list_size)

            ###################################################################
            # Parse response float
            ###################################################################
            rec_float_ = link.rx_obj(obj_type=type(float_),
                                     obj_byte_size=float_size,
                                     start_pos=(list_size + str_size))

            ###################################################################
            # Display the received data
            ###################################################################
            print('SENT: {} {} {}'.format(list_, str_, float_))
            print('RCVD: {} {} {}'.format(rec_list_, rec_str_, rec_float_))
            print(' ')

    except KeyboardInterrupt:
        link.close()

    except:
        import traceback
        traceback.print_exc()

        link.close()

```

**Example Arduino Code:**

```
#include "SerialTransfer.h"

SerialTransfer myTransfer;

void setup()
{
  Serial.begin(115200);
  myTransfer.begin(Serial);
}

void loop()
{
  if(myTransfer.available())
  {
    // send all received data back to Python
    for(uint16_t i=0; i < myTransfer.bytesRead; i++)
      myTransfer.txBuff[i] = myTransfer.rxBuff[i];

    myTransfer.sendData(myTransfer.bytesRead);
  }
}

```

# Answer
> 0 votes
Building on P\_B's answer to pack additional data types, I extended the python as follows. Of course, the receiving Arduino code needs to receive into the correct data type as well.

```
def StuffInt(txfer_obj, int_to_send, start_pos=0):
  """Insert integer into pySerialtxfer TX buffer starting at the specified index."""
  return StuffObject(txfer_obj, int_to_send, 'i', 4, start_pos=0)

def StuffFloat(txfer_obj, float_to_send, start_pos=0):
  """Insert integer into pySerialtxfer TX buffer starting at the specified index."""
  return StuffObject(txfer_obj, float_to_send, 'f', 4, start_pos=0)

def StuffStr(txfer_obj, string_to_send, max_length=None, start_pos=0):
  """Insert string into pySerialtxfer TX buffer starting at the specified index.

  Args:
    txfer_obj: see StuffObject
    string_to_send: see StuffObject
    max_length: if provided, the string is truncated to the requested size; otherwise
      defaults to the length of the string
    object_byte_size: integer number of bytes of the object to pack
    start_pos: see StuffObject
  Returns:
    start_pos for next object
  """
  if max_length is None:
    max_length = len(string_to_send)
  format_string = '%ds' % max_length
  truncated_string = string_to_send[:max_length]
  truncated_string_b = bytes(truncated_string, 'ascii')
  print (truncated_string_b)
  return StuffObject(txfer_obj, truncated_string_b, format_string, max_length, start_pos=0)

def StuffObject(txfer_obj, val, format_string, object_byte_size, start_pos=0):
  """Insert an object into pySerialtxfer TX buffer starting at the specified index.

  Args:
    txfer_obj: txfer - Transfer class instance to communicate over serial
    val: value to be inserted into TX buffer
    format_string: string used with struct.pack to pack the val
    object_byte_size: integer number of bytes of the object to pack
    start_pos: index of the last byte of the float in the TX buffer + 1

  Returns:
    start_pos for next object
  """
  val_bytes = struct.pack(format_string, val)
  for index in range(object_byte_size):
    txfer_obj.txBuff[index + start_pos] = val_bytes[index]
  return object_byte_size + start_pos

```

---
Tags: arduino-uno, serial, arduino-mega, python
---


title: Toggling a blinking led ON & OFF

text:
# Question
Title: Toggling a blinking led ON & OFF
I am trying to implement a toggle switch to turn blinking ON & OFF. However, the code only turns the led ON or OFF and that too unreliably. Can you help me understand why it isn't working?

```
   const int redLed = 10;
const int buttonPin = 2;
unsigned long newTime;
unsigned long oldTime = 0;
byte newButtonState;
byte oldButtonState = 0;
boolean ledState = false;
boolean blinkState = false;
boolean state = LOW;

void setup() {
  pinMode(redLed, OUTPUT);
  Serial.begin(9600);
  pinMode(buttonPin, INPUT);
}

void loop() {

  newButtonState = digitalRead(buttonPin);
  delay(100);

  // check if button state has changed
  if (newButtonState != oldButtonState) {
    // if button was pushed
    if (newButtonState == HIGH) {
      // check led state
      if (ledState == false) {
        ledState = true;
        blinkState = true;
      } else {
        ledState = false;
        blinkState = false;
      }
      if (ledState == true && blinkState == true) {
        newTime = millis();
        if (newTime - oldTime >= 250) {
          state = !state;
          oldTime = newTime;
        }
        digitalWrite(redLed, state);
      }
    }
  }
  oldButtonState = newButtonState;
}

```

# Answer
I don't see why you would set `blinkState` together with `ledState`. I assume, that you want the button to toggle the blinking. 1 press --\> LED is blinking, another press --\> LED stops blinking, ...

I suggest to restructure your code. First separate input and output, meaning button check code and LED blink code. For blinking you already have a state variable named `blinkState`. So in your `loop()` function you first write

```
newTime = millis();
if(blinkState && newTime - oldTime >= 250){
    ledState = !ledState;
    oldTime = newTime;
}

```

That will toggle `ledState`, whenever `blinkState` is set, in intervals. Now we simply `digitalWrite()` that value out directly after that:

```
digitalWrite(redLed, ledState);

```

Now we need to handle the button. Your button if statements seem to be good, so we only need to change, whats inside the statements. There we simply negate the `blinkState` variable:

```
if (newButtonState != oldButtonState) {
    // if button was pushed
    if (newButtonState == HIGH) {
        blinkState = !blinkState;
    }
}
oldButtonState = newButtonState;
delay(100);

```

With this code the LED will stop changing and keep the state, that it had, when you pressed the button. If you want the LED to turn off at that point, you shoud add `ledState = false;` after negating `blinkState`.

Note, that this code doesn't need your `state` variable. 2 variables are enough for this. 1 for the current led state, 1 for the blinking state.

Also note, that using `delay()` is not the best way to debounce a button. It is an easy way, but it might not behave exactly, like you want to. If you want better debouncing, you can use the Bounce2 library from github. If you don't want to use a library for it, you can still learn about their ways to debounce in the Readme file.
> 0 votes

# Answer
Note, this is not an answer, but I want to show some code examples based on the comment:

You can use as said in the comment:

* Remove '== true' in a boolean condition
* Replace '== false' by '!' in a boolean condition

You will get this:

```
  // check if button state has changed
  if (newButtonState != oldButtonState) {
    // if button was pushed
    if (newButtonState == HIGH) {
      // check led state
      if (!ledState) {
        ledState = true;
        blinkState = true;
      } else {
        ledState = false;
        blinkState = false;
      }
      if (ledState && blinkState) {
        newTime = millis();
        if (newTime - oldTime >= 250) {
          state = !state;
          oldTime = newTime;
        }
        digitalWrite(redLed, state);
      }
    }
  }
  oldButtonState = newButtonState;
}

```

About the following fragment:

```
  if (!ledState) {
    ledState = true;
    blinkState = true;
  } else {
    ledState = false;
    blinkState = false;
  }

```

Since you write `ledState` and `blinkState` in both clauses, and the condition is simple (so you don't need to put it in a temporary variable, you can replace this fragment by:

```
blinkState = !ledState;
ledState = !ledState;

```

Note you have to reverse the order as `blinkState` depends on `ledState`.
> 2 votes

# Answer
You never set the `pinMode` of `buttonPin`.

Normally it defaults to `INPUT` if you don't manually specify anything, and I assume from your results that you don't have an external pullup or pulldown resistor. Therefore you need to specify `pinMode(buttonPin, INPUT_PULLUP);` and make sure that your switch or button connects the input pin to ground when activated (which means that "active" will be LOW).

Or, if you do have an external pullup or pulldown resistor then it sounds like it may not be wired corrcetly.
> 0 votes

# Answer
Your blink code is only active

```
if (newButtonState != oldButtonState)

```

so it won't blink (by itself)

To toggle blinking, just change it e.g. like this

```
void loop() {
  bool newButtonState = digitalRead(buttonPin);
  if (newButtonState != oldButtonState) {
    // button state has changed
    delay(5);  // debounce
    oldButtonState = newButtonState; // run only once per button push
    if (newButtonState == HIGH) {
      // toggle blink state
      blinkState = ! blinkState;
    }
  }

  if (blinkState) {
     // BlinkWithoutDelay
     unsigned long newTime = millis();
     if (newTime - oldTime >= 250) {
        state = !state;
        oldTime = newTime;
        digitalWrite(redLed, state);
     }
  } else {
     // no Blinking : just leave redLed as is
  }
}

```

Now please clean up the global variables: some are not required globally, some are not required at all.
> 0 votes

---
Tags: arduino-uno
---


# Question
Title: Can I run 3 devices on Arduino Uno with different power sources?
I'm pretty new to these types of projects I'd like to work on a greenhouse project with an Arduino Uno. The goal is to be able to sense temperature and control a heating lamp, detect humidity and control a humidifier, and connect a soil hydration sensor and connect a small water pump for irrigation. Could the Uno support all of this power that could theoretically run at the same time? How would controlling the 3 isolated functions look in the Sketch?

# Answer
Your question is 2 fold:

* **Power requirements:** The actual power requirement depends on the devices, but the Arduino will certainly not be able to provide power for a heating lamp. It just cannot provide that much current (you would fry the Arduino). But the Arduino is also only powered from outside. I guess you have a power source, that can provide enough power for all the devices. Then you can connect these devices in parallel to the power source (meaning + and - of the heating lamp power goes directly to the power supply). That way the current for the devices doesn't flow through the Arduino. The Arduino will only use control signals, which don't have high current. Sensors are normally either analog sensors (which connect to the analog pins with only neglectable currents) or use communication interfaces, which are also ok. The current hungry output devices (humidifier and heat lamp) either have a digital control pin, a communication interface, or they must be controlled via a relay (depends on the actual devices).
* **Controlling all the devices:** The Arduino can only do 1 thing at a time. But that is no problem, since you can do things sequentially very fast. For example write one function for every device, that you want to control. In that function you communicate with/control the device according to some variables (like the measured temperature). The `loop()` function can then look as simple as:

```
void loop(){
    measure_temperature();
    measure_humidity();
    measure_soil_hydration();
    control_humidifier();
    control_headlamp();
}

```

If you want to only do this periodically (not all the time), you can either add a `delay()` or - better - use `millis()` like in the `BlinkWithoutDelay` example (there are also many tutorials about `millis()` on the web). Make sure, that the individual functions are not blocking. They should do, what they need to do, and exit quickly. No long staying in loops or waiting for an event there.
> 1 votes

# Answer
Yes, you can run all of those from an UNO, but you'd probably be better off using an ESP32 so that you can add a web portal to your project for relatively the same cost.

You would be able to run the HDT or similar sensor and temperature sensor as well as the hydration sensor directly from an MCU. The other components would require something else, like NPN MOSFET low side power switch (like an FDS3890) that could be controlled by the MCU. You will need to look at the datasheets for each component you buy, find the power ratings, and make sure you have components rated to support the voltage and current of your devices (A good rule of thumb is twice the expected use, so if you have a 12V pump that can sink 3A of current, you should get a MOSFET that can handle 24+ volts and 6+ Amps.

Each sensor will likely have a library you will use and has samples. Googling each one and working on one individual function at a time is a great way to learn and progress your project.

Some MCU only have one core and everything is placed into a loop. Others (like that ESP32) have multiple cores, and can use a RTOS for task scheduling.
> 1 votes

---
Tags: arduino-uno
---


title: Mouse.move values

text:
# Question
Title: Mouse.move values
I understand that `Mouse.move` move the mouse from its current position, example:

`Mouse.move(100, 100);`

Will move the mouse to 100 pixels right and 100 pixels down.

But in reality it will move to somehting like 150 pixels right and/or 150 pixels down..

I already tested without cursor precision/acceleration and it doesn't change a thing.

What unit does the function use ?

I know about the 127 -127 limit, and i respect it, but still... when i ask to move 100,100 it doesn't move 100,100.

# Answer
The mouse coordinates are not pixels. They are a proportion of the physical minimum/maximum parameters of the report descriptor. Since those aren't specified in the report descriptor they are taken to be the same as the logical: -127 to 127.

So moving 100 "units" is moving 100/(127-(-127)) of 100%, which is about 40%.

But 40% of what?

Well, 40% of an inch. Or what your OS believes that an inch is on your current screen.

In the HID specification:

> While Logical Minimum and Logical Maximum (extents) bound the values returned by a device, Physical Minimum and Physical Maximum give meaning to those bounds by allowing the report value to be offset and scaled. For example, a thermometer might have logical extents of 0 and 999 but physical extents of 32 and 212 degrees.The resolution can be determined with the following algorithm:
>
> ```
> if ((Physical Maximum == UNDEFINED) || (Physical Minimum == UNDEFINED) || ((Physical Maximum == 0) && (Physical Minimum == 0))) {
>     Physical Maximum = Logical Maximum;
>     Physical Minimum = Logical Minimum;
> }
>
> If (Unit Exponent == UNDEFINED)
>     Unit Exponent = 0;
>
> Resolution = (Logical Maximum – Logical Minimum) / ((Physical Maximum – Physical Minimum) * (10^Unit Exponent))
>
> ```

```

```
> 2 votes

---
Tags: arduino-leonardo
---


# Question
Title: Clearing string buffer with memset after a serial read
In using the SerialTransfer.h / pySerialTransfer libraries to send commands between my laptop and an Arduino Mega, I am sending multiple sequential strings between the devices. However, I'm having trouble "clearing" the receiving buffer on the Arduino side - it never shrinks, despite a few different attempts to clear the string (memset; a for loop).

I'm sending a string to the Arduino of the format , where there are anywhere from 1 to 5 asterisks. Then the Arduino is simply sending the exact same string back, without any processing (as of yet). And in the python terminal, I'm printing it all out; this is what I get:

```
SENT (17 bytes): <rand_len_str=**>
RECD (17 bytes): <rand_len_str=**>

SENT (18 bytes): <rand_len_str=***>
RECD (18 bytes): <rand_len_str=***>

SENT (19 bytes): <rand_len_str=****>
RECD (19 bytes): <rand_len_str=****>

SENT (17 bytes): <rand_len_str=**>
RECD (19 bytes): <rand_len_str=**>*>

SENT (18 bytes): <rand_len_str=***>
RECD (19 bytes): <rand_len_str=***>>

SENT (18 bytes): <rand_len_str=***>
RECD (19 bytes): <rand_len_str=***>>

```

As long as the string is growing, all is well - but see the error in the 4th pair, with the extra \*\> characters, etc.

The following is my Arduino code; I've tried to reset the receiving string using memset, but this seems not to be working.

```
#include "SerialTransfer.h"

SerialTransfer myTransfer;

const int CMD_LEN = 200;
char buff[CMD_LEN];
char received_str[CMD_LEN];

void setup()
{
  Serial.begin(115200);
  myTransfer.begin(Serial);
}

void loop()
{
  if(myTransfer.available())
  {
    //////////////////////////////////////////////
    // handle call from Python

    memset(received_str, '\0', CMD_LEN*sizeof(char));
    myTransfer.rxObj(received_str, CMD_LEN);

    sprintf(buff, "%s", received_str);
    //////////////////////////////////////////////

    //////////////////////////////////////////////
    // send response
    myTransfer.txObj(buff, strlen(buff));
    myTransfer.sendData(strlen(buff));
    //////////////////////////////////////////////
  }
  else if(myTransfer.status < 0)
  {
    Serial.print("ERROR: ");

    if(myTransfer.status == -1)
      Serial.println(F("CRC_ERROR"));
    else if(myTransfer.status == -2)
      Serial.println(F("PAYLOAD_ERROR"));
    else if(myTransfer.status == -3)
      Serial.println(F("STOP_BYTE_ERROR"));
  }
}

```

I didn't see anything in SerialTransfer.h about clearing the rxObj; I can always just use the first terminating \> character to parse the command - but I imagine there is a cleaner / better solution in clearing the buffer, or at least, I'd like to understand what's going on! Thanks in advance.

# Answer
Instead of clearing your buffers, make use of the bytesRead property. Have a look at how they print the received string in the example code from the library using a for loop. I don't know that it is null terminated or anything.

Example from the library's github page:

```
#include "SerialTransfer.h"

SerialTransfer myTransfer;

void setup()
{
  Serial.begin(115200);
  Serial1.begin(115200);
  myTransfer.begin(Serial1);
}

void loop()
{
  if(myTransfer.available())
  {
    Serial.println("New Data");
    for(byte i = 0; i < myTransfer.bytesRead; i++)
      Serial.write(myTransfer.rxBuff[i]);
    Serial.println();
  }
  else if(myTransfer.status < 0)
  {
    Serial.print("ERROR: ");

    if(myTransfer.status == -1)
      Serial.println(F("CRC_ERROR"));
    else if(myTransfer.status == -2)
      Serial.println(F("PAYLOAD_ERROR"));
    else if(myTransfer.status == -3)
      Serial.println(F("STOP_BYTE_ERROR"));
  }

```
> 0 votes

# Answer
Thanks for the pointer - that did the trick. Applying it to my original code, if I update the few lines around `handle call from Python` to the following, it works as intended.

```
    //////////////////////////////////////////////
    // handle call from Python

    myTransfer.rxObj(received_str, CMD_LEN);
    strncpy(buff, received_str, myTransfer.bytesRead);
    buff[myTransfer.bytesRead] = '\0';

    //////////////////////////////////////////////

```

Thanks again!
> 1 votes

---
Tags: serial, string, buffer
---


title: MAX7219 with 8digit 7seg array

text:
# Question
Title: MAX7219 with 8digit 7seg array
I have a concern about the library port handling. I have used direct port direction manipulation successfully in previous projects but there seems to be a problem here.

```
// This code mostly taken from the example
#include "LedControl.h"

LedControl lc=LedControl(11,13,10,1);
//LedControl lc=LedControl(12,11,10,1); // original
// pin 12 is connected to the DIN pin (now MOSI 11)
// pin 11 is connected to the CLK pin (now SCK 13)
// pin 10 is connected to the CS pin  (now SS 10)
// 1 as we are only using 1 MAX7219

// I am actually using all arduino pins except 12 for my project
#define PD_MSK  B11111100 // Data pins PD2..7 (pins2..7)
#define PB_MSK  B00000011 // Data pins PB0,1 (pins8,9)
#define PC_MSK  B00001111 // Data pins PC0..3 (pins 14..17)

void setup()
{
// set pins 2..9 as inputs
  DDRD = DDRD & !PD_MSK; // this works OK
  DDRB = DDRB & !PB_MSK; // configure ports D,B inputs *** doesnt work with this
 // pinMode(8, INPUT); //*** does work with this
  //pinMode(9, INPUT); //*** does work with this

  DDRC = DDRC | PC_MSK; // configure PortC0..3 as outputs
  PORTC |= 0x0F; // set PortC0..3 high (default)

  // the zero refers to the MAX7219 number, it is zero for 1 chip
  lc.shutdown(0,false);// turn off power saving, enables display
  lc.setIntensity(0,8);// sets brightness (0~15 possible values)
  lc.clearDisplay(0);// clear screen

}
void loop()
{
  //numbers 7 to 0
  for (int a=0; a<8; a++)
  {
    lc.setDigit(0,a,a,false);
  }

  delay(1000);

  //display number 8 on all segments
  for (int a=0; a<8; a++)
  {
    lc.setDigit(0,a,8,false);
  }
  delay(1000);

  // numbers 7 to 0 reverse order
  for (int a=8; a>=0; a--)
  {
    lc.setDigit(0,a,a,false);
    //delay(100);
  }
  delay(1000);

}

```

The direct port direction setting does not seem to allow the library to work while the pinMode commands doing the same job do. I note that the library uses software SPI but I would like to use hardware if possible. I have certainly used hardware SPI with frequent port direction changes on the remaining pins for other projects. Any insight as to why this problem occurs?

Thanks.

# Answer
As always I recommend the old RTFM (read the f\***ing manual) of the LedControl.h library.
In the FAQ its clearly stated:

> Why don't you use the hardware SPI-Bus of the Arduino?
>
> When I wrote the first version of the library I didn't knew much about the Arduino or AVR processors in general and I knew nothing about writing code for the hardware SPI-bus on an ATMega. But I knew how the SPI protocol works and how I could make this work using simple digitalWrite() commands. I turned out the library code is fast enough for common use cases, so there is no need for doing Hi-Speed communications.
>
> Other strong points in favour of the (admittedly trivial) code design are - Use any three free IO-Pins of your board for the hardware - Simple to debug. Much easier than managing 3 differnt SPI devices connected to the same hardware bus - Library is easily portable to other platforms, since it uses only two very basic functions from the Arduino language

So with this library you clearly have never used hardware SPI (although you could use the pins, but only via softwareSPI)
> -1 votes

---
Tags: max7219
---


# Question
Title: Uno - error during uploading with library
I'm writing the code in *VS Code* on *IO Platform*. Yesterday i finished my code and uploaded it to the Arduino Uno. It works fine. Next day i launched the VS Code and i changed the code a bit, then i uploaded it and i got the error.

Error:

```
Tone.cpp.o (symbol from plugin): In function `timer0_pin_port':
(.text+0x0): multiple definition of `__vector_7'
NewPing.cpp.o (symbol from plugin):(.text+0x0): first defined here
collect2.exe: error: ld returned 1 exit status
*** [.pio\build\uno\firmware.elf] Error 1

```

I am using the libary `NewPing.h`. The code should does this: If is distance more than 20cm, the the buzz makes the sound and turns on the red led. If distance is less than 20cm, the blue led turns on

The code:

```
#include <Arduino.h>  //It has to be there, because the arduino ide in VS Code will not work.

#include <NewPing.h>

#define echo_pin 3
#define trig_pin 4
#define max_range 450

#define red_led_pin 7
#define blue_led_pin 9
#define buzz_pin 10

int distance = 0;

NewPing sonar(trig_pin, echo_pin, max_range);

void setup(){
  Serial.begin(9600);
  pinMode(red_led_pin, OUTPUT);
  pinMode(blue_led_pin, OUTPUT);

  pinMode(buzz_pin, OUTPUT);
}

void loop() {

  distance = sonar.ping_cm();
  delay(50);

  if (distance > 0) {
          distance = 0;

    for (int i=0; i<5; i++) {
      distance += sonar.ping_cm();
      delay(50);
    }
    distance /= 4;

    Serial.print("Distance: ");
    Serial.print(distance);
    Serial.println("cm");

    if (distance > 20) {

      digitalWrite(blue_led_pin, LOW);
      digitalWrite(red_led_pin, HIGH);
      tone(buzz_pin, 1500);
      tone(buzz_pin, 800);
    }

    else {

      digitalWrite(red_led_pin, LOW);
      digitalWrite(blue_led_pin, HIGH);
    }
  }
}

```

I don't undersand, what has changed. I tried to import again the libary https://www.arduino.cc/en/guide/libraries by importing the \*.zip file, also installing in IDE.

# Answer
You have a conflict of interrupts. Both the internal `tone()` command and the `NewPing.h` use Timer 2 by default, which makes them mutually exclusive.

However you can change `NewPing` to not use a timer by editing the `src/NewPing.h` file and setting `TIMER_ENABLED` to be `false`:

```
    #define TIMER_ENABLED true      // Set to "false" to disable the timer ISR (if getting "__vector_7" compile errors set this to false). Default=true

```
> 0 votes

---
Tags: arduino-uno, arduino-ide, library, visualstudio
---


# Question
Title: Can I emulate Arduino in a headless CI/CD setup?
6 years ago, there has been a question "How to emulate Arduino on PC".

Since then, probably many more Arduino emulators have been introduces.

With this question, I would like to narrow the search scope down to the following criteria:

* Linux compatible
* headless operation mode without UI/IDE possible to run in a CI/CD (continuous integration/delivery) system in collaborative environment where many code versions need to be merged and tested.

Do such setups exist already?

# Answer
> 1 votes
The problems with this kind of software is:

* always behind the recent releases of cores/ hw variations.
* reliable only for simple programs/tasks
* Imho all the products I tested (mainly on Win) are actually a (somewhat crippled ) teaching and visualization help.
* if you look into the emulators you mostly see only support for different chips and not the whole micro computer, which is far more complex to create

Due to the low cost of the hardware it is easier to run real HW setups with HW diagnostics (and get also feedback for thermal/electric issues)
So this kind of SW is for the low cost avr/esp HW and its hundreds of variants (even between production batches from one manufacturer) hard to develop and mantain. So you'll only find nice "play around" emulators which won't fulfill any professional requirement (even if some claim it)

---
Tags: testing, automatization
---