title: Problem communicating with ENC28J60

text:
# Question
Title: Problem communicating with ENC28J60
I want to send/receive strings to/from an ENC28J60 via a C# application. I used my own "protocol" to do this. For example I send "" to Arduino and it replies with a string containing temperature values. This method works fine in Serial communication mode, but freezes in Network mode. What am I missing here? Is there a better method to do this? I'm new to socket programming. I'm using UIPEthernet.h by ntruchsess.

My server-side (Arduino) code:

```
void checkAndReceiveFromTCPClients(){
  size_t size;
  if (EClient = EServer.available()){
    char* strIn;
    if(size = EClient.available() > 0){
      strIn = (char*)malloc(size + 1);
      memset(strIn, 0, size + 1);
      EClient.read(strIn, size);
    }
    strIn[size] = 0;
    String strInput = String(strIn);
    strInput.trim();
    //This replies to client (sends string) with a string (EClient.write(answer)):
    InterpretInputString(strInput);
    //EClient.stop();
    EClient.flush();
  }
}

```

C# code:

```
string SendAndReceiveOverNet(string Command) {
    Byte[] data = System.Text.Encoding.ASCII.GetBytes(Command);
    NetworkStream stream = TClient.GetStream();
    stream.Write(data, 0, data.Length);
    data = new Byte[256];
    String responseData = String.Empty;
    Int32 bytes = stream.Read(data, 0, data.Length);
    responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes);
    return responseData;
}

```

# Answer
Something like this is needed here. If you use stream.Read without TClient.Available, the program will freeze or crash.

C# code:

```
string SendAndReceiveOverNet(string Command) {
    Byte[] data = System.Text.Encoding.ASCII.GetBytes(Command);
    NetworkStream stream = TClient.GetStream();
    stream.Write(data, 0, data.Length);
    String responseData = String.Empty;
    Int32 size = TClient.Available;
    if (size > 0)
    {
        data = new Byte[size];
        Int32 bytes = stream.Read(data, 0, data.Length);
        responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes);
    }
    return responseData;
}

```
> 1 votes

---
Tags: networking, c#
---


title: How to loop over analog pins?

text:
# Question
Title: How to loop over analog pins?
I want to do something along the lines of

```
for (int i = 0; i < 4; i++) {
  analogRead(i);
}

```

Which appears to work, but the following does not:

```
for (int i = 0; i < 4; i++) {
  pinMode(i, INPUT);
  pinMode(i + 4, OUTPUT); // should make Analog Pin (i + 4) into an output
  digitalWrite(i + 4, LOW);
  analogRead(i);
}

```

Instead, it appears to treat the pin addressed by `digitalWrite(i + 4, LOW);` as one of the digital pins.

Do I really have to explicitly specify A0, A1, A2, ... anytime I want to loop over the analog pins?

# Answer
> 11 votes
Yes, the analog pins must be addressed using A0, A1,... when using them for digital I/O.

Depending on the board you are using A0,A1,etc. are mapped to different values (for instance it looks like A0 is 18 on some boards but 14 on others.

One solution for looping over the analog pins would be this:

```
static const uint8_t analog_pins[] = {A0,A1,A2,A3,A4};
// Setup pins for input
for (int i = 0; i < 5; i++) { //or i <= 4
  digitalRead(analog_pins[i]);
}

```

If you are using the analog pins only with the `analogRead()` call you can use 0,1,... instead of A0,A1,...

# Answer
> 5 votes
At least an Uno/Megas/leonardos, all the values mapped to analog pin numbers are consecutive, so

```
for (int i = A0; i < A4; i++) {
  pinMode(i, OUTPUT);
  digitalWrite(i, LOW);
}

```

will set A0, A1, A2, and A3 to OUTPUT, and then LOW.

# Answer
> 0 votes
Your first loop will work just fine indeed, however, you might want to add `delay(1);` after you `analogRead(i);`, to give the ADC some time to settle.

Could you elaborate on what you are trying to do with your second piece of code? As it looks right now, it doesn't really make sense to use *analog inputs* as *digital outputs*.

Besides, you're trying to read a pin's input just a couple of lines after you specified the pin to be an output.

Please explain what you are trying achieve, so the nice folks around here can you help you better.

# Answer
> 0 votes
Pins 14 through 19 are the analog pins A0 to A5. `A0` is just an alias for `14` and so on.

So another way of writing BrettM's answer:

```
for (int i = 14; i < 18 i++) {
  pinMode(i, OUTPUT);
  digitalWrite(i, LOW);
}

```

# Answer
> 0 votes
I know this is old, but if you hover your mouse over A0 to A7 in visual micro it will show you the true value, they are just a variable (it actually shows as 14U but while addressing you do not need to include the U). What Craig said is wrong, they do NOT have to be addressed by A0, A1 ect..

A0 = 14 A1 = 15 . . A7 = 21

```
//Will set all pins, digital and analog to LOW (0)
for (int i = 1; i < 22; i++) {
    digitalWrite(i, LOW);
}

//Will set all analog pins to LOW (0)
for (int i = 14; i < 22; i++) {
    digitalWrite(i, LOW);
}

//Will set all analog pins to LOW (0)
for (int i = A0; i < A7 + 1; i++) {
    digitalWrite(i, LOW);
}

```

The last for loop is basically saying i = 1 (A0), and stop on 21 (A7).

# Answer
> 0 votes
Assuming pin numbers are consecutives you can iterate them:

```
int acc = 0;
for (int Ai = A0; Ai < A0 + NUM_ANALOG_INPUTS; Ai++) {
    acc += analogRead(Ai);
}
Serial.println(acc);

```

---
Tags: programming, c++, analogread
---


# Question
Title: What kind of power cable do I need for the MKR 1010?
I see very confusing documentation on powering the Arduino MKR 1010. I would like to know what kind of cable to power it with (a weird connector port on its side).

Can I just put 5 V + (AC or DC?) on the Vin port and connect a ground?

# Answer
The documentation shows three ways of powering the board see FAQs section Batteries, Pins and board LEDs

1. Using a USB connector to provide 5V to the board. Typically, this is connected to a USB port on the PC you are using to program the board. Alternatively, a USB cable connected to a standard USB power supply could be used after the program has been loaded.
2. Using the Vin pin to supply a REGULATED 5V (maximum 6V). Of course, this is DC. Yes, you would also connect the power supply GND to the board's GND pin.
3. LiPo battery. This is a little more complicated to use safely and there is documentation on that as well - see the app note here to start. You **absolutely** need to understand how to use a battery with that board - there are safety concerns in this regard that can't be ignored.

Hope it helps.
> 0 votes

# Answer
Just if you are wondering,The mkr1010 uses Micro USB (USB-B) arduino doc says. https://docs.arduino.cc/hardware/mkr-wifi-1010
> 0 votes

---
Tags: mkr1010
---


# Question
Title: Read values from a txt file on an SD card
I'm trying to read a text file (has numeric values) from SD card. The values in the file like this

```
87 512
255

```

I need to read 87 in ch1 and 512 in ch2 and 255 in ch3.

Why did I get on 'SKIP\_NONE' 'SKIP\_WHITESPACE' was not declared in this scope?

```
int ch1 = in_file.parseInt(SKIP_WHITESPACE);
Serial.printf("First = %d \n",ch1);

int ch2 = in_file.parseInt(SKIP_NONE, '\n');
Serial.printf("Second = %d \n",ch2);

int ch3 = in_file.parseInt();
Serial.printf("Third = %d \n",ch3);

```

# Answer
These symbols were introduced in the Arduino AVR core 1.6.7, in December 2015. You can find them in Stream.h. They are probably defined in other cores too.

For some reason, the Teensy cores do not define them. You may consider filing an issue in their GitHub project.
> 3 votes

---
Tags: programming, arduino-ide, sd-card, arduino-makefile
---


# Question
Title: A fatal error occurred: Could not open /dev/ttyUSB0, the port doesn't exist (UART bridge CP2102)
I can't upload my program to ESP32-CAM. It just keeps saying the port doesn't exist. But I can see it in /dev/ttyUSB0 (By the way, I'm on linux, Fedora) The UART bridge is CP2102 Silicon Labs.

What I've tried:

* Using both IDE 1, 2
* Removing everything, trying again on IDE 1
* upgrading permissions

Any help will be appreciated.

---

After `sudo dmesg -wT | grep cp2102` as suggested by @timemage, I got this:

---

# Answer
A post by Bee\_HapBee on Reddit solved my issue! Thank you!

```
sudo chmod 666 /dev/ttyUSB0

```

> Yep, I wish esptool.py would've told me that I needed permissions, rather than the port doesn't exist
> 2 votes

---
Tags: arduino-ide, uart
---


# Question
Title: The port is not recognized when working with esp32 in arduino ide 2.2.1 (windows 11 home edition)
I'm trying to program the ESP32 board with Arduino IDE.  But The port it's not recogniized when working with esp32 in arduino ide 2.2.1. After some research I found that the port is not recognized by my operating system (WINDOWS 11 home edition). Image of Device Manager showing the message that the port is not recognized.

I installed the Silicon Labs drivers for the CP210x USB to UART Bridge. After restarting the PC, the port is still not recognized. I did a search with the command line and the driver CP210x USB to UART Bridge is not installed. CMD Line image:

I'm out of ideas how to solve this problem, some one knows how to solve this issue?

# Answer
I don't have a Stack Account yet, but i saw this and i know the answer...

1. it appears by your photo that you do indeed have a CP2102 Chip which requires the driver from here CP2102 DRIVER

This driver should be able to be installed without connecting your ESP32 Dev Board.

2. This is a driver issue, so .. do this In Device Manager (i'm going to make some assumptions because i don't know what motherboard you have or machine ) But....

* Uninstall the USB Drivers completely
* Re Install the USB Drivers
* Re Install the chipset drivers for your mainboard
* Ensure your BIOS is up to date, if not, Update it via the correct software.

After all that , Restart Your computer

* Try it again, if problem persists
* Open cmd.exe Run sfc/scannow and press enter This will run the windows System File Checker
* Try again, If problem persists
* You likely have a knock off board, They are notorious for not wanting to play nice with the drivers.

it's also possible that your computer is faulty, Try it on another computer, obviously but at the end of the day , it's more likely that you have a knock off board or you have a driver issue and things need to get updated and resolved.
> 1 votes

---
Tags: arduino-ide, esp32
---


title: Why is char being "extended" to an int?

text:
# Question
Title: Why is char being "extended" to an int?
I know I'm missing something so simple here, but I can't figure it out.

If I do `char letter = 'A';` then `letter = letter << 8`, letter = 0, as one should expect, since we are shifting the bits "off the shelf" to the left.

But, if we do this:

```
char letter = 'A';

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

  int twoBytes = letter << 8;
  Serial.println(twoBytes, BIN);

}

void loop() {}

```

The result is 100000100000000, but why? `<<` has precedence over `=`, so it should be bitshifting `letter` left by 8 first, then assigning that value (which should be 0) to `twoBytes`.

# Answer
This is a funny, non-intuitive rule of the C++ language called “integral promotion”. Simply stated, it says that no computation is ever performed on a type smaller than `int`: anything smaller gets implicitly promoted to `int` as soon as it appears in an arithmetic or logic expression.

See Implicit conversions in cppreference.com (warnings: it's hairy).
> 4 votes

---
Tags: c++, bit, bitshift
---


# Question
Title: Multiple definition error in STM32CubeIDE
How do global variable declarations work?

For example:

In file1.c I am defining:

```
#define volt_add 0x20

uint8_t vol[8]= {0x53, 0x35, 0x05, 0x22, volt_add,0x00,0x00,0x00};

uint16_t EM_vol;

```

I need to use all above variables in *file2.c*.

I tried to define them in the *global.h* file and included that file in both *file1.c* and *file2.c*, but I am getting a multiple definition error, first defined here error.

How can I do it?

# Answer
> 2 votes
If you want global variable accessible from everywhere you include global.h, you'll need declaration of that variable in header (declatation only):

```
// globals.h:
extern uint8_t vol[8];

```

Anywhere else you'll #include "global.h"

But there must be one cpp or c file with:

```
#include "global.h"
uint8_t vol[8]= {0x53, 0x35, 0x05, 0x22, volt_add,0x00,0x00,0x00};

```

If you make this definition in header or more than one .c file, you'll get multiple definition error.

Another way would be make it static and make whole definition in the header, however each compilation unit will be using it's own instance and it won't be visible from other compilation units (compilation unit == every c file compiled into own .o file). This is issue on MCUs and if you even want to write into it, it'll be total mess (although nobody uses const correctness in C)

---
Tags: variables
---


# Question
Title: ESP-IDF logging library slows down ISR processing
I'm hacking a project with ESP32-WROOM module. I'm running some timers with alarms along with some peripherals triggering ISRs. In the ISR routine I'm sending events to a queue, and receiving them in a task. Normally I'm seeing ~50 micros delay between ISR routine and the task.

I added the `esp_log` component for logging to UART. If I call some `ESP_LOGx` in the task after receiving the queue event, the aforementioned delay grows to 25 millis in some cases (depending on the amount of logging).

What's the reason? Does `esp_log` have longish `noInterrupt` sections internally? Is there any way to avoid them? Any other remedies?

Those delays are quire troublesome because on one hand I need logging to get things working. On other hand those delays turn all the timings upside down...

I actually switched to `esp_log` form hand-rolled logger. In my logger I had a 5k fifo queue for log data. The logging calls would format strings and push them into the queue. A low priority task would pop the data and print it to the UART. It was much better in terms of performance. I switched to `esp_log` for richer functionality, but ... Going back unless there is a fix.

# Answer
> 0 votes
Since your logger uses the UART, you need to take the transmission time into account.

Supposing that you use a 9600 baud line and send about 25 bytes.

A single byte has 10 bits on the wire, start bit, data bits, and at least one stop bit. There are more options to the protocol, but this is it basically.

Each bit takes 1/9600 seconds, this is the definition of 9600 baud. (Actually, this is oversimplified, but nevertheless a correct number here.) 10 bits of one byte take t\_Byte = 10 / 9600 s = 1.042 ms.

To send 25 bytes, this sums up to about 25 ms.

Lesson learned: do not log directly to UART in a time critical task. You found the common solution by queuing the bytes to send. Just make sure that the queue will not fill up in the long term.

---
Tags: esp32, isr, performance, logging
---


# Question
Title: Wolfram Mathematica reads but closes stream feeds from Arduino Serial port after a few data sets
This is a Wolfram Mathematica / Arduino serial feed problem , but I am posting here just in for any suggestions on enhancing the Arduino code or the Mathematica notebook. The original post is here Mathematica Exchange post and in here

The Arduino sketch monitor a sensor and returns a set of three intergers.

```
     #include <Wire.h>
#include "Adafruit_AS726x.h"

//create the object
Adafruit_AS726x ams;

//buffer para leer valores en bruto
uint16_t sensorValues[AS726x_NUM_CHANNELS];

//buffer para  guardar los valores calibrados( no esta siendo utilizado en este codigo)
//float calibratedValues[AS726x_NUM_CHANNELS];

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

  // inicializa el pin digital LED_BUILTIN como un output.
  pinMode(LED_BUILTIN, OUTPUT);

  //inicia y permite la comunicacion con el sensor
  if(!ams.begin()){
    Serial.println("could not connect to sensor! Please check your wiring.");
    while(1);
  }
}

void loop() {

  //lee la temperatura del sensor
  uint8_t temp = ams.readTemperature();

  //ams.drvOn(); // descomentar esto si quieres usar el led del sensor para hacer medidas
  ams.startMeasurement(); //begin a measurement

  //permite que el sensor lea la data cuando este disponible
  bool rdy = false;
  while(!rdy){
    //delay(1000);
    rdy = ams.dataReady();
  }
  //ams.drvOff(); //descomentar esto si quieres usar el led del sensor para hacer medidas

  //lee los valores!
  ams.readRawValues(sensorValues);
  //ams.readCalibratedValues(calibratedValues);

   //Serial.print("{");
  //Serial.print("Temp: ");
  //Serial.print(temp);
  //Serial.print(",");
  //Serial.print(" Violet: ");
  //Serial.print(sensorValues[AS726x_VIOLET]);
   //Serial.print(",");
  //Serial.print(" Blue: ");
  Serial.print(sensorValues[AS726x_BLUE]);
   Serial.print(",");
  //Serial.print(" Green: ");
  //Serial.print(sensorValues[AS726x_GREEN]);
   //Serial.print(",");
  //Serial.print(" Yellow: ");
   Serial.print(sensorValues[AS726x_YELLOW]);
    Serial.print(",");
  //Serial.print(" Orange: ");
  //Serial.print(sensorValues[AS726x_ORANGE]);
   //Serial.print(",");
  //Serial.print(" Red: ");
  Serial.print(sensorValues[AS726x_RED]);
  //Serial.print("}");

  Serial.println();
  //Serial.println();
  delay(400);

```

The Mathematica notebooks is

```
dev = DeviceOpen["Serial", "COM3"]

parseData[{val1__, 44, val2__, 44, val3__}] :=
 ToExpression@FromCharacterCode@# & /@ {{val1}, {val2}, {val3}}
parseData[___] := Sequence[]
rawReadings = {}
task = SessionSubmit[
  ScheduledTask[
   AppendTo[rawReadings,
    DeviceReadBuffer[dev, "ReadTerminator" -> 10]], {1, 100},
   "AutoRemove" -> True]]
test1 = parseData /@ rawReadings
ListLinePlot[Transpose[parseData /@ rawReadings],
  PlotLegends -> Automatic] // Dynamic
DeviceClose[dev]

```

But the Notebooks is not returning a dynamic feed of data from Arduino. It closes and not able to determine why. It is suppose to stream a feed continously.

# Answer
> 0 votes
Jose! As I already mentioned in Mathematica SE, you need to remove the delay statements out of your code and additionally send the data to serial only if new data has arrived.

---
Tags: serial, matlab
---


title: Copying String into another String

text:
# Question
Title: Copying String into another String
I have an array of Strings in my code:

```
String BitSequence [257];

```

Each string will have 23~64 characters. At one point in my code, I have to use "myString.remove()" command and I don't want to apply any changes to my original strings. I need to make a copy and perform my commands on the copied string. I did:

```
MycopyString = BitSequence [1];

```

but it doesn't work. What tricks do I need to do here to make a copy?

# Answer
> 2 votes
Do not work with the String class on Arduino. That said what to do?
Use char arrays (what an individual String is internally). Then you work with pointers or pointers to pointers. Guessing from the fragments (what type is MycopyString?) you gave, you create a pointer (?) to the element in the array.
Working with String class has two disadvantages.

* You have to look into the lib to see what a function really does and
* by reserving and releasing memory it fractures on the long (most of the time short) run your heap causing your AVR/ESP to crash.

The possibility to create two dimensional arrays

```
i = 257;
char myTwoDimArray [i][64] = {'\0','\0'}// 64 ... 63 chars + 1 terminator(!)

```

and then you operate with pointers either to the entry (i) or in the specified char array itself.

How to remove an entry You just write:

```
i = 23;
myTwoDimArray [i][0] = '\0';

```

by writing a zero terminator to the first index (starts with 0) of the 24th (!) element (again the index starts with 0) its deleted.

Commands to look for when operating with chars

```
strcpy (targetChar, charToAdd); // Initializes the targetChar starts at index 0
strcat (targetChar, charToAdd); // Appends to the targetChar starts at current index

```

converting numeric values to chars:

```
  char numBuffer [16] = {'\0'}; // Helper buffer for conversions

 itoa (myNumberValue,numBuffer,10);  // converts an integer to a base 10 (decimal) char
itoa (myNumberValue,numBuffer,2);  // converts an integer to a base 2 (binary) char
itoa (myNuberValue,numBuffer,16);  // converts an integer to a base 16 (hex) char

```

itoa initilizes a char array so we need the helper array:

```
strcat (targetChar, numBuffer);

```

to convert float we use

```
dtostrf(floatVariable, StringLengthIncDecimalPoint, numVarsAfterDecimal, numBuffer);

```

to convert chars back to int use

```
int16_t myIntVar = atoi(numBuffer);

```

to convert chars back to floats use

```
float myFloatVar = atof(numBuffer, decimalsToShow); // using just atof(numBuffer)
gives you standard x.XX only 2 decimals

```

Hope this comprehensive intro to chars helps you for your current and future projects.

# Answer
> 1 votes
> I don't want to apply any changes to my original strings

You should read about PROGMEM and/or the \__FlashStringHelper ( F-Macro ) . Probably you can even handle that vast amount of constant texts on your Nano controller, which is meant to be a controller, not a text processing computer.

# Answer
> -1 votes
Thank you for all the helpful answers. I think also found a way to copy strings. Using "myString.substring(from,to)" I could resolve my problem. The command works on array strings as well.

```
mynewcopystring =mystring[2].substring(0,mystring[2].length());

```

# Answer
> -1 votes
String has a constructor that takes other strings.

```
String mycopyString(BitSequence[1]);

```

will create a new String object named mycopyString with its value initialized to the value of `BitSequence[1]`.

See https://www.arduino.cc/reference/en/language/variables/data-types/stringobject/ for more details

---
Tags: string, arduino-nano-ble
---


# Question
Title: Lora SX1278 stops receiving after a short time
I am working with two Lora ra-02 sx1278 modules and two Arduino Uno. Programming on Arduino IDE 2.1.1

sender

receiver

The problem is the receiver receives a few packets successfully, but then the board no longer receives the signal. I know the sender is sending data constantly because the RX LED on Arduino blinks. Every time I reset the receiver board, it starts receiving again and then stops after a few packets.

I have this problem when running the basic send and receive example of the Lora library itself. Here's the library I'm using from Arduino IDE libraries: link of the Lora library (I just changed the frequency to 433 for my area, and reduced the delay of sending packets from 5 seconds to 1 second)

I couldn't find anything helpful on the internet. Any suggestions?

Update: My project is a hand-gesture-controlled car. I uploaded the project's program on boards. With this code, if the command to the robot car is "stop", it receives some packets every 1 second and then after an acceptable time, doesn't receive anymore. But if I move my hand so it sends move commands to the car, it receives the move command and motors work but it doesn't receive the next packet. When I detached the motor drivers from Arduino, it received at least 15-20 packets. Apparently, it receives packets but after motor drivers and motors work, it suddenly doesn't receive anything. I'm confused.

Sender:

```
#include <SPI.h>
#include <LoRa.h>
#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#include <Wire.h>

int counter = 0;
String msg = "";
int xdata = 0;
int ydata = 0;
int flag=0;
Adafruit_MPU6050 mpu;

void setup() {
  Serial.begin(9600);
  while (!Serial)
  Serial.println("LoRa Sender");
  if (!LoRa.begin(433E6)) {
    Serial.println("Starting LoRa failed!");
    while (1);
  }
  if (!mpu.begin()) {
    Serial.println("Failed to find MPU6050 chip");
    while (1) {
      delay(10);
    }
  }
  Serial.println("MPU6050 Found!");
  LoRa.setTxPower(10);
}
void loop() {
  sensors_event_t a, g, temp;
  mpu.getEvent(&a, &g, &temp);
  xdata = a.acceleration.x;
  ydata = a.acceleration.y;
  Serial.println(counter);

  if((xdata>2)&&(flag==0))
  {
    flag=1;
    msg = "l";
    Serial.println("l");
    }
  if(xdata<-2 && flag==0)
  {
    flag=1;
    msg = "r";
    Serial.println("r");
    }
  if(ydata>2 && flag==0)
  {
    flag=1;
    msg = "b";
    Serial.println("b");
    }
  if(ydata<-2 && flag==0)
  {
    flag=1;
    msg = "f";
    Serial.println("f");
    }
  if((xdata<2)&&(xdata>-2)&&(ydata<2)&&(ydata>-2)&&(flag==1))
  {
    flag=0;
    msg = "s";
    Serial.println("s");
    }

  LoRa.beginPacket();
  LoRa.print(counter);
  LoRa.print(msg);
  LoRa.endPacket();
  counter++;
  delay(1000);
}

```

Receiver:

```
#include <SPI.h>
#include <LoRa.h>

int motor1pin1 = 3;   //front left
int motor1pin2 = 4;
int motor2pin1 = 5;   //front right
int motor2pin2 = 6;
int motor3pin1 = A0;  //back right
int motor3pin2 = A1;
int motor4pin1 = A2;  //back left
int motor4pin2 = A3;
String  msg="";

void setup() {
  pinMode(motor1pin1, OUTPUT);
  pinMode(motor1pin2, OUTPUT);
  pinMode(motor2pin1, OUTPUT);
  pinMode(motor2pin2, OUTPUT);
  pinMode(motor3pin1, OUTPUT);
  pinMode(motor3pin2, OUTPUT);
  pinMode(motor4pin1, OUTPUT);
  pinMode(motor4pin2, OUTPUT);

  Serial.begin(9600);
  while (!Serial);

  Serial.println("LoRa Receiver");

  if (!LoRa.begin(433E6)) {
    Serial.println("Starting LoRa failed!");
    while (1);
  }
}

void loop() {
  // try to parse packet
  int packetSize = LoRa.parsePacket();
  yield();
  if (packetSize) {
    // received a packet
    Serial.print("Received packet '");
    // read packet
    while (LoRa.available()) {
      msg=(char)LoRa.read();
      Serial.print(msg);
    }
    //Serial.println(msg);
    if(msg=="f")
    {
      digitalWrite(motor1pin1, HIGH);
      digitalWrite(motor1pin2, LOW);
      digitalWrite(motor2pin1, HIGH);
      digitalWrite(motor2pin2, LOW);
      digitalWrite(motor3pin1, HIGH);
      digitalWrite(motor3pin2, LOW);
      digitalWrite(motor4pin1, HIGH);
      digitalWrite(motor4pin2, LOW);
      Serial.println(" :  Forward");
    }
    else if(msg=="b")
    {
      digitalWrite(motor1pin1, LOW);
      digitalWrite(motor1pin2, HIGH);
      digitalWrite(motor2pin1, LOW);
      digitalWrite(motor2pin2, HIGH);
      digitalWrite(motor3pin1, LOW);
      digitalWrite(motor3pin2, HIGH);
      digitalWrite(motor4pin1, LOW);
      digitalWrite(motor4pin2, HIGH);
      Serial.println(" :  Back");
    }
    else if(msg=="l")
    {
      digitalWrite(motor1pin1, LOW);
      digitalWrite(motor1pin2, HIGH);
      digitalWrite(motor2pin1, HIGH);
      digitalWrite(motor2pin2, LOW);
      digitalWrite(motor3pin1, HIGH);
      digitalWrite(motor3pin2, LOW);
      digitalWrite(motor4pin1, LOW);
      digitalWrite(motor4pin2, HIGH);
      Serial.println(" :  Left");
    }
    else if(msg=="r")
    {
      digitalWrite(motor1pin1, HIGH);
      digitalWrite(motor1pin2, LOW);
      digitalWrite(motor2pin1, LOW);
      digitalWrite(motor2pin2, HIGH);
      digitalWrite(motor3pin1, LOW);
      digitalWrite(motor3pin2, HIGH);
      digitalWrite(motor4pin1, HIGH);
      digitalWrite(motor4pin2, LOW);
      Serial.println(" :  Right");
    }
    else if(msg=="s")
    {
      digitalWrite(motor1pin1, LOW);
      digitalWrite(motor1pin2, LOW);
      digitalWrite(motor2pin1, LOW);
      digitalWrite(motor2pin2, LOW);
      digitalWrite(motor3pin1, LOW);
      digitalWrite(motor3pin2, LOW);
      digitalWrite(motor4pin1, LOW);
      digitalWrite(motor4pin2, LOW);
      Serial.println(" :  Stop");
    }
    LoRa.receive();
  }
}

```

# Answer
> 0 votes
The first thing that comes to mind is that the delay between sends is too short. Not only are you flooding the airwaves with your packets (fair use, 1% airtime and all that), but after a few packets your receiver might not be able to keep up and start missing packets.

Also, there's the definite possibility that another device in the neighourhood is sending packets too, and interferes with your transmission. You are after all on the standard 433 MHz frequency, with default settings.

Try:

* Change frequency to something less crowded.
* Change SF / BW to something less standard.
* Set delay between pings to around 30 seconds.
* Depending on the LoRa library you are using, consider using CAD, Channel Activity Detection.

I just saw you are using the arduino-LoRa library. It has CAD, not in the master branch, but in a separate branch.

---
Tags: arduino-uno, lora
---


# Question
Title: LoRa Ra-02 Module begin and beginPacket not working in Arduino Nano
Here there, recently I am testing **Lora Ra-02 module** I saw many videos and it is easy to set up, according to this schematic:

> LoRa SX1278 Module-----Arduino Nano Board
>
> 3.3V-------
>
> Gnd---------Gnd
>
> En/Nss------D10
>
> G0/DIO0------D2
>
> SCK---------D13
>
> MISO----------D12
>
> MOSI----------D11
>
> RST-------------D9

I am using a very common library called sandeepmistry. and I tried this code:

```
#include <SPI.h>
#include <LoRa.h>

int counter = 1;

void setup() {
  Serial.begin(9600);
  while (!Serial);
  Serial.println("LoRa Sender");
  if (!LoRa.begin(433E6)) {
    Serial.println("Starting LoRa failed!");
    while (1);
  }
}

void loop() {
  Serial.print("Sending packet: ");
  Serial.println(counter);
  // send packet
  LoRa.beginPacket();
  LoRa.print("hello ");
  LoRa.print(counter);
  LoRa.endPacket();
  counter++;
  delay(500);
}

```

When I run it, it just sticks in this line {Serial.println("**Starting LoRa failed!**");}

Then I updated the code and tried to reduce the SPI Frequency because I am using **Arduino Nano** now the code is this:

```
#include <SPI.h>
#include <LoRa.h>

int counter = 1;
int frequency = 8E6; // Set the desired frequency here

void setup() {
  Serial.begin(9600);
  while (!Serial);
  Serial.println("LoRa Sender");
  LoRa.setSPIFrequency(frequency); // Add the missing semicolon here
  if (!LoRa.begin(433E6)) {
    Serial.println("Starting LoRa failed!");
    while (1);
  }
}

void loop() {
  Serial.print("Sending packet: ");
  Serial.println(counter);
  // send packet
  LoRa.beginPacket();
  LoRa.print("hello ");
  LoRa.print(counter);
  LoRa.endPacket();
  counter++;
  delay(500);
}

```

This code passes the line **Starting LoRa failed!** but it again stuck in here

> LoRa Sender Sending packet: 1

So why won't it do `LoRa.beginPacket();` and loop the code? Why does it stop here?

# Answer
> 0 votes
Have you set the pins properly? Try doing:

```
  LoRa.setPins(csPin, resetPin, irqPin);// set CS, reset, IRQ pin

```

There is a problem with the way your SX1276 is connected to the board, which is why `.begin()` returns false.

---
Tags: arduino-ide, arduino-nano, wireless, lora, arduino-esplora
---


# Question
Title: (Why is) getLocalTime() on ESP32 taking several seconds to complete successfully
This is a cross-post from https://github.com/espressif/arduino-esp32/discussions/8653 as it didn't yield any results there.

I noticed that `getLocalTime()` is consistently taking 5-10+ seconds to complete. So far I haven't been able to find the root cause.

I am testing on a ESP32-WROVER-B module. On startup the device first connects to WiFi and then tries to sync time.

```
boolean initTime() {
  struct tm timeinfo;

  log_i("Synchronizing time.");
  // Connect to NTP server with 0 TZ offset, call setTimezone() later
  configTime(0, 0, "pool.ntp.org");
  // getLocalTime uses a default timeout of 5s -> the loop takes at most 3*5s to complete
  for (int i = 0; i < 3; i++) {
    if (getLocalTime(&timeinfo)) {
      log_i("UTC time: %s.", getCurrentTimestamp(SYSTEM_TIMESTAMP_FORMAT).c_str());
      return true;
    }
  }

  log_e("Failed to obtain time.");
  return false;
}

```

```
  ...
  10:12:28.118 > [  3634][I][connectivity.h:17] startWiFi(): ...done. IP: 192.168.0.57, WiFi RSSI: -55.
- 10:12:28.118 > [  3700][I][util.h:25] initTime(): Synchronizing time.
|
->10:12:34.025 > [ 11572][I][util.h:37] initTime(): UTC time: 2023-09-19 08:12:34.
  10:12:34.037 > [ 11572][I][util.h:60] setTimezone(): Setting timezone to 'CET-1CEST,M3.5.0,M10.5.0/3'.
  10:12:34.042 > [ 11574][I][main.cpp:175] syncTime(): Current local time: 2023-09-19 10:12:34
  ...

```

In the above example it took ~6s for a "valid" timestamp to become available.

# Answer
> 1 votes
Based on the wording in the question, it appears you are requesting an NTP re-synchronizing event often. Perhaps as often as possible. Consider that most Arduino projects request an NTP re-synchronizing event once to set the local RTC. Then perhaps once a day to check if the RTC is accurate.

Keep in mind that many NTP servers defend them selves from attack by throttling the service from an IP address who utilize them excessively. This quote:

> The NTP server may throttle traffic, especially for clients making frequent requests.

... is from this web site.

---

In case you are not aware, if time is important for your Arduino project, consider adding RTC hardware. This can be set to the the local time just after the NTP re-synchronizing. From that point forward, the local RTC can provide the time. Later, it may be prudent to check the local RTC against the NTP reported time. But this is usually not necessary for days at a time for the vast majority of Arduino projects.

---
Tags: esp32, time, ntpclient
---


title: Arduino to Arduino communication

text:
# Question
Title: Arduino to Arduino communication
When I send data to an Arduino Uno via the serial monitor, the serial data goes down the same USB cable used to program the Arduino. So there must be a device on the Arduino board like a FTDI or USB-capable AVR that drives the `RXD` pin of the Arduino. So my question is: When I want two Arduino boards to communicate with each other over serial, many tutorials say just connect RX and TX on one Arduino to TX to RX on the other. So how come the device on the board that normally drives the `RXD` pin doesn't "fight" the other Arduino that is also now driving the `RXD` line?

# Answer
The Atmega16U2 that does the USB communications is connected to Rx and Tx via 1k resistors, so when communicating with another Arduino it "overpowers" the USB interface. See image:

---

By the way, note that the Tx and Rx LEDs are connected to the Atmega16U2, not the Atmega328P, so they do *not* light when doing Arduino-to-Arduino communications.

---

Measuring with an empty sketch on my Uno, the current between Tx and Gnd was 0.14 mA, not 5 mA. So that suggests that the Atmega16U2 sets the pins to high-impedance when not actually receiving data from the USB interface.

It's logical it would do that, because the 5 mA you mention (in a comment) could be a nuisance if you wanted to use that pin for something else.
> 6 votes

# Answer
If we take a look at this portion of the Arduino Uno schematic (whole schematic is located here):

... we see there are two 1K Ohm (1,000 Ohms) resistors (labeled RN4A and RN4B) between the USB to serial conversion chip on the left to the Atmel processor at center right. These allow the Rx (Receive) and Tx (Transmit) pins to be back driven by an externally connected device.
> 3 votes

# Answer
Another way to do serial communication between Arduinos is to use the SoftwareSerial library using (digital) pins of your choosing for serial communication between the Arduinos. Incidentally, it avoids interference from your computer under simple serial communication,

> The SoftwareSerial library allows serial communication on other digital pins of an Arduino board, using software to replicate the functionality (hence the name "SoftwareSerial"). It is possible to have multiple software serial ports with speeds up to 115200 bps. A parameter enables inverted signaling for devices which require that protocol.

https://docs.arduino.cc/learn/built-in-libraries/software-serial

It takes just a little preparation and understanding, but not much.

```
#include <SoftwareSerial.h>

#define rxPin 10
#define txPin 11

// Set up a new SoftwareSerial object
SoftwareSerial mySerial =  SoftwareSerial(rxPin, txPin);

void setup()  {
    // Define pin modes for TX and RX
    pinMode(rxPin, INPUT);
    pinMode(txPin, OUTPUT);

    // Set the baud rate for the SoftwareSerial object
    mySerial.begin(9600);
}

void loop() {
    if (mySerial.available() > 0) {
        mySerial.read();
    }
}

```

In this example (copied from the above/linked article), you would use the `mySerial` variable to do your Arduino to Arduino communication in the same way as you use the standard serial connection. You would also need to wire the `RX` and `TX` pins of one Arduino to the `TX` and `RX` pin of the other Arduino, respectively.

One of the benefits of learning how to use the SoftwareSerial library is that there are many communication devices that use serial connection, such as Bluetooth modules (HC-05, HC-06, and HM-10 for example), that you can now use with ease. In this case, you can replace the wires I had you add with a Bluetooth module and communication between the 2 Arduinos wirelessly. Or you can instead communicate with a mobile device with the Bluetooth module.

https://www.instructables.com/Tutorial-Using-HC06-Bluetooth-to-Serial-Wireless-U-1/

Or you could access the internet with a WiFi module over SoftwareSerial.

https://www.taintedbits.com/2017/07/21/arduino-uno-esp8266-software-serial/
> 0 votes

---
Tags: serial
---


# Question
Title: L LED on Arduino is constantly on and com is not detected
When I connect the Arduino to the computer, the L LED is constantly on and com is not detected. However, when I press the reset button, the L LED starts blinking for about 10 seconds and com appears. But then he leaves.

# Answer
Hold the Reset button down with one hand and start uploading the sketch (like, an empty sketch or the Blink sketch) with the other. Once you see "uploading" release the Reset button.
> 0 votes

---
Tags: led, arduino-leonardo
---


# Question
Title: Python script cannot connect to serial port
I want to control the LEDs with my hand, for this I used the repository https://github.com/paveldat/finger\_counter/tree/main. I want to control the LEDs with my hand, for this I used the repository. To connect to the arduino mega serial port, I use the pyserial library, here is the code to which I pass variables.

```
arduinoData = serial.Serial("com9", 9600)
arduinoData.write(bytes(str(variable), "utf-8"))

```

to control the LEDs and process data from the serial port, I wrote the following code in the Arduino IDE:

```
void setup() {
  Serial.begin(9600);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
}

void loop() {
/*
  if (Serial.available() > 0){
    serialData = Serial.read();

    for (int i = 3; i<serialData; i++){
      digitalWrite(i, HIGH);
    }
    }
*/
  if (Serial.available() > 0){
    char serialData = Serial.read();
    if (serialData == '3'){
      digitalWrite(3, HIGH);
      }
    else if (serialData == '4'){
      digitalWrite(3, HIGH);
      digitalWrite(4, HIGH);
      }
    else if (serialData == '5'){
      digitalWrite(3, HIGH);
      digitalWrite(4, HIGH);
      digitalWrite(5, HIGH);
      }
    else if (serialData == '6'){
      digitalWrite(3, HIGH);
      digitalWrite(4, HIGH);
      digitalWrite(5, HIGH);
      digitalWrite(6, HIGH);
      }
    else if (serialData == '7'){
      digitalWrite(3, HIGH);
      digitalWrite(4, HIGH);
      digitalWrite(5, HIGH);
      digitalWrite(6, HIGH);
      digitalWrite(7, HIGH);
      }
    else if (serialData == '0'){
      digitalWrite(3, LOW);
      digitalWrite(4, LOW);
      digitalWrite(5, LOW);
      digitalWrite(6, LOW);
      digitalWrite(7, LOW);
      }

    //Serial.println(serialData);
    //digitalWrite(serialData, HIGH);
    //delay(1000);
  }
}

```

when I run this code without connecting the camera and just pass the values to the serial port, then everything works. However, when I try to run this code together with the camera, the following error occurs:

```
serial.serialutil.SerialException: could not open port 'com9': PermissionError(13, 'Access denied.', None, 5)

```

The camera is a laptop webcam, I have not tested the code with the USB camera, the assumption is that the USB camera will not occupy all serial ports.

# Answer
> 0 votes
The problem with accessing the port is solved, it was busy since I tried to open it every time in a loop that receives an image and displays it on the screen. I took out the code for a cycle, but the LEDs did not start. here is the updated code:

```
import cv2
import time
import os
import serial
import HandTrackingModule as htm

wCam, hCam = 640, 480

cap = cv2.VideoCapture(0)
cap.set(3, wCam)
cap.set(4, hCam)

folderPath = "fingers" # name of the folder, where there are images of fingers
fingerList = os.listdir(folderPath) # list of image titles in 'fingers' folder
overlayList = []
for imgPath in fingerList:
    image = cv2.imread(f'{folderPath}/{imgPath}')
    overlayList.append(image)

pTime = 0

detector = htm.handDetector(detectionCon=0.75)
totalFingers = 0

def arduino_write(totalFingers):
    arduinoData = serial.Serial("com9", 9600)
    arduinoData.write(bytes(str(totalFingers+2)+"\n", "utf-8"))
    arduinoData.close()

while True:
    sucess, img = cap.read()
    img = cv2.flip(img, 1)

    img = detector.findHands(img)
    lmList, bbox = detector.findPosition(img, draw=False)

    if lmList:
        fingersUp = detector.fingersUp()
        totalFingers = fingersUp.count(1)

    h, w, c = overlayList[totalFingers].shape
    img[0:h, 0:w] = overlayList[totalFingers]

    cTime = time.time()
    fps = 1/ (cTime-pTime)
    pTime = cTime

    cv2.putText(img, f'FPS: {int(fps)}', (400, 70), cv2.FONT_HERSHEY_PLAIN, 3, (255, 0, 0), 3)
    cv2.rectangle(img, (20, 225), (170, 425), (0, 255, 0), cv2.FILLED)
    cv2.putText(img, str(totalFingers), (45, 375), cv2.FONT_HERSHEY_PLAIN, 10, (255, 0, 0), 25)

    arduino_write(totalFingers)

    cv2.imshow("Image", img)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()

```

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


# Question
Title: error: expected unqualified-id before 'if' if (send) { but all semicolons are available
I am getting a compilation error: expected unqualified-id before 'if' . Btu I have check all the semicolons . Please help finding my error. The rest of the message error reads

```
C:\Users\jecalderon\Documents\Arduino\Codigo_AS7262_Investigacion_V2\Codigo_AS7262_Investigacion_V2.ino:35:1: error: expected unqualified-id before 'if'
 if (currentMillis - previousMillis >= interval) {
 ^~
C:........\Codigo_AS7262_Investigacion_V2.ino:40:1: error: expected unqualified-id before 'if'
 if (send) {
 ^~

exit status 1

Compilation error: expected unqualified-id before 'if'

```

```
#include <Wire.h>
#include "Adafruit_AS726x.h"
//create the object
Adafruit_AS726x ams;
//buffer para leer valores en bruto
uint16_t sensorValues[AS726x_NUM_CHANNELS];
//buffer para  guardar los valores calibrados( no esta siendo utilizado en este codigo)
//float calibratedValues[AS726x_NUM_CHANNELS];
unsigned long previousMillis = 0;
const long interval = 250;
bool send = false;
void setup() {
  Serial.begin(115200);
  while (!Serial) {
    // inicializa el pin digital LED_BUILTIN como un output.
    pinMode(LED_BUILTIN, OUTPUT);

    //inicia y permite la comunicacion con el sensor
    if (!ams.begin()) {
      Serial.println("could not connect to sensor! Please check your wiring.");

    }
  }
}
void loop() {
  //lee la temperatura del sensor
  //uint8_t temp = ams.readTemperature();
  //ams.drvOn(); // descomentar esto si quieres usar el led del sensor para hacer medidas
  ams.startMeasurement();  //begin a measurement
  //permite que el sensor lea la data cuando este disponible
  unsigned long currentMillis = millis();
};
//ams.drvOff(); //descomentar esto si quieres usar el led del sensor para hacer medidas
if (currentMillis - previousMillis >= interval) {
  previousMillis = currentMillis;
  send = true;
}

if (send) {
  //lee los valores!
  ams.readRawValues(sensorValues);
  //ams.readCalibratedValues(calibratedValues);

  //Serial.print("{");
  //Serial.print("Temp: ");
  //Serial.print(temp);
  //Serial.print(",");
  //Serial.print(" Violet: ");
  Serial.print(sensorValues[AS726x_VIOLET]);
  Serial.print(",");
  //Serial.print(" Blue: ");
  Serial.print(sensorValues[AS726x_BLUE]);
  Serial.print(",");
  //Serial.print(" Green: ");
  Serial.print(sensorValues[AS726x_GREEN]);
  Serial.print(",");
  //Serial.print(" Yellow: ");
  Serial.print(sensorValues[AS726x_YELLOW]);
  Serial.print(",");
  //Serial.print(" Orange: ");
  Serial.print(sensorValues[AS726x_ORANGE]);
  Serial.print(",");
  //Serial.print(" Red: ");
  Serial.print(sensorValues[AS726x_RED]);
  //Serial.print("}");

  Serial.println();

  send = false;
}

```

# Answer
> 0 votes
Check your braces. Use Control-T to autoformat your code and the error will become apparent.

This is your entire loop function. Everything after this is is outside of the function.

```
void loop() {
  //lee la temperatura del sensor
  //uint8_t temp = ams.readTemperature();
  //ams.drvOn(); // descomentar esto si quieres usar el led del sensor para hacer medidas
  ams.startMeasurement();  //begin a measurement
  //permite que el sensor lea la data cuando este disponible
  unsigned long currentMillis = millis();
};

```

---
Tags: arduino-uno, code-review
---


# Question
Title: Arduino library or code for ESP32 to scan for Bluetooth devices?
Is there some code or library that would allow me to scan for nearby Bluetooth devices using a common ESP32 board ? I only found similar code for actual Arduino boards.

# Answer
> 1 votes
The ESP32 Arduino boards support package includes libraries for ESP32 Bluetooth and BLE. Both libraries have examples which you can find in Arduino IDE Examples menu.

# Answer
> 1 votes
https://github.com/esp32beans/ESP32-BT-exp is a Bluetooth Dual Mode (classic and BLE) scanner. ESP32-BT-exp works on the original ESP32. No other ESP32 supports BT classic mode.

---
Tags: esp32, bluetooth, library, ble
---


# Question
Title: Can't connect esp8266 via USB to Linux Mint 21.1
# What was my problem

I had a big problem with my esp8266. I couldn't upload anything to it using the Arduino IDE 2.2.1, the ttyUSB port couldn't be found.

When I plug my esp8266 into the USB Port, it shows up in the port selection in the Arduino IDE but then disappears imminently.

## dmesg | grep ch34

```
[    7.286317] usbcore: registered new interface driver ch341
[    7.286328] usbserial: USB Serial support registered for ch341-uart
[    7.286342] ch341 1-3:1.0: ch341-uart converter detected
[    7.304530] usb 1-3: ch341-uart converter now attached to ttyUSB0
[    7.804730] usb 1-3: usbfs: interface 0 claimed by ch341 while 'brltty' sets config #1
[    7.811803] ch341-uart ttyUSB0: ch341-uart converter now disconnected from ttyUSB0
[    7.811814] ch341 1-3:1.0: device disconnected

```

As shown above, the esp8266 is connecting, but then disconnects.

# Answer
> 1 votes
# The solution

https://www.linux.org/threads/ch340-driver-on-linux-mint.44961/post-204493

`sudo apt-get remove -y brltty`

Just remove the brltty package.

## What is brltty?

https://brltty.app/
"BRLTTY is a background process (daemon) which provides access to the Linux/Unix console (when in text mode) for a blind person using a refreshable braille display. It drives the braille display, and provides complete screen review functionality. Some speech capability has also been incorporated."

So as long as you don't need the abilty for displaying something on a braille display, you'll good to go wit that solution.

I hope, that this will help anyone :D I posted this here, because I was searching for that very long, so it might be useful to have short solution for that.

---
Tags: esp8266, arduino-ide, linux
---


# Question
Title: Serial Buffer stays empty as soon as it becomes empty once
I have a question regarding serial buffer readout.

At program start, I send a serial command to a sensor that 1. activates him and 2. let him send data - that works. When I unplug the sensor, the serial buffer remains empty and the program goes into the else condition of void loop. But if I connect the sensor again, the serial buffer should be filled again and the program should jump into the if condition of the void loop. But it does not.

I added the variable i because the serial buffer becomes empty too quickly and the program then sends the start command of the else condition again, even though the sensor is connected and still works. Then the readout gets mixed up...that works too.

Why doesn't the program jumps back in the if condition of void loop when the sensor gets connected again after it was disconnected some time? Then serial.available() should be bigger 0 and it should readout data?

```
#include <SoftwareSerial.h>
int i = 0;

void setup()  {
    Serial.begin(9600);
    Serial1.begin(9600);
    Serial1.write(Send Start Sequence);
    Serial1.write(Start continuously read out sensor data);
}

void loop() {
  if (Serial1.available() > 0) {
    char incomingByte = Serial1.read();
    Serial.write(incomingByte);
  i = 0;
  }
  else {
    i++;
    if (i > 5) {
      Serial1.write(Send Start Sequence);
      Serial1.write(Start continuously read out sensor data);
    }
  }
}

```

# Answer
I second Nick Gammon in recommending a time-based condition, rather than counting the loop iterations. You can do it in a non-blocking fashion though:

* keep track of when was the last time you communicated with the sensor
* if this was too long ago, resend the “start sequence” command

Note that sending the command counts as a communication event, which rearms the timer. Otherwise you would be repeatedly sending the command too fast.

```
// After this delay, assume we lost the sensor.
const unsigned long timeout = 200;

// Last time we communicated with the sensor.
unsigned long last_comm_time;

void loop() {
    // Check the clock.
    unsigned long now = millis();

    // Process incoming data.
    if (Serial1.available() > 0) {
        last_comm_time = now;
        char incomingByte = Serial1.read();
        Serial.write(incomingByte);
    }

    // Try to wake up the sensor if we lost it.
    if (now - last_comm_time >= timeout) {
        last_comm_time = now;  // count this as a communication event
        Serial1.write(start_sequence);
        Serial1.write(continuously_read_out_sensor_data);
    }
}

```

You could potentially have separate timeouts for “the sensor just stopped sending data” and “the sensor should be processing the start command we just sent”. This would be a bit more complex though, requiring some sort of state machine. If you can use a single timeout value, things are simpler.
> 1 votes

# Answer
Your loop going to 5 is going to happen extremely quickly. Instead I would do a delay, say of one second (1000 ms), maybe less. Constantly sending the start sequence my be misinterpreted if the sensor comes online in the middle of the sequence. Plus your (counting) delay would only happen once. Putting a delay in the loop would make it happen every time.

---

I suggest a different way of recovering from an unplugged sensor:

```
#include <SoftwareSerial.h>

void setup()  {
    Serial.begin(9600);
    Serial1.begin(9600);
    Serial1.write("Send Start Sequence");
    Serial1.write("Start continuously read out sensor data");
}

unsigned long lastDataReceived;

void loop() {
  if (Serial1.available() > 0) {
    char incomingByte = Serial1.read();
    Serial.write(incomingByte);
    lastDataReceived = millis ();
  }
  else {
    if ((millis() - lastDataReceived) > 5000) {
      Serial1.write("Send Start Sequence");
      Serial1.write("Start continuously read out sensor data");
      lastDataReceived = millis ();
    }
  }
}

```

What this will do is wait 5 seconds before sending out the new start sequence. At 9600 baud your loop will be a lot faster than incoming bytes. This will be more reliable.
> 0 votes

---
Tags: serial, sensors, time, timing, buffer
---


title: Arduino Leonardo Key Detector

text:
# Question
Title: Arduino Leonardo Key Detector
I want to make an arduino code on the arduino leonardo that detects when keys are being pressed and to print them to the serial monitor so I can control the arduino with the computer keyboard. I need to know how to detect keyboard presses.

# Answer
If the keyboard is plugged to the computer, there is no way the Arduino can detect the key presses. You can, however, run a program on the computer that detects those key presses and forwards that information to the Arduino.

That being said, if you goal is simply to “control the Arduino with the computer keyboard”, I suggest you run a terminal emulator on the computer. This is a program that emulates an old school computer terminal, like the classic VT100 series. You won't get individual key events this way: only characters. For example, if you press and hold `Shift`, then press `A`, then release both, the Arduino will receive a single `'A'` character through the serial port, instead of four individual key events.

On Windows, you can try Putty. On macOS and Linux, you already have a terminal emulator: you just need a communication program such as picocom to connect it to the serial port.

You could also use the Arduino serial monitor. This is, however, not a proper terminal emulator. Specifically, it doesn't send the characters you type immediately: you have to click on “Send” for that.
> 1 votes

---
Tags: arduino-leonardo
---


# Question
Title: Sparkfun ISL29125 breakout board issue with Arduino IDE with ESP32
I am working on a project where I need to get the RGB light value from surrounding ambient light.

For that I am using an ESP32 with a Sparkfun ISL29125 breakout board. I have tried to scan available/connected I2C devices addresses. I'm getting the 0x44 address in the output, which is the address of the ISL29125.

But when running the following code, I am not getting any output. I have added the library to the Arduino IDE.

I have checked all wire connections. 2 other sensors are connected to the I2C bus.

I have connected the pins as follows:

GPIO21 (ESP32) -\> SDA (ISL29125) GPIO22(ESP32) -\> SCL (ISL29125).

I'm supplying 3.3v and GND from ESP32.

I have scanned the I2C bus and getting the addresses of all connected sensors including the ISL29125.

* 0X38
* 0X44 (Address of the ISL29125)
* 0X47

Following is the source code.

```
#include <Wire.h>
#include <SparkFunISL29125.h>
SFE_ISL29125 RGB_sensor;
void setup() {
  // Initialize serial communication
  Serial.begin(115200);
  Serial.println("Hello123");
  // Initialize the ISL29125 with simple configuration so it starts sampling
  if (!RGB_sensor.init()) {
    Serial.println("Sensor Initialization Problem\n\r");
  }
}

void loop() {
  Serial.println("Hello");
  // Read sensor values (16 bit integers)
  unsigned int red = RGB_sensor.readRed();
  unsigned int green = RGB_sensor.readGreen();
  unsigned int blue = RGB_sensor.readBlue();

  // Print out readings, change HEX to DEC if you prefer decimal output
  Serial.print("Red: "); Serial.println(red,HEX);
  Serial.print("Green: "); Serial.println(green,HEX);
  Serial.print("Blue: "); Serial.println(blue,HEX);
  Serial.println();
  delay(2000);
}

```

This is the output I am getting

```
[     4][D][esp32-hal-cpu.c:244] setCpuFrequencyMhz(): PLL: 480 / 2 = 240 Mhz, APB: 80000000 Hz
Hello123
[    21][I][esp32-hal-i2c.c:75] i2cInit(): Initialising I2C Master: sda=21 scl=22 freq=100000

```

I am not getting any RGB value or the code is getting stuck in the `init()` method. Can anyone guide me? What can be the problem? What is my mistake?

# Answer
> 1 votes
The library file "SparkFunISL29125.cpp" contains this: `Wire.begin();` and I guess you want it to contain `Wire.begin(21,22)` from what you have said in a later comment. Best would be to comment out `Wire.begin();` in the library and put the corrected version in your sketch. In such a situation I'd suggest copying the .cpp and .h files of the library into the sketch folder. You also have to change this in the sketch: `#include <SparkFunISL29125.h>` to `#include "SparkFunISL29125.h"` to address the local copy.

Further, the schematic of the SparkFun ILS29125 breakout board shows that the on board I2C pullup resistors are connected via a solder jumper which by default is not bridged. You appear to have done the I2C scan test with two other devices connected and may have "benefitted" from their I2C pullup resistors. If you did the live test with the ILS29125 alone, there may have been no I2C pullup resistors in the circuit.

---
Tags: sensors, esp32, i2c
---


# Question
Title: Can’t set duty cycle to 0% with custom PWM
I'm trying to control a heating element with PWM with an Arduino Nano, but the problem is even if I set the duty cycle to 0 it gives a tiny spike.

I want to generate a square wave of 1Hz and that's why I override the default PWM registers.

Here is the code:

```
// Set up fast PWM on the Arduino Uno at 1 Hz on digital pin D9
void setup() {

    // set I/O pins
    pinMode(LDR_INPUT, INPUT);      // A0
    pinMode(HEATER_OUTPUT, OUTPUT); // D9

    // Enable the PWM output OC1A on digital pins 9
    TCCR1A = _BV(COM1A1) | _BV(WGM11);
    // Set fast PWM and prescaler of 256 on timer 1
    TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS12);
    // Set the PWM frequency to 1Hz: 16MHz/(256 * 1Hz) - 1 = 62499
    ICR1 = 62499;

    // OCR1A = 32149; // this gives me duty cycle of 50%, working fine

    OCR1A = 0;       // but this is not working

    //allow PWM timers to start
    delay(10);
}

```

For testing, I connected an LED to the PWM pin (D9) and these are the spikes from the LDR reading from analog pin A0 (I don't have an oscilloscope).

I'm getting the same results with the Nano and Uno. My IDE version is 1.8.14.

How can I fix this problem?

Here is my temperature control function:

```
void Compute()
{
    unsigned long now = millis();
    int timeChange = (now - lastTime);

    if(timeChange>=SampleTime)
    {
        /*Compute all the working error variables*/
        double error = Setpoint - temprature;

        if (error <= 0)
        {
            Output = 0;
            Serial.println("level: 0");
        }
        else if (error <= 1)
        {
            Output = 5;
            Serial.println("level: 1");
        }
        else if (error <= 2)
        {
            Output = 30;
            Serial.println("level: 2");
        }
        else if (error <= 3)
        {
            Output = 50;
            Serial.println("level: 3");
        }
        else if (error <= 10)
        {
            Output = 60;
            Serial.println("level: 4");
        }
        else if (error <= 100)
        {
            Output = 200;
            Serial.println("level: 5");
        }
        else
        {
            Output = 255;
            Serial.println("level: 6");
        }

        analogWrite(HEATER_OUTPUT, Output);
        //OCR1A = map(Output, 0, 255, 0, 62499);
        delay(10);

        lastErr = error;
        lastTime = now;
    }
}

```

The problem is that after I override the PWM registers, the `analogWrite()` seems messed up. It's not working, and for all the values of `Output`, the result is almost the same.

### UPDATE 22/06/2021

I'm still struggling to fix this, if I use `analogWrite()` or `digitalWrite()` to turn off the PWM pin, the further changes on `OCR1A` regs are not taking action. whatever values I gave to the OCR1A the pin remains low, if I manually make the pin high with digitalWrite or analogWrite the pin remains high forever the changes on `OCR1A` are not taking into action.

I wrote a test function

```
void testPWM3() {

    Serial.println("f: 1Hz | on 0s");
    digitalWrite(HEATER_OUTPUT, LOW); // turn off the pwm pin to get full of (0% duty cycle)
    delay(5000);
    /*
     After turning off the pin with digitalWrite() further changes on OCR1A reg are not taken into action
    */
    digitalWrite(HEATER_OUTPUT, HIGH);
    Serial.println("f: 1Hz | on 125ms");
    OCR1A =  1953;
    delay(5000);

    Serial.println("f: 1Hz | on 250ms");
    OCR1A =  3906;
    delay(5000);

    Serial.println("f: 1Hz | on 500ms");
    OCR1A =  7812;
    delay(5000);

    Serial.println("f: 1Hz | on 1sec");
    digitalWrite(HEATER_OUTPUT, HIGH);  // this works
    delay(5000);
}

```

Any advice on this will be greatly helpful, thank you

# Answer
> 7 votes
That is how it is supposed to be. In this fast PWM mode, the duty cycle is `(OCR1A+1)/(ICR1+1)`. If you want a duty cycle of zero, you have to disengage the PWM and turn the pin to `OUTPUT` `LOW`.

This is what the Arduino's `analogWrite()` does: it treats the value 0 as a special case. Note that 255 is also treated as a special case, although that is not useful.

**Edit 1**: about `analogWrite()` being messed up.

`analogWrite(9, value)` sets `OCR1A` to a value between 1 and 254 (0 and 255 being handled in a different manner). The duty cycle you get is, as I wrote before `(OCR1A+1)/(ICR1+1)`. This is **not** what your test function expects.

I suggest you ditch `analogWrite()` and instead set directly `OCR1A`.

**Edit 2**: Once you have taken control of a PWM channel at low-level, by writing directly to the hardware registers, you should **not** use the Arduino functions `digitalWrite()` nor `analogWrite()` on the associated pin. These functions assume those hardware registers are controlled solely by the Arduino core, and they will fiddle with them in a way that will likely break your program.

To set the duty cycle to zero, disable the PWM mode and set the pin to LOW:

```
TCCR1A &= ~_BV(COM1A1);  // disable PWM on pin OC1A = PB1
PORTB  &= _BV(PB1);      // set PB1 to LOW

```

# Answer
> 0 votes
Fast PWM works that way, on Duty Cycle 0% the Output is set to high for 1 cycle at TOP+1 for non-inverted PWM mode and to low for inverted mode. If you want to have a continuous low output, you have to use Phase Correct or Phase and Frequency Correct PWM.

---
Tags: arduino-uno, arduino-nano, pwm
---


title: avrdude ser_open() can't set com-state

text:
# Question
Title: avrdude ser_open() can't set com-state
When trying to upload the blink sketch to my (unofficial) Arduino Uno, I get the following error:

```
avrdude ser_open() can't set com-state for "\\.\COM3"

```

I have programmed this Arduino before using this same laptop, but not for quite some time. I have not changed anything in the Arduino IDE in this time.

I have tried the following:

None of the above fixed the issue and all gave the same error as shown above (except when trying different USB ports which showed the error just for different COM ports).

EDIT: Just tried both the Uno and Nano on another computer and both worked fine. This confirms that both the arduinos and cables I'm using are working properly.

# Answer
> 10 votes
Maybe a Windows driver problem. Do your uno and nano use a ch340? (It is the component translating USB to uart (serial pins of atmega328). Windows has no software way to differenciate boards using this component. It is a common use on cheap clones to lower price. Official arduinos use a second atmega (atmega16u2 natively supporting usb) instead of the ch340. Allowing windows to identify the arduino model.

You should try to update your ch340 driver as you have the same problem with the 2 boards. here is the download page of the manufacturer (ch341ser.exe is the package you want)

You can also try to connect your board to an usb2 port as some problems (and solutions to try) are posted here (arduino forum) And even try to use an usb2 hub...

# Answer
> 2 votes
I had the same problem, open the port under COM and LPT in your device manager. Then roll back driver so the PC uninstalls all updates to the driver. At this point uploading the code will give the "Windows does not recognize driver" or some error like that. Now just unplug and plug the UNO back in and update driver. This solved the problem for me. Hope this helps :)

# Answer
> 0 votes
I had the same problem. I was able to upload a simple Blink example, but not my own program. And I thought there's no problem in my program, since I successfully tested it on other Arduino before. But actually, that was the problem. I had this in my program (for console logs):

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

```

Then I read that different Arduinos use different baud rates. Originally I tested it on Arduino Mega, but this time I wanted to upload it to "unofficial" Arduino Nano (for which you have to use `ATmega328P (Old Bootloader)` option when uploading).

Since I didn't need debug logs in my program anymore, I removed these 'Serial' commands completely. Then it got uploaded without problems.

A short article on this topic

# Answer
> -1 votes
I have the same problem. I found it related to the card and not the PC. The offending card uses processor ATMEGA328P\_U\_TH (Image 1). The successful card uses a different processor ATMEGA328P\_U (Image 2). I have NOT found a way to use the ATMEGA328P\_U\_TH card. It will not correctly connect to a PC and allow code to download from IDE to card.

Image 1

Image 2

---
Tags: arduino-uno, arduino-ide, arduino-nano, avrdude
---


# Question
Title: avrdude: ser_open(): can't set com-state for "\\.\COM2"
I have an unofficial Arduino Uno.

I've tested these:

> * Testing on USB 2.0 and USB 3.0
> * Changing Port (COM XX)
> * Updating drivers for the Unknown device to Arduino Uno (COM XX)
> * Resetting Arduino Board
> * Plug/Unplug
> * 1x PC Reboot
> * Burning bootloader
> * Changing 'Programmer'
> * Uninstalling-Reinstalling device
> * Holding the "Reset" button while I Upload
> * Testing different examples (Blinking/Voltage Serial Read)
> * Testing different "Board" in Arduino software (just in case, you never know)
> * Removing jump wires

Does anyone have any suggestion more than I just tried?

# Answer
> 2 votes
The board you have uses the CH340G chip instead of an ATMega16U2 or FTDI FT232R chip.

It requires special drivers, not the ones that come with the IDE.

Why do they use that chip instead of the proper one? Simply because it's dirt cheap. They are the cheapest of the cheapest of the cheapest USB chips around. They frequently die. You might want to save up and invest in a genuine Arduino at some point, because that one may well die out of the blue.

# Answer
> 1 votes
I had the same problem with the cheap nano from Amazon Longrunner. At first, it worked, I could program it. Then, I farted around with my COM port numbers because I was tired of being in the COM14 area. Since that moment, it stopped working. IDE couldn't find the port COM3. After reading you guys, I also noticed that the device was identified RAMPS which it wasn't before. I updated the driver which didn't work; it told me I was already with latest driver. So I deleted that driver and reconnected my Nano and lord and behold, the new driver USB-SERIAL CH340 installed and everything was fine. El cheapo still works. I don't care to pay more just for the USB chip which I will use only once. The uP is still up to par.

# Answer
> -1 votes
I had the same problem. I was able to upload a simple Blink example, but not my own program. And I thought there's no problem in my program, since I successfully tested it on other Arduino before. But actually, that was the problem. I had this in my program (for console logs):

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

```

Then I read that different Arduinos use different baud rates. Originally I tested it on Arduino Mega, but this time I wanted to upload it to "unofficial" Arduino Nano (for which you have to use `ATmega328P (Old Bootloader)` option when uploading).

Since I didn't need debug logs in my program anymore, I removed these 'Serial' commands completely. Then it got uploaded without problems.

A short article on this topic

---
Tags: arduino-uno
---


title: DHT11's data on MAX7219 reads 0

text:
# Question
Title: DHT11's data on MAX7219 reads 0
I want print data from a DHT11 (temperature and humidity) on a MAX7219 LED display but it only shows 0. Serial monitor, on the other hand, shows both humidity and temperature which means that my circuit works just fine and there's something wrong with code. Could anyone please point out what needs to be fixed to make it work? Thanks.   Here is the code

```
#include <WiFi.h>
#include <NTPClient.h>
#include <DHT.h>
#include <WiFiUdp.h>
#include <MD_Parola.h>
#include <MD_MAX72xx.h>
#include <SPI.h>
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
//#define HARDWARE_TYPE MD_MAX72XX::GENERIC_H
#define MAX_DEVICES 4
#define CLK_PIN   5
#define DATA_PIN  7
#define CS_PIN    6
MD_Parola Display = MD_Parola(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP);
const char* ssid     = "6666";
const char* password = "6666";
String Time, hour, minute;
String Formatted_date;
long currentMillis = 0;
long previousMillis = 0;
int interval = 1000;
#define DHTPIN  A2         /*Signal pin for DHT11 Sensor*/
#define DHTTYPE    DHT11
DHT dht(DHTPIN, DHTTYPE);
void setup() {
  Serial.begin(115200);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print("Connecting.");
  }
  Serial.println("");
  Serial.println("WiFi connected.");
  timeClient.begin();
  timeClient.setTimeOffset(0);

  Display.begin();
  Display.setIntensity(0);
  Display.displayClear();

   dht.begin();
   Serial.println("Status\tHumidity (%)\tTemperature (C)");
}
void loop()
 {
   obtainTime();
}
void obtainTime() {
  while(!timeClient.update()) {
    timeClient.forceUpdate();
  }
  currentMillis = millis();
  if (currentMillis - previousMillis > interval)  {
previousMillis = millis();
Formatted_date = timeClient.getFormattedDate();
Serial.println(Formatted_date);
hour = Formatted_date.substring(11, 13);
minute = Formatted_date.substring(14, 16);

Time = hour + ":" + minute;
Serial.println(Time);
Display.setTextAlignment(PA_CENTER);
Display.print(Time);

delay(3000);
// The DHT11 returns at most one measurement every 3s
  float h = dht.readHumidity();
  //Read the moisture content in %.
  float t = dht.readTemperature();
  //Read the temperature in degrees Celsius

Serial.println(t);
Serial.println(h);
Display.setTextAlignment(PA_CENTER);
Display.print(t);
delay(5000);
Display.displayClear();

}

}

```

# Answer
> 3 votes
It turned out that MD\_Parola can't handle floats directly. I fixed the problem by converting the floats t and h into strings using dtostrf()

```
 float h = dht.readHumidity();
 float t = dht.readTemperature();

char temp_result[6];
dtostrf(t,2,1,temp_result);

char hum_result[6];
dtostrf(h,2,0,hum_result);
Serial.println(t);
Serial.println(h);
Display.setTextAlignment(PA_CENTER);
//Display.print(temp_result);
Display.print((String)temp_result+" "+"C");
delay(5000);
//Display.print(hum_result);
Display.print((String)hum_result+" "+"%");
delay(5000);

```

---
Tags: max7219, dht11, arduino-uno-r4-wifi
---


title: Arduino MKR WiFi 1010 memory management

text:
# Question
Title: Arduino MKR WiFi 1010 memory management
according to the official documentation of the Arduino, the SRAM memory (which is allocated for the local variables) should be automatically released after calling any function. For example, I have a function `memory_allocate_test2`, which declares a large char array and this function is called in the loop(). I expect, that every time, after the function `memory_allocate_test2` is executed, the SRAM memory that I allocated for the local variables within that function should be freed or released. However, it is not working like that. When I call that function in a loop() the microcontroller hangs and stops working because it runs out of the available SRAM memory. Let me provide an example code:

```
void setup() {
  //Initialize serial and wait for port to open:
  Serial.begin(9600);

  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only - development mode. It has to be removed when releasing to live!!!
  }
}

void loop() {
  delay(2000);
  memory_allocate_test2();
}

void memory_allocate_test2() {
  Serial.println("memory_allocate_test2 STARTING ");
  display_freeram();
  Serial.println("------------------------------------------------------------");
  Serial.println("Allocating the memory for the MKR: ");
  char* memory_usage_test = new char[2000];
  Serial.println("Allocated memory!");
  display_freeram();
  Serial.println("------------------------------------------------------------");
}

extern "C" char* sbrk(int incr);

void display_freeram(){
  Serial.print(F("- SRAM left: "));
  Serial.println(freeRam());
}

int freeRam() {
  char top;
  return &top - reinterpret_cast<char*>(sbrk(0));
}

```

why it doesn't work as it states in the documentation? what I'm doing wrong? why the SRAM memory is not released each time after the `memory_allocate_test2` function execution?

https://www.seeedstudio.com/blog/2021/04/26/managing-arduino-memory-flash-sram-eeprom/

when I execute that program, here is what happens:

memory\_allocate\_test2 STARTING

* SRAM left: 7163

---

Allocating the memory for the MKR: Allocated memory!

* SRAM left: 5155

---

memory\_allocate\_test2 STARTING

* SRAM left: 5155

---

Allocating the memory for the MKR: Allocated memory!

* SRAM left: 3147

---

memory\_allocate\_test2 STARTING

* SRAM left: 3147

---

Allocating the memory for the MKR: Allocated memory!

* SRAM left: 1139

---

memory\_allocate\_test2 STARTING

* SRAM left: 1139

---

Allocating the memory for the MKR: Allocated memory!

* SRAM left: -869

---

memory\_allocate\_test2 STARTING

* SRAM left: -869

---

Allocating the memory for the MKR:

at that point the device just hangs and stops working. That's not what I expect!

since the functionality differs for each board and microcontroller, here are my specs: the board name is "**Arduino® MKR WiFi 1010**", the microcontroller name is "**SAMD21 Cortex®-M0+ 32bit low power ARM MCU**"

# Answer
> 1 votes
You are mixing two different ways of memory allocation.

The automatic memory allocation and release you cite works with defined local variables. These variables are allocated on the stack. At the end of their scope, their memory is released. To mimic your example:

```
void memory_allocate_test3() {
  Serial.println("memory_allocate_test3 STARTING ");
  display_freeram();
  Serial.println("------------------------------------------------------------");
  Serial.println("Allocating the memory for the MKR: ");
  char memory_usage_test[2000] = "Some content...";
  Serial.println("Allocated memory!");
  display_freeram();
  Serial.println("------------------------------------------------------------");
}

```

But what you use is heap-allocated memory because of the `new` operator. This kind of allocation is under complete responsibility of the programmer, this is you. Since you only allocate and never release, each loop reduces the remaining RAM. Use `delete` (actually `delete[]`) to release:

```
void memory_allocate_test2() {
  Serial.println("memory_allocate_test2 STARTING ");
  display_freeram();
  Serial.println("------------------------------------------------------------");
  Serial.println("Allocating the memory for the MKR: ");
  char* memory_usage_test = new char[2000];
  Serial.println("Allocated memory!");
  display_freeram();
  Serial.println("------------------------------------------------------------");
  delete[] memory_usage_test;
}

```

---

**Beware:** There are different allocation methods, `malloc`/`calloc`/`alloca`/`free` and `new`/`delete`. The former method uses functions of the C standard library, the latter method uses keywords of C++.

The pointers returned by the different methods are not compatible. You cannot release memory by `free` that you allocated by `new`. The same holds true for `delete`/`malloc`.

However, you can use both methods in the same program.

Please learn about memory allocation before attempting to use it. C and C++ are error-prone to the unsuspecting user.

As a side note, C and C++ are different languages, even though you can build a mixed program.

---
Tags: arduino-mkr, mkr1010wifi
---


# Question
Title: The code is showing same angles for all three axis in the mpu gyro. can anyone solve it so that it works
```
#include<avr/io.h>
float x, y, z, baf = 0, j, i = 0, k, angle, a, b, c, d;
unsigned long current_time = 0;
unsigned long previous_time = 0;
unsigned long time_interval = 0;
float gyro_offset_x = 0.0;
float gyro_offset_y = 0.0;
float gyro_offset_z = 0.0;

void i2cinit(void)
{
  TWSR = 0x00;
  TWBR = 0x14;
  TWCR = (1 << TWEN);
}

void i2cstart(void)
{
  TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN);
  while (!(TWCR & (1 << TWINT)));
}

void i2cwrite( unsigned char data)
{
  TWDR = data;
  TWCR = (1 << TWINT) | (1 << TWEN);
  while (!(TWCR & (1 << TWINT)));
}

unsigned int i2c_receive(unsigned char isLast) {
  if (isLast == 0)
  {
    TWCR |= (1 << TWINT) | (1 << TWEA) | (1 << TWEN);
  }
  else
  {
    TWCR = (1 << TWINT) | (1 << TWEN);
  }
  while (!(TWCR & (1 << TWINT)));
  return TWDR;
}

void i2cstop(void)
{
  TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);

}

void mpu6050_init(void) {
  i2cstart();
  i2cwrite(0xD0);
  i2cwrite(0x6B); // PWR_MGMT_1 register
  i2cwrite(0);
  i2cstop();
}
void mpu6050f()
{
  i2cstart();
  i2cwrite(0xD0);
  i2cwrite(0x1B);
  i2cwrite(0x00);// changed here
  i2cstop();
}
float mpu6050rbyte(int gyro) {
  i2cstart();
  i2cwrite(0xD0);
  i2cwrite(gyro);
  i2cstart();
  i2cwrite(0xD0 | 0x01);
  float i = i2c_receive(1);
  i2cstop();
  return i;
}
float mpu6050_whole_data(int a, int b) {
  int msb = mpu6050rbyte(a);
  int lsb = mpu6050rbyte(b);
  float x_gyro = (msb << 8) | lsb;

  return x_gyro;
}

void calibrateGyroOffset() {
  const int numSamples = 100;
  for (k = 0; k < numSamples; k++) {
    gyro_offset_x += mpu6050_whole_data(0x43, 0x44);
    gyro_offset_y += mpu6050_whole_data(0x45, 0x46);
    gyro_offset_z += mpu6050_whole_data(0x47, 0x48);
  }

  gyro_offset_x /= numSamples;
  gyro_offset_y /= numSamples;
  gyro_offset_z /= numSamples;
}

float mpu6050angle(float woho, float gyro) {
  float angular_velocity = (woho - gyro) / 131.0;
  previous_time = current_time;
  current_time = millis();
  time_interval = (current_time - previous_time);
  float filter = (0.98 * angular_velocity) + (0.04 * angular_velocity);
  float angle = baf + (filter * time_interval) / 1000.0;
  baf = angle;
  return angle;
}

void setup()
{
  Serial.begin(9600);
  i2cinit();
  mpu6050_init();
  mpu6050f();
  calibrateGyroOffset();
}
void loop()
{
  x = mpu6050_whole_data(0x43, 0x44);
  y = mpu6050_whole_data(0x45, 0x46);
  z = mpu6050_whole_data(0x47, 0x48);
  //  a = mpu6050angle(y, gyro_offset_msb);
  //  b = mpu6050angle(z, gyro_offset_lsb);
  j = mpu6050angle(x, gyro_offset_x);
  c = mpu6050angle(y, gyro_offset_y);
  d = mpu6050angle(z, gyro_offset_z);
  //  mpu6050r(0x43, &x, &y, &z);
  // mpu6050_init();
  //  Serial.print("Offset x");
  //    Serial.print(gyro_offset_x) ;
  //    Serial.print("      ");
  //  Serial.print("Offset y");
  //  Serial.print(y) ;
  //  Serial.print("      ");
  //  //  Serial.print("Offset z");
  //  Serial.print(z) ;
  //  Serial.print("      ");
  Serial.print("Angle x: ");
  Serial.print(j);
  Serial.print("      ");
  Serial.print("Angle y: ");
  Serial.print(c);
  Serial.print("      ");
  Serial.print("Angle z: ");
  Serial.println(d);
}

```

# Answer
*There may be a number of problems with this code. I will try to edit this answer as you provide feed back. The goal is a workable answer. To be clear, some here may, but it is up to you to fix your code.*

* Dead Reckoning is difficult. Any errors accumulate over time. A gyroscope is usually used as part of a sensor fusion with an Accelerometer or Magnetometer. This allows the gyroscope absolute reading to be corrected or reset to mitigate accumulated error. If sensor fusion is not available, then the gyroscope calibration will be very important in mitigating as much drift as possible.
* Constrain the problem to make it simple. Initially, constrain the gyroscope movements such that only the X axis is rotated. For example, only rotate the gyroscope on a stable table top. This way, only the X data need be considered / shared as this problem is discussed.
* Consider finding the gyroscope offset as the first step. The calibration function does not appear to have a time delay as does the normal sampling code. If the calibration function samples the gyroscope as fast as possible, the offsets may be too small or even zero and little use later when applying them to the gyroscope samples.
> 0 votes

---
Tags: arduino-uno, i2c, mpu6050
---


# Question
Title: Can I use [[__progmem__]] instead of PROGMEM?
In `pgmspace.h`, `PROGMEM` is defined as `__ATTR_PROGMEM__`, which is defined as `__attribute__((__progmem__))`. AFAIK, `__attribute__` is GNU only. Since C++ 11, we have the attribute specifier sequence.

I can't use `[[__progmem__]]` instead of `PROGMEM`. The error is

> warning: '\__progmem\__' attribute directive ignored \[-Wattributes\]

Shouldn't that work equally?

Why would I want to do that?

1. **Clarity**: When I first read code that used PROGMEM, I thought that this is the variable name (being a constant, we have a conding guideline that it should be upper case, which matched). Reading on, I found the real variable name, which confused me. Putting it into square brackets would immediately have made clear that it's an attribute and not a name.
2. **Portability**: `[[ ]]` is Standard C++, whereas `__attribute__` is not.

# Answer
Maybe I should just read the complete documentation...

Under Standard Attributes, we see the attributes that come with the C++ Standard. `__progmem__` isn't one of them.

Following the example for syntax 2, I tried `[[gnu::__progmem__]]`, which compiles. So this helps with *Clarity*, but since it now has the `gnu` namespace, it doesn't help with *Portability*.
> 0 votes

---
Tags: progmem
---


# Question
Title: 433MHz RF run away TX burst with ATTiny85 IC
I have recently created a sketch for an ATTiny85.

My project consists of:

* 1x ATTiny85 IC only
* 1x 433MHz RF module =\> using data pin `2`
* 2x input digital pins =\> using pin `3` and pin `4`

Running at 16MHz using the ATTiny85 board core from https://github.com/damellis/attiny

All running on a 5v 1A 7805 only using `24.4mA` idle `29.5mA` when TXing.

I have optimized my code a bit and the sketch works as intended. However sometimes the RF 433 module just keeps sending data for a few seconds instead of sending a burst then waiting for my 7 second timeout.

I do use the internal pullup resistors on pin 3 and 4.

This happens intermittently.. I would like to know if anyone has had a similar problem and knows how to prevent this "*runaway transmission*".. Or suggestions code improvements etc.

Strangely enough I can get 450m+- line of sight (farm land) distance accurate pings on my sensitive receiver using this cheap module.

**RF 433 Module**

I have the one with the SMD coil I have also soldered a 17.3cm LAN wire as antenna.

**SDR Waterfall**

I expect a constant burst every 7s.

**Code**

The code starts by looping a switch statement over states when an input is H/L or a timer runs out a state is changed.

When a trigger state is initiated a for loop copies and concatinates a condenses hex string then the next for loop sends these signals over pin 2.

After the signal is sent the state then changes to a timeout to wait before sending a pulse again.

*This is where the problem is.*

Sometimes the signal keeps sending as if the state is stuck for a few seconds but then the timer starts working as expected...

The longer 15min timer works fine, it's only the 7s and 9s loops that seem to have this issue.

---

**Pictures of testing PCB**

---

**Full sketch** \[*updated with suggestions*\]

```
#include <stdint.h>
#include <avr/io.h>
#include <util/delay.h>

#define DATA_PIN PB2// digital pin 2
#define ALARM_TRIGGER_PIN PB3// digital pin 3
#define LEARN_PIN PB4// digital pin 4

//15min= 900000 ms
//16min = 960000 ms
//20min= 500000 ms
const unsigned long DELAY_TIME_ZONE_HEARTBEAT = 900000;//15min
const unsigned long DELAY_TIME_CHECKALARM_TIMEOUT = 7000;//7sec
const unsigned long DELAY_TIME_CHECKLEARN_TIMEOUT = 9000;//9sec

unsigned long Delay_Start_Check_Alarm = 0;
unsigned long Delay_Start_Heartbeat = 0;
unsigned long Delay_Start_Learn = 0;

char LEARN[] ="269369a6924d36da6c800";//condensed hexadecimal signal; learnState/tamper same signal
char ALARM[] = "da4da69a4934db69b200";//condensed hexadecimal signal
char HEARTBEAT[] ="1269b4d349269b6d36400";//condensed hexadecimal signal
uint16_t pulse = 1100;//Attiny85 chip needs more of delay time
uint8_t i;

//custom states
enum State
{
  ALARMTIMEOUT,
  CHECKING,
  HEARTBEATTIMEOUT,
  HEARTBEATSEND,
  LEARNTIMEOUT,
  LEARNSEND,
  ALARMSEND
};

enum State state;

void setup()
{
  DDRB |= (1 << DATA_PIN);//replaces pinMode(DATA_PIN, OUTPUT);
  DDRB &= ~(1 << ALARM_TRIGGER_PIN); //replaces pinMode(ALARM_TRIGGER_PIN, INPUT);
  DDRB &= ~(1 << LEARN_PIN); //replaces pinMode(LEARN_PIN, INPUT);

  PORTB |= (1 << ALARM_TRIGGER_PIN);//initiate alarm pin pullup
  PORTB |= (1 << LEARN_PIN);//initiate learn pin pullup

  ADCSRA &= ~(1 << ADEN); //Disable ADC, saves ~230uA

  Delay_Start_Check_Alarm = Delay_Start_Heartbeat = Delay_Start_Learn  = millis();//set to start millis
  state = CHECKING;//initial state
}

void Check_Alarm_And_Heartbeat()
{
  unsigned long Mill = millis();//set to current time

  uint8_t alarmState = PINB&8;//read alarm pin 3
  uint8_t learnState = PINB&16;//read learn pin 4

  //main switch loop
    switch (state)
    {
    case CHECKING:
         //constant checking here
         if((alarmState) && (!learnState))
          {
           state = ALARMSEND;//set state
           Delay_Start_Check_Alarm = Mill;//keep time
          }
         //learn loop
         if((learnState) && (!alarmState))
         {
           state = LEARNSEND;//set state
           Delay_Start_Learn = Mill;//keep time
         }
         //continue heartbeat
         if((!alarmState) && (!learnState))
         {
           state = HEARTBEATTIMEOUT;//set state
         }
         //if both are high prioratize learnState/tamper signal
         if((alarmState) && (learnState))
         {
           state = LEARNSEND;//set state; learnState/tamper same signal
           Delay_Start_Learn = Mill;//keep time
         }
        break;
    case LEARNSEND:
         {
           state = LEARNTIMEOUT;//set state
           char LEARNFINAL[168];//make LEARNFINAL var and define length
           strcpy(LEARNFINAL, LEARN);//copy LEARN to new LEARNFINAL var
           for (uint8_t i = 0; i < 7; i++)
           {
             strcat(LEARNFINAL, LEARN);// append/concatenate LEARN 7 times to LEARNFINAL
           }
             for (i = 0; i < sizeof(LEARNFINAL); i++)
             {
               Send_Hex_Digit(DATA_PIN, LEARNFINAL[i], pulse);//send finished LEARNFINAL var
             }
             //PORTB &= ~(1 << DATA_PIN);//write low
         }
        break;
    case ALARMSEND:
         {
           state = ALARMTIMEOUT;//set state
           char ALARMFINAL[168];//make ALARMFINAL var and define length
           strcpy(ALARMFINAL, ALARM);//copy ALARM to new ALARMFINAL var
            for (uint8_t i = 0; i < 7; i++)
            {
               strcat(ALARMFINAL, ALARM);// append/concatenate ALARM 7 times to ALARMFINAL
            }
             for (i = 0; i < sizeof(ALARMFINAL); i++)
             {
               Send_Hex_Digit(DATA_PIN, ALARMFINAL[i], pulse);//send finished ALARMFINAL var
             }
             //PORTB &= ~(1 << DATA_PIN);//write low
         }
        break;
    case HEARTBEATSEND:
         {
             state = CHECKING;//change state
             char HEARTBEATPREFINAL[160];//make HEARTBEATPREFINAL var and define length
             strcpy(HEARTBEATPREFINAL, HEARTBEAT);//copy HEARTBEAT to new HEARTBEATPREFINAL var
              for (uint8_t i = 0; i < 7; i++)
              {
                 strcat(HEARTBEATPREFINAL, HEARTBEAT);// append/concatenate HEARTBEAT 7 times to HEARTBEATPREFINAL
              }
             for (i = 0; i < sizeof(HEARTBEATPREFINAL); i++)
             {
               Send_Hex_Digit(DATA_PIN, HEARTBEATPREFINAL[i], pulse);//send finished HEARTBEATPREFINAL var
             }
         }
        break;
    case HEARTBEATTIMEOUT:
             state = CHECKING;//change state
             if ((Mill - Delay_Start_Heartbeat) >= DELAY_TIME_ZONE_HEARTBEAT)
             {
                 Delay_Start_Heartbeat += DELAY_TIME_ZONE_HEARTBEAT;//prevents drift
                 state = HEARTBEATSEND;//change state when time ends
             }
        break;
    case ALARMTIMEOUT:
             state = ALARMTIMEOUT;//change state
             if ((Mill - Delay_Start_Check_Alarm) >= DELAY_TIME_CHECKALARM_TIMEOUT)
             {
                 state = CHECKING;//change state when time ends
             }
        break;
    case LEARNTIMEOUT:
             state = LEARNTIMEOUT;//change state
             if ((Mill - Delay_Start_Learn) >= DELAY_TIME_CHECKLEARN_TIMEOUT)
             {
                 state = CHECKING;//change state when time ends
             }
        break;
    default:
        //do nothing
        break;
    }
}

void Send_Hex_Digit(uint8_t pin, char c, uint16_t pulse)
{
  byte bc = c - 48 ; // convert c to number 0 to 15
  for (int i = 3; i >= 0; i--)
  {
    bitWrite(PORTB, pin, bitRead(bc, i));
    delayMicroseconds(pulse);
  }
}

void loop()
{
  Check_Alarm_And_Heartbeat();
}

```

# Answer
After implementing the suggestions I was able to make the sketch smaller and also solve the unwanted transmitting for the 2 timeouts (`pin3`, `pin4`).

The main issue was a 7s timeout before the sketch checks the High/Low.

This was solved by setting `Delay_Start_Check_Alarm` and `Delay_Start_Learn` in my switch statement, if the alarm was triggered.

```
    Delay_Start_Check_Alarm = Mill;//Setting this solved the issue

```

The heartbeat did not need this change since it gets set every time `HEARTBEATTIMEOUT` is called so it works ok.

The code in the question is also updated.

Big thanks to *@chrisl*, *@6v6gt* and *@timemage*.
> 1 votes

---
Tags: communication, attiny, rf, attiny85
---


# Question
Title: ESP8266 Wemos D1 Mini Pro v2.0 - Load sharing and battery
I have a simple question regarding the new version of **Wemos D1 Mini Pro v2.0** and specifically about its load sharing circuitry. Schematic is here :

https://www.wemos.cc/en/latest/\_static/files/sch\_d1\_mini\_pro\_v2.0.0.pdf

Battery charger is TP4054 and there's a load sharing configuration based on P-MOSFET CJ2301.

My question is what happens if you do NOT connect any battery.

It seems that the charging LED faintly flashes, and positive voltage appears in positive battery terminal. Moreover, voltage appears in A0 and ADC input (provided that SJ1 is connected), while someone would expect a zero voltage there, since there's no battery.

Am I missing something here? Is there any way to fix this issue?

# Answer
I have test it and you are right. When you plug power into the USB connector with no battery connected to the Wemos D1 mini Pro v2.0.0 (provided BAT-A0 is connected) and I have got 1023, the maximum read into A0, when it should be 0.

I think a related problem is that when you are running with battery and you connect a charger into the USB port you can *not* read the battery voltage, you are getting always 1023, like if the battery was fully charged. So, you can use A0 to monitor battery voltage when discharging, but not when charging.
> 1 votes

---
Tags: esp8266, battery, mosfet
---


title: Get 3-inch e-Paper working on a Nano

text:
# Question
Title: Get 3-inch e-Paper working on a Nano
Please help!

I purchased a 3-inch e-Paper Display from Waveshare, which appeared to suit my project well. The exemplary little code to show an image was easy to set up and to demonstrate functionality:

```
#include <SPI.h>
#include "epd3in0g.h"
#include "imagedata.h"

Epd epd;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  Serial.print("e-Paper init ");
  if (epd.Init() != 0) {
      Serial.print("e-Paper init failed");
      return;
  }

  Serial.print("White \r\n");
  epd.Clear(white);
  delay(2000);

  epd.Init();
  Serial.print("Image \r\n");
  epd.Display(IMAGE_DATA);
  delay(2000);

  epd.Init();
  Serial.print("Small Image \r\n");
  epd.Display_part(IMAGE_DATA, 0 ,0, 168, 400);
  delay(2000);

  epd.Init();
  Serial.print("Clear...\r\n");
  epd.Clear(white);
  delay(2000);

  Serial.print("Goto Sleep...\r\n");
  epd.Sleep();
}

void loop() {

}

```

I will not just have images displayed, I aim for strings with text and numbers and those partial refreshed. Wild guesses if a

```
epd.Display_Text('''Hello World''');

```

might work is pointless. Thus, the existence and usage of possible commands for the *epd.* appears to me not well documented (or I was unable to find something even after a thoroughly search).

I had a look at other examples using GxEPD libraries and it seemed as a good starting point for me.

Within the GxEPD2 Library it seems a class for 3-inch EPD is missing as it is nowhere declared (I assume there should be something like a *GxEPD\_300* to set display dimensions etc.).

So, I reckon I need to wrap up something to meet the specs of the 400x168 pixel display but I don't know where to start.

I tried around with the GxEPD\_MinimumExample.ino, like

* replacing the display specific lib with the *epd3in0g.h* from the example
* adjusted the right pins according to the Waveshare Wiki

```
// GxEPD_MinimumExample by Jean-Marc Zingg

#include <GxEPD.h>

// select the display class to use, only one, copy from GxEPD_Example
//#include <GxGDEH0154D67/GxGDEH0154D67.h>  // 1.54" b/w -> from org. example.
#include "epd3in0g.h" //my 3-inch display

#include <GxIO/GxIO_SPI/GxIO_SPI.h>
#include <GxIO/GxIO.h>

// constructor for AVR Arduino, copy from GxEPD_Example else
GxIO_Class io(SPI, /*CS=*/ 10, /*DC=*/ 9, /*RST=*/ 8); // arbitrary selection of 8, 9 selected for default of GxEPD_Class
GxEPD_Class display(io, /*RST=*/ 8, /*BUSY=*/ 7); // default selection of (9), 7

void setup()
{
  display.init();
  display.eraseDisplay();
  // comment out next line to have no or minimal Adafruit_GFX code
  display.drawPaged(drawHelloWorld); // version for AVR using paged drawing, works also on other processors
}

void drawHelloWorld()
{
  display.setTextColor(GxEPD_BLACK);
  display.print("Hello World!");
}

void loop() {};

```

During the verification prior the upload I get errors pointing back to the libs:

```
error: 'GxEPD_Class' does not name a type; did you mean 'GxIO_Class'?*

```

I assume this is because the call to initiate the display is not working.

Thank you for any advice!

# Answer
> 0 votes
Waveshare examples, by and large, suck. They're usually a bunch of register writes, undocumented. I had to write a library for an EPD once - OEM version, which later popped up on Waveshare's website as their own - and the OEM's documentation and code were good enough (just...) to produce a functional library.

Looking at the example for your specific screen, I see it is indeed the usual `SendCommand()` crap. Although it seems slightly more evolved, with an `Epd` class. But still, useless.

EPD code is HARD, and requires a lot of information from the manufacturer. And producing a library that handles text is also a little harder to get right.

I don't think trying to transplant their crappy code onto an existing library is going to work. I figure you have two solutions:

* Rewrite a library for this epaper from scratch.
* Half-ass something by adding text handling to their code by converting text to pixels in the buffer, and push that.

In both cases, painful.

---
Tags: library
---


# Question
Title: RF24 if statements are not reading properly, even if an "if" value is wrong, it still follows the associated code
My code is taking values from a remote and transmitting the state of it. Right now the states are just 1 and 0, on or off, and is writing over the serial monitor on the transmitting Arduino. On the receiving RF module I can't seem to get my if statements working right

Transmitter code:

```
const char a[] = "1";
const char b[] = "0";
void loop() {
if (Serial.available ( ) > 0)
{
char state = Serial.read(); // reading the value from the remote

if (state >= 0)
{
digitalWrite (7, HIGH); //turning LED on transmitting breadboard on to compare to recieving breadboard
radio.write(&a, sizeof(a)); //tell the other arduino that the value is 1
}
if (state < 0)
{
digitalWrite(7,LOW);
radio.write(&b,sizeof(b)); //tell other arduino value is 0
}
}

```

reciever code:

```
void loop()
{
if (radio.available())
{
char state[32] = {0};

radio.read(&state, sizeof(state));
Serial.println(state);
int a = state;
if (a = 1);
{
  digitalWrite(7,HIGH);
  Serial.println("do something");
}
if (a = 0);
{
digitalWrite(7,LOW);
Serial.println("do nothing");
}
}

```

receiving serial monitor

```
1
do something
do nothing
0
do something
do nothing
0
do something
do nothing

```

and my light stays off on the receiving Arduino, why does it print both statements? A is 1, but it prints the value that's supposed to be printed when a is 0 also, i'm so confused

# Answer
```
if (a = 1);
{
  digitalWrite(7,HIGH);
  Serial.println("do something");
}

```

Two major problems here. In C++ you test for equality for `==`, not `=`.

Second, putting the semicolon after the `if` terminates the scope of the `if`.

That should read:

```
if (a == 1)
{
  digitalWrite(7,HIGH);
  Serial.println("do something");
}

```

---

```
char state[32] = {0};

radio.read(&state, sizeof(state));
Serial.println(state);
int a = state;

```

`state` is an array. If you assign that to `a` you will get the same array, in another variable. That array will not be zero or one.

Maybe you mean:

```
int a = state [0];

```
> 0 votes

---
Tags: arduino-uno, serial, nrf24l01+
---