# Question
Title: Why does my 16x2 LCD displays weird letters and can't insert key from keypad?
I'm a newbie on Arduino here, and this is my first project on 16x2 LCD, 4x4 keypad and others. So, the story is, after I uploaded the program for my group's Arduino alarm clock to the Arduino board, the LCD displays black boxes on the first row of the LCD. But after soldering the LCD pins again and connect the Vo to the 10k ohm potentiometer, the LCD can display the "welcome" part properly. This can be seen in the two pictures below.

However, after a while, there are weird letters appearing on the second row of the LCD, blinking from the first picture below to the second picture again and again. Plus, I couldn't input any key from the keypad to the LCD, since the display's stuck at there.

I'm not sure if there's any problem in the circuit or in the programming. I'm quite confused here. Below is the code I uploaded to the Arduino board. Thank you in advance.

```
#include <EEPROM.h>
#include <Keypad.h>
#include <DS1307.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <LiquidCrystal.h>

DS1307 rtc(SDA, SCL);
LiquidCrystal lcd(A3, A2, A1, A0, 5, 4);
Time t;

#define buz 3

int Hor, Min, Sec, h, m, s;
int ASCII = 48;
char* tim;
char* dat;
const char key = 0;
char buffer[2];
const byte numRows= 4;
const byte numCols= 4;
char keymap[numRows][numCols]=
{
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};
byte rowPins[numRows] = {12, 11, 10, 9};
byte colPins[numCols]= {8, 7, 6, 5};
Keypad myKeypad= Keypad(makeKeymap(keymap),rowPins, colPins, numRows, numCols);

void setup() {
  Wire.begin();
  rtc.begin();
  pinMode(buz, OUTPUT);
  lcd.begin(16, 2);
  welcome();

  rtc.setDOW(SATURDAY); //Set Day-of-Week to SUNDAY
  rtc.setTime(10, 54, 0); //Set the time to 12:00:00     (24hr format)
  rtc.setDate(7, 1, 2017); //Day, Month, Year
}

void loop() {
  t = rtc.getTime();
  Hor = t.hour;
  Min = t.min;
  Sec = t.sec;
  tim = rtc.getTimeStr();
  dat = rtc.getDateStr();
  char key = myKeypad.getKey();

  if (key == 'C'){
    digitalWrite(buz, LOW);
    EEPROM.write(2, ASCII+6);
    EEPROM.write(3, ASCII);
  }

  if(key == '#'){
    lcd.setCursor(0,0);
    lcd.print("Enter New Time");
    lcd.setCursor(0,1);
    int j =0;
    int i=0;
    while( j<6)
    {
      if(i==2 || i == 5){
        lcd.print(":");
        lcd.display();
        i++;
      }
      key=myKeypad.getKey();
      if(key)
      {
        lcd.print(key);
        lcd.display();
        EEPROM.write(j,key);
        j++;
        i++;
      }
    }
  }

  changealarm();
  checkalarm();
  timedate();
}

void checkalarm(){
  if( Hor == h && Min == m)
  {
    delay(3000);
    lcd.setCursor(0,1);
    lcd.print("Hold C");
    digitalWrite(buz, HIGH);
    delay(3000);
  }
}

void changealarm(){
  buffer[0]=EEPROM.read(0);
  buffer[1]=EEPROM.read(1);
  h = atoi(buffer);
  buffer[0]=EEPROM.read(2);
  buffer[1]=EEPROM.read(3);
  m = atoi(buffer);
  buffer[0]=EEPROM.read(4);
  buffer[1]=EEPROM.read(5);
  s = atoi(buffer);
}

void timedate(){
  lcd.setCursor(0,0);
  lcd.print("Time: ");
  lcd.print(rtc.getTimeStr());

  lcd.setCursor(0,1);
  lcd.print("Date: ");
  lcd.print(rtc.getDateStr());
  delay(3000);
  lcd.setCursor(0,1);
  lcd.print("Alarm: ");
  lcd.print(h);
  lcd.print(".");
  lcd.print(m);
  lcd.print(".");
  lcd.print(s);
  delay(3000);
}

void welcome(){
  lcd.setCursor(0,0);
  lcd.print("Welcome");

  lcd.setCursor(0,1);
  lcd.print("To");
  delay(3000);

  lcd.setCursor(0,1);
  lcd.print("TIMeProject");
  delay(3000);
}

```

# Answer
> 1 votes
In your `changealarm()` function, you call `atoi(buffer)`, and `buffer` is defined as `char buffer[2]`.

`atoi()` expects a c-style string, which is null-terminated, and you have to include space for the null termination character (`'\0'`, `0`, `0x00`, etc.), but you write to both allocated spaces in the `changealarm()` function. If your 2nd byte of each EEPROM space (1, 3, 5) is non-zero, then your have an unterminated string.

`atoi()` expects a null-terminated string, and so the behavior is unexpected. Probably `atoi()` is running into other memory. If the string being sent is not representable by a `int` type, then the behavior of `atoi()` is *undefined*.

---

A quick fix would be to increase the size of `buffer` and guarantee null termination:

```
char buffer[3];  // Make the buffer 3 bytes long
[...]
void changealarm() {
  buffer[2]=0;   // Set the 3rd byte to zero to null-terminate

  buffer[0]=EEPROM.read(0);
  buffer[1]=EEPROM.read(1);
  h = atoi(buffer);
  buffer[0]=EEPROM.read(2);
  buffer[1]=EEPROM.read(3);
  m = atoi(buffer);
  buffer[0]=EEPROM.read(4);
  buffer[1]=EEPROM.read(5);
  s = atoi(buffer);
}

```

---
Tags: lcd, adafruit, eeprom, wire-library, keypad
---


# Question
Title: Looking for a waterproof SPI temperature sensor
In my current project I'm using a DS18B20, which seems to be the only temperature sensor to show up when googling for waterproof temperature sensor for an arduino.

The sensor itself is fine, however, I'm outputting the sensor's data to a SPI screen, and whenever the sensor is called to read data I believe the SPI communication is interrupted because of 1-Wire, and you can see a white flicker on the screen. The background LED is flashing more brightly for one frame. It's almost unnoticeable, but it bothers me.

I'm not using delays, and I'm not redrawing unnecessary elements on the screen again. Only dynamic elements are refreshed when they need to, static elements are only drawn once on the screen. The sensor is called every 5 seconds with a comparison:

```
if(currentTime - lastTimeQueried >= delay){
    lastTimeQueried = currentTime;
    temperature = new temperature;
    return temperature;
} else {
    return temperature;
}

```

I also tried a function where I'm constantly calling the sensor and only drawing on the screen if there's a change in temperature, but then the screen is flickering all the time. Thus I conclude that the flickering is caused by the actual calling of the sensor, and not from redrawing anything on the screen.

So I'm wondering if there's an alternative to the DS18B20 that communicates via SPI, and that I can use in an aquarium, so I don't have to use both protocols in my project.

Edit:

As requested some more of my code and wiring:

The screen is wired to the ICSP headers on my Arduino Mega 2560 and power is supplied via 5V on a powersupply that is connected to my breadboard.

The DS18B20 is wired to pin 29 on the Arduino and is also supplied with power via 5V on the same powersupply.

```
//TFT SPI
#define TFT_DC 9
#define TFT_CS 10
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);

//SD Card Reader SPI
//#define SD_CS 4

//Touchscreen I2C
UTouch  myTouch(5, 8, 6, 7, 2);  //(T_CLK, T_CS, T_DIN, T_DOUT, T_IRQ)

#define ONE_WIRE_BUS 29
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

```

Here are some more variables that I have defined to help with using the sensor:

```
//Temperature measurement
unsigned long lastTempMeasure;  //Holds last unix timestamp temperature was measured at
char tempMeasureDelay = 5;      //Call temperature every 5 seconds
float sensorTemp;               //Holds measured temperature

```

In my loop I then use this function:

```
tft.print(temperatureCall());

```

and then:

```
float temperatureCall(){
  //get unix time for right now
  unsigned long currentUnix = now();

  //if 5 seconds passed since last poll, ask for new temperature, else return old measurement
  if(currentUnix - lastTempMeasure >= tempMeasureDelay){
    lastTempMeasure = currentUnix; //save last polling time

    sensors.requestTemperatures();
    sensorTemp = sensors.getTempCByIndex(0);

    return sensorTemp;
  } else {
    return sensorTemp;
  }
}

```

As I said, the flicker only occurs when these two are used every 5 seconds:

```
sensors.requestTemperatures();
sensorTemp = sensors.getTempCByIndex(0);

```

Edit 2:

Pic of wiring:

# Answer
There is a delay in the DallasTemperature `requestTemperatures()` function - it blocks until the temperature conversion is complete unless you have previously called `setWaitForConversion(FALSE)`. If you did that, you would still have to wait for the conversion but you can do it an a non-blocking manner, and I don't see that happening in your code.
> 1 votes

---
Tags: arduino-mega, sensors, i2c, spi, temperature-sensor
---


# Question
Title: Changing parameters in Arduino without the IDE
I’m installing Arduino-based well monitors in my local community. Each well is different and has slightly different parameters and several hardware variations. Currently, when I need to make a program change I have to uninstall the Arduino, bring it back to my computer, reprogram it, then reinstall it. I’m developing these units as I go so there are various refinements that arise as well. I’d love to be able to reprogram a unit in place. It seems like it *could* be done with another Arduino but I don’t currently have the skills for that. The second, less flexible, method would be to use dip switches to select various options. This option is attractive but would limit me to only the options that I know of at programming time. Is there a third option I haven’t thought of? Has anyone else tried programming one Arduino from the other? Edit: I’m primarily using Unos but I’m working on a low power version that will use a Mini Pro. The units are accessible as far as USB cables and such. However I don’t own a laptop.

# Answer
Sounds like you need a Standalone programmer. I offer one, it loads the target device from a program you select on SD card. Up to 256 programs can be stored on 1 card. Check it out here www.crossroadsfencing.com/BobuinoRev17/Programmer.html
> 1 votes

---
Tags: isp
---


# Question
Title: HTTP get request using Arduino Uno and ESP8266
I have an Arduino Uno and an ESP8266 and I want to send a HTTP get request to `google.com` and print the response. Please help me thanks.

# Answer
You can use ESP8266Wifi Arduino Library.

Here an example:

```
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>

const char* ssid = "yourNetworkName";
const char* password = "yourNetworkPassword";

void setup () {

  Serial.begin(115200);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {

    delay(1000);
    Serial.print("Connecting..");

  }

}

void loop() {

  if (WiFi.status() == WL_CONNECTED) { //Check WiFi connection status

    HTTPClient http;  //Declare an object of class HTTPClient

    http.begin("http://www.google.com");  //Specify request destination
    int httpCode = http.GET();     //Send the request

    if (httpCode > 0) { //Check the returning code

      String payload = http.getString();   //Get the request response payload
      Serial.println(payload);                     //Print the response payload

    }

    http.end();   //Close connection

  }

  delay(30000);    //Send a request every 30 seconds

}

```
> 2 votes

---
Tags: arduino-uno, esp8266, http
---


title: Guideline in library creation

text:
# Question
Title: Guideline in library creation
According to this example, creation of an Arduino library is quite understandable.

But a few things I would like ask (mostly regarding to what to be defined where) when a library is not that simple:

1. Where to put additional libraries (such as `<Wifi.h>`) in `.h` or `.cpp`, since it works when defined in each one of them?
2. What is the purpose of defining variables in the `:private` section? Since they can be defined inside constructor, and as far as I know/tested, it works as well.
3. In a `.cpp` file, does it matter when instances or variables are defined outside a class (at the beginning of code ), since again, it works the same?

# Answer
> Where to put additional libraries (such as ) in .h or .cpp, since it works when defined in each one of them?

It doesn't really matter as long as the parts of your library that need to see the headers can see them. Personally I put all headers in the master .h file and then that gets included in the .cpp file(s). It just keeps it all in one place and is easier to manage.

> What is the purpose of defining variables in the :private section? Since they can be defined inside constructor, and as far as I know/tested, it works as well.

You need to understand "scope". Defining a variable inside the constructor means that it's only available within that constructor. This is "local" scope. Defining the variable in the class, within the "private" section makes that variable available to every function within the class. Putting it in "public" makes it available to anyone anywhere.

> In a .cpp file, does it matter when instances or variables are defined outside a class (at the beginning of code ), since again, it works the same?

Again this is a matter of "scope". A variable declared outside the class is in "global" scope. There is only one copy of each of these variables, and all instances of the class share the same physical variable. It is the same as declaring a class variable as "static" - it makes it common to all instances of the class. If the data you need to store is specific to a class instance (which most of the time it is), you do *not* want to use global variables. In general it's bad form using global variables if you don't have to.

Incidentally, you may see variables defined both in the class *and* at the top of the CPP file. This is a special case where you have *static* variables in your class, which don't have any storage space allocated to them (normally a variable has its storage space allocated when you create an instance of the class, but that doesn't happen with static variables for obvious reasons), so you have to manually provide the storage space with a separate entry in the CPP file.
> 2 votes

# Answer
> 1. Where to put additional libraries (such as `<Wifi.h>`) in `.h` or `.cpp`, since it works when defined in each one of them?

Any library can reference any other library. So including another library in your library is the same as including in the sketch. They should be on standard locations.

Include the other libraries .h in the file where you need it. If you use something from the other library in your .h, include it there. If you need it only in .cpp include it there.

> 2. What is the purpose of defining variables in the `:private` section? Since they can be defined inside constructor, and as far as I know/tested, it works as well.

With declaring a class member as `private`, the author of the class tells: don't use it, it is for internal use and can change in future versions.

> 3. In a `.cpp` file, does it matter when instances or variables are defined outside a class (at the beginning of code ), since again, it works the same?

If the variable is not a member of the class, then if you create two instances of the class they will share the variable. A variable in constructor is restricted to the constructor's scope.
> 3 votes

# Answer
Regarding 1: prefer to add it in the sketch/.cpp file only. If this is not possible (because you need the class to be known in the header file, only than add it in the header.

Reason: a header file is typically included by many other files and adding an include results in more coupled code, making later maintenance more difficult.

Regarding 2/3: See also the somewhat related answer of me in why-to-store-a-function-parameter-value-in-a-class-private-variable.
> 1 votes

---
Tags: library, cpp
---


# Question
Title: Distance measuring utilizing (1 or 2) Arduino Nano's
I would like to develop a small-distance measuring device that will be primarily used in indoor scenarios to measure a distance with cm accuracy (mm if possible). The device would be in a small form factor and would calculate the distance it has moved in reference to the starting position. However, upon doing more research I have found that this is a bit harder than I thought it would be. My initial idea was to utilize an accelerometer and take the double integral to determine displacement, however, I learned that this is primarily impossible with consumer grade accelerometers.

My current idea for implementation would utilize a small stationary external device that sends signals constantly back and forth measuring the difference in time it takes the wave of information to be received. I have looked online to find similar projects to this, but could not find any. Perhaps I haven't looked hard enough, but does anyone know if projects like this exist (preferably Arduino based)? If not then, would a simple consumer-based IR sensor work for this situation? Maybe I'm overthinking it and there's an even easier solution for measuring small distances with an external device. I could use some guidance on this. Thank you.

# Answer
Try to take a look to Lidar sensors.

Here an interesting guide by SparkFun.
> 1 votes

# Answer
Look at Ping sensor also. Ultrasonic, way less expensive than Lidar.

> Ultrasonic ranging module HC - SR04 provides 2cm - 400cm non-contact measurement function, the ranging accuracy can reach to 3mm.

https://www.digikey.com/product-detail/en/sparkfun-electronics/SEN-13959/1568-1421-ND/6193598&?gclid=EAIaIQobChMIs4Ltisap3wIVD4zICh0mkwyfEAQYAiABEgILqfD\_BwE

Give it a shot, see if the $4 solution meets your needs.
> 0 votes

---
Tags: arduino-nano, wifi, bluetooth, arduino-micro, infrared
---


title: Most efficent way to adjust value

text:
# Question
Title: Most efficent way to adjust value
I am working on a system that starts a process based of a set time value (startHour). The user sets the start hour and can only select values from 00-23. I have been asked to start the same process at 6 hour intervals so that it occurs 4 times during the day.

My initial though is to add three more variable, secondStartHour, thirdStartHour and fourthStartHour. secondStartHour would be assigned a value 6 hours ahead of the startHour, thirdstartHour a value 12 hours ahead of startHour and fourthStartHour would be assigned a value 18 hours ahead of start hour. I could then use any of the startHour variables to trigger the process.

I wrote some code (below) that will work but I'm wondering if there is a better, more efficient way of doing it.

```
//set up secondStartHour 6 hours ahead of startHour
if (startHour <= 5)
{
    secondStartHour = startHour - 18;
}
else
{
    secondStartHour = startHour + 6;
}

//set up thirdStartHour 12 hours ahead of startHour
if (startHour <= 11)
{
    thirdStartHour = startHour - 12;
}
else
{
    thirdStartHour = startHour + 12;
}

//set up fourthStartHour 18 hours ahead of startHour
if (startHour <= 17)
{
    fourthStartHour = startHour - 6;
}
else
{
    fourthStartHour = startHour + 18;
}

```

I had to write the code in the way I did above because I am working with a 24 hour clock so in some cases adding time to a startHour will actually reduce the value. By this I mean if startHour is 23 (23:00) and I need to add 6 hours to it to get secondStartHour the result will be 5 (05:00) so I can't simply write code to say secondStartHour = startHour + 6. The code just seems too long winded and messy but I cant think of a better way to write it. I could use a switch case statement but then I would have 24 cases with assignments for each of the new variables in each case so that seems worse, any ideas would be appreciated.

# Answer
Instead of comparing, you can use the modulo operator:

```
 secondStartHour = (startHour +  6) % 24;

```

And similar for the others:

```
 thirdStartHour  = (startHour + 12) % 24;
 fourthStartHour = (startHour + 18) % 24;

```

While xxxStartHour \>= 24, 24 will be removed until it is within range \[0, 24).

If you need an offset, you also can add some hours of course after the module (I don't fully understand your example which can have values \>= 24.

Also, if you need to do the same task every 6 hours, you can use with one time and 'restart' it every 6 hours (and maybe taking summer/winter time into account).
> 1 votes

# Answer
If you think about it logically you actually only have 6 start hours. Things can only start at a time between 0 and 5 am inclusive. Everything else is a multiple of 6 hours on from that start. Any time provided that's past 5am is actually a future time of an earlier start time.

So you can just "modulus" the given time so it is one of the first 6 hours of the day:

```
startHour = startHour % 6;

```

And then add 6 each time for the other hours:

```
secondStartHour = startHour + 6;
thirdStartHour = startHour + 12;
fourthStartHour = startHour + 18;

```

So your hour arrangements can only be:

```
0  6  12  18
1  7  13  19
2  8  14  20
3  9  15  21
4 10  16  22
5 11  17  23

```

If you provide the hour 15 as a start time, 15 % 6 is 3 (divide 15 by 6, you get 2 with 3 remaining), so you are in the time pattern "3 9 15 21".
> 1 votes

---
Tags: programming, c++, arduino-due
---


# Question
Title: Avrdude Verification Error while flashing Arduino Mega code
I'm working with an Arduino Mega 2560 and am getting the following error at compile time:

> avrdude: verification error, first mismatch in byte 0x0000 0x14! = 0x25 avrdude: verification error; content mismatch

I've already changed the COM port and also restarted an IDE.

# Answer
I have made Jot's comment into an answer in the hope that it helps someone.

---

First mismatch in byte 0x0000. \[This is\] the first byte that goes wrong. That means that not even a single byte passes the verification.

Perhaps the cause is one of these:

1. A cheap clone with a bad bootloader.
2. An old bootloader.
3. A bug, perhaps a bug with the size of the code or ram, for example the code at the border of 32k or 64k.
4. Maybe the voltage of the Arduino board is too low. Measure it. It must be above 4.5V.
5. Maybe a bad USB cable.
6. Wrong USB driver.
7. Board is too cheap and is missing decoupling capacitors.
> 1 votes

---
Tags: arduino-ide, avrdude
---


# Question
Title: Arduino Uno vs Arduino MKR1000 analogRead discrepancies
I'm using an Arduino to control a BLDC motor connected with the motor driver. It is just a simple control which I'm using a PWM as a signal. Before this, I'm used Arduino Uno pin 5 to control BLDC motor, the analogue value starts from 80. Now, I'm changed to Arduino MKR1000 board with the same pin 5 to control BLDC motor. But, for MKR1000 to rotate the motor, analogue value start from 125. My question is, why two of this board using a different PWM value for rotating the BLDC motor.

# Answer
> 2 votes
The Adruino Uno is running off 5V, while the MKR1000 is 3.3V. This means you need a bit more on-time to get the same power output.

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


# Question
Title: What's wrong with my keypad and time program?
I really need help here. I'm a total noob in Arduino and this is my first Arduino project. I've been trying to get the keypad to be able to input time for my alarm clock project but I only managed to get the welcome part of the program. But then the display stuck at the welcome part only. I want to set alarm time by using the keypad only, and if the alarm time is the same as the time display, the buzzer should ring.

Plus, the deadline is in two days. I'm certain that there's no problem with hardware since all of the components (16x2 LCD, RTC DS1307, buzzer, 4x4 keypad) work properly when I use some basic tutorial coding for the components.

Please check what could be wrong in my code? I've tried to replace some of the codes but it had no change; the display's still stuck at the welcome part.

\[Edit\]I've added the "milli" code at the `timedate()` part. But I'm not sure, how to improve the `alarm()` part of this code? I can't input any key to insert the alarm time at this part.

If there's any update on what I've edit to my code later, I will edit this question's body. Thank you in advance.

```
#include <EEPROM.h>
#include <Keypad.h>
#include <DS1307.h>
#include <Wire.h>
#include <LiquidCrystal.h>
DS1307 rtc(SDA, SCL);
LiquidCrystal lcd(A3, A2, A1, A0, 5, 4);
Time t;

#define buz 3

int Hor, Min, Sec, h, m, s;
int ASCII = 48;
char* tim;
char* dat;
char buffer[3];
const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
byte rowPins[ROWS] = {6, 7, 8, 9};
byte colPins[COLS]= {10, 11, 12, 13};
Keypad keypad= Keypad(makeKeymap(keys),rowPins, colPins, ROWS, COLS);

unsigned long previousMillis = 0;
const long interval = 1000;

void setup() {
Wire.begin();
rtc.begin();
pinMode(buz, OUTPUT);
lcd.begin(16, 2);
welcome();

rtc.setDOW(TUESDAY); //Set Day-of-Week to SUNDAY
rtc.setTime(18, 20, 00); //Set the time to 12:00:00     (24hr format)
rtc.setDate(18, 12, 2018); //Day, Month, Year
}

void loop() {
t = rtc.getTime();
Hor = t.hour;
Min = t.min;
Sec = t.sec;
tim = rtc.getTimeStr();
dat = rtc.getDateStr();
char key = keypad.getKey();

if(key == 'A'){
alarm();
}

if (key == 'C'){
digitalWrite(buz, LOW);
EEPROM.write(2, ASCII+6);
EEPROM.write(3, ASCII);
}
changealarm();
checkalarm();
timedate();
}

void checkalarm(){
if( Hor == h && Min == m)
{
delay(3000);
lcd.setCursor(0,1);
lcd.print("Hold C");
digitalWrite(buz, HIGH);
delay(3000);
}
}

void changealarm(){
buffer[2] = 0;
buffer[0] = EEPROM.read(0);
buffer[1] = EEPROM.read(1);
h = atoi(buffer);
buffer[0] = EEPROM.read(2);
buffer[1] = EEPROM.read(3);
m = atoi(buffer);
buffer[0] = EEPROM.read(4);
buffer[1] = EEPROM.read(5);
s = atoi(buffer);
}

void timedate(){
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Date: ");
lcd.print(rtc.getDateStr());

lcd.setCursor(0,1);
lcd.print("Time: ");
lcd.print(rtc.getTimeStr());
delay(3000);
lcd.setCursor(0,1);
lcd.print("Alarm: ");
lcd.print(h);
lcd.print(":");
lcd.print(m);
lcd.print(":");
lcd.print(s);
}
}

void welcome(){
lcd.setCursor(0,0);
lcd.print("Welcome");

lcd.setCursor(0,1);
lcd.print("To");
delay(2000);

lcd.setCursor(0,1);
lcd.print("TIMe Project");
delay(2000);
}

void alarm()
{
int j=0;
char key = keypad.getKey();
lcd.clear();
lcd.print("Enter Alarm Time: ");
lcd.setCursor(0,1);
while(j<4)
{
lcd.print(h);
lcd.print(":");
lcd.print(key);
lcd.print(m);
lcd.print(":");
lcd.print(key);
lcd.print(s);
lcd.print(key);
key=0;
}
delay(500);
}

```

# Answer
> 0 votes
Your function `timedate()` is called every time through `loop()` and it has a total of 6000ms of delay. During a delay, **NOTHING** can happen, not even checking for a keypress.

So, you would have to hold the desired key down until the `key = keypad.getKey()` statement is executed, which is a minimum of every 6 seconds.

Use of `delay()` for an interactive program in which user input can happen any time is not desired. Instead, there is a popular example Arduino sketch called "BlinkWithoutDelay" which us used as an explanation of how to avoid using `delay()` by letting your `loop()` function run at very high speed and only taking the desired action if the desired time has elapsed since some initiating action.

The more generic concept is called a "State Machine" and there are numerous websites that attempt to teach it, such as this one.

Be prepared to make significant changes to the structure of your program, however, as moving from `delay()` usage to state machine usage means a re-thinking of your `loop()` function -- you have to consider it running tens of thousands of times per second, and most of those times it doesn't do anything but check if something needs to be done -- most often the answer is "no, nothing needs to be done this time."

---
Tags: rtc
---


title: Elapsedtime variable not resetting

text:
# Question
Title: Elapsedtime variable not resetting
I am new to Arduino programming. Let me describe the application I am working on. I am pressing a button for a certain period of time (30 sec). I can not hold it in a pressed position for all the time. I want to avoid accidental transition from button state going from logic HIGH to LOW. I am trying to drive a solenoid valve only at the end of the event.

The algorithm I am using is if once the system detects a HIGH from the sensor it goes in a loop and looks for transition to LOW. It checks if there is continuous LOW for more than 5 sec. If NO then it resets to start checking LOW again. If YES that means end of event and drives the solenoid valve.

The problem I am facing with the code is although the transition to LOW and remaining in LOW is less than 5 sec, the system is sending pulse to drive the solenoid valve. I have incorporated Serial.print() function to observe the value of the sensor input state and elapsed-time. The elapsed-time variable does not reset and keep increasing even though the button state reverts from LOW to HIGH.

I am incorporating part of the code here which is related to the algorithm. I will greatly appreciate if you kindly take a look at the code and the output file and help me detect the bug.

Thanks again! Niloy.

```
void loop() {

      buttonstate = digitalRead(button);   // read the state of the microswitch value: HIGH "on" or LOW "off"

      if (buttonstate == HIGH ){
          countstart = 1;

          while(countstart == 1) {
          buttonstate = digitalRead(button);   // read the state of the microswitch value: HIGH "on" or LOW "off"

          if ( ( buttonstate == LOW ) && ( startFlag == 0 ) ) { //start new time sequence
                  startFlag = 1;
                  startTime = millis();
            }
          if ( ( buttonstate == LOW ) && startFlag == 1 ){
                  endTime = millis();
                  elapsedTime = endTime - startTime;
          }

          if ( ( buttonstate == HIGH ) && startFlag == 1 ){
                  startFlag == 0;
                  endTime = startTime =0;
                  elapsedTime = endTime - startTime;
                  countstart = 0;
          }

          Serial.print(buttonstate);
          Serial.print("\n");       // Print tab space
          Serial.print(elapsedTime);
          Serial.print("\n");       // Print tab space

      if ( elapsedTime >= 5000)
      {
          delay(2000);  //2 sec delay
          solenoid->run(FORWARD);
          delay(40);
          solenoid->run(RELEASE);

          delay(500);

          solenoid->run(BACKWARD);
          delay(40);
          solenoid->run(RELEASE);

          countstart = 0;
          endTime = startTime =0;
          elapsedTime = endTime - startTime;
          buttonstate = LOW;
          delay(15000); //wait for 15 sec

      }
     }

    }
}

```

# Answer
> 0 votes
startFlag variable never goes to zero because there is a bug in this part of code:

```
 if ( ( buttonstate == HIGH ) && startFlag == 1 ){
          **startFlag = 0;**
          endTime = startTime =0;
          elapsedTime = endTime - startTime;
          countstart = 0;
  }

```

---
Tags: millis, digital, debounce
---


title: How to use map function

text:
# Question
Title: How to use map function
```
if(pin10==HIGH)
  val=analog.read (potpin);
  val=map(val,0,1023,0,180);
  servowrite(val);
else
  val=map(0,1023,0,90);
    servo.write(val);}

```

# Answer
> 1 votes
It looks like you're using pin 10 to indicate whether sweep your servo through 180-degrees or through 90-degrees. Is that correct? Then you only need the if/else statements to select one of the two 'map()' calls. I see several problems:

1. Your indentation suggests you tried to select 3 statements with your 'if', but an 'if' only refers to one following statement or block of statements. If you want it to control a block of statements, you need to surround those statements with braces: '{' and '}'.
2. In this case, you need everything but the 'map' calls to be *outside* the 'if' statements.
3. Statements (except 'if' and 'else' by themselves) need to end with a semi-colon.

I think you meant to write:

```
val=analog.read (potpin);     // read the pot

if(pin10==HIGH)               // pin 10 selects servo range
  val=map(val,0,1023,0,180);  // map the pot value ...
else                          //   into one of
  val=map(0,1023,0,90);       //   the servo ranges

servowrite(val);              // drive the servo

```

Update:

> I had try every thing , but there is some shaking and vibration when if condition is satisfied.

Was the shaking near rotation limits? Most servos, especially the inexpensive hobby ones, get unstable near each end of their travel. Some will move smoothly to the limit, others get shaky within a few degrees of the limit. Each one is a little bit different.

Update 2:

Here is a complete, working example based on the Arduino Servo-example and your specifications. There were two bugs above:

1. I left out the 'val' argument in one of the map commands. This cause a compile error and should have prevented you from testing it. It could not have run, properly or improperly.
2. In your code example, `if(pin10==HIGH)` doesn't read any input pin! It just reads some (unseen!) variable named 'pin10' - unless you did read the pin in some code you didn't show us? Which is why we ask for a minimum, *complete*, & verifiable example.

This code runs and rotates my sg90 servo through 90 degrees, if pin 10 is low, or 180 degrees, if pin 10 is high.

---
Tags: programming, servo, potentiometer
---


# Question
Title: Sketch starts and keeps counting on external power supply but not usb
Thank you for the add, total newbie here (electronics and arduino) on his first project.

Trying to make a counter for a hay baler with two HAL effect sensors, (pin 5 & 6) and outputting to an I2C display. One counts the amount of flakes per bale and the other the amount of bales (resetting the flakes on each bale and displaying an average)

I works perfectly whilst powered through USB, plug the 12v in and the counter just goes nuts and keeps counting without the magnet passing by the sensor.

* I have checked if there is 5v at the 5v pin.
* As soon as you take the trigger out of pin 5 or 6 the corresponding counter stops, put anything in the pin (even a bit of wire or a diode) and the counter starts taking off again.

```
//Bale and flake Counter
//Lourens Houttuin
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
//i2c pins
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); //
// set up a constant for the tilt switchPin
const int flakePin = 6;
const int balePin = 7;

int bales = 0;
int flakes = 0;
int avflakes = 0;

// variable to hold the value of the flakePin & bale pin
int switchState = 0;
int baleswitchState = 0;

// variable to hold previous value of the flakepin
int prevSwitchState = 0;
int prevBaleswitchstate = 0;

void setup() {
  // set up the number of columns and rows on the LCD
  lcd.begin(16, 2);

  // set up the switch pin as an input
  pinMode(flakePin,INPUT);
  pinMode(balePin,INPUT);

 lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Flakes: 0");
}

void loop() {
  // check the status of the switch
  switchState = digitalRead(flakePin);
  baleswitchState = digitalRead(balePin);

  // compare the switchState to its previous state
  if (baleswitchState != prevBaleswitchstate){
    if (baleswitchState == LOW) {
      bales = bales + 1;
      flakes = 0;
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Flakes:");
      lcd.setCursor(8, 0);
      lcd.print(flakes);
      lcd.print("/");
      lcd.print(avflakes/bales);
      lcd.setCursor (0,1);
      lcd.print("Bales:");
      lcd.setCursor (8,1);
      lcd.print(bales);
    }
  }
  if (switchState != prevSwitchState) {
    if (flakes>13){
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Flakes:");
      lcd.setCursor(8, 0);
      lcd.print("Speed UP");
    }
    if (switchState == LOW) {
      flakes = flakes + 1;
      avflakes=avflakes+1;
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Flakes:");
      lcd.setCursor(8, 0);
      lcd.print(flakes);
      lcd.print("/");
      lcd.print(avflakes/bales);
      lcd.setCursor (0,1);
      lcd.print("Bales:");
      lcd.setCursor (8,1);
      lcd.print(bales);
    }
  }
  // save the current switch state as the last state
  prevSwitchState = switchState;
  prevBaleswitchstate = baleswitchState;
}

```

# Answer
Is the 12v supply from a running vehicle? And the USB is from a computer? Is the Arduino in the same location for both tests or is it on your desk with the USB and on the vehicle for the 12v test?

Vehicle power is notoriously noisy - varying voltages, voltage spikes. I have run an Arduino successfully in my car supplied from a 5v USB charger in the cigarette lighter socket. Even with a thermo-sensor on a piece of Cat-5 cable coming out of the hood and through the driver's window (don't ask! :) I had quite steady readings and my display (I2C OLED) was solid. But do expect most external wiring to act like an antenna and pick up some of that noise. You might have to do some data smoothing or averaging to clean it up.

Update:

> The eventual finished unit will be mounted in a tractor with the sensors about 4 meters back

See if a car-USB charger fixes the problem on the bench. Does the tractor have a "cigarette lighter socket" power-point as a car does? If not, they are available as a standalone part.

Is it ignition-suppressed to not interfere with a radio, the way a car is? Or does the baler have its own engine (which is most probably not suppressed)? If no suppression, you may need to put the Arduino in a metal box, grounded to the tractor frame, and use a shielded cable between the box and the sensors. And if it's still noisy, possibly even locate the box closer to the sensors - that cable will be like an antenna for noise; you'll need to minimize it.
> 0 votes

---
Tags: lcd, usb, switch, wire-library
---


title: Adafruit nRF52 feather board [SOLVED]

text:
# Question
Title: Adafruit nRF52 feather board [SOLVED]
I am working on a project (the scenario is depicted in the attachment) involving Bluetooth Low Energy (BLE). As a master (central device) I am using the Adafruit nRF52 feather board (https://learn.adafruit.com/bluefruit-nrf52-feather-learning-guide/introduction) and as slaves (peripheral devices) a pair of Adafruit nRF8001 modules (https://learn.adafruit.com/getting-started-with-the-nrf8001-bluefruit-le-breakout/pinouts?view=all#introduction). Moreover, I have to wire the nRF52 up with an Arduino Uno rev3.

I am trying to set up the very initial communication between central and peripheral devices, but if I even try to upload the blinky sketch into the nRF52 board the compiling phase returns to me the following error:

> exec: "nrfutil": executable file not found in $PATH

Does anyone have an idea what it means? I googled a lot but I am not able to figure it out on this problem.

Thanks in advance to anyone would be able to help me!

Filippo

**\[EDIT\]** Solved: just need to install the nfrutil first, as written in https://learn.adafruit.com/bluefruit-nrf52-feather-learning-guide/arduino-bsp-setup#nrfutil-os-x-and-linux-only

# Answer
> 1 votes
Step 2 solves this problem:

https://learn.adafruit.com/bluefruit-nrf52-feather-learning-guide/arduino-bsp-setup

Also, read up about how to add something to Path Variable on Windows.

---
Tags: bluetooth
---


# Question
Title: How do I choose a battery to power my Arduino Nano project?
I was wondering if anyone would be willing to teach me how to *logically* choose/calculate which battery I should/can use to power my Arduino nano project (so I don't have to keep it connected to my computer to use it)? I am interested in learning, not just being given an answer because my goal is to be able to figure this out on my own for my next project. (Also, I got this far by myself because of a lot of trial and error in addition to reading as much as possible, but I don't want to buy an assortment of batteries for my trial and process of learning.) Thank you kindly.

If you are willing to teach, I have included all of the details about my project in the code below or at least I think I did.

Before I get to my code, one problem (I think) is that the two digit seven segment LED display that I bought for my project does not have a data sheet. However, even if it did, I am not sure that I would understand how to use it. I looked up other similar LED displays and if I understand what I am looking at, they seem to use between 2-3 V and 20-30 mA.

I thought that because I saw 2-3 V on the similar looking LED displays, I would be able to use a 3V battery to power my project. However, when I tried the following two batteries to power my project they did not work:

1. 3V CR2032 lithium cell battery (for LilyPad) - this was enough power to dimly turn the power light on the nano, but not enough to turn the lights on for my project.
2. E-Textiles Battery 3.7 V - 110mAh (2C Discharge) - this was also enough to dimly turn the power light on the nano, but not enough to turn the lights on for my project.

Because those did not work and it's all I had left, I tried a 9V battery:

3. 9V battery - this powers the project just fine, but I was hoping to calculate the actual voltage and/or current because I was hoping to use one of the tiny lithium ion batteries from SparkFun.com (or elsewhere) to power my project if this is possible.

Here is my code (Sorry that the code is a bit long. I couldn't figure out how the SevSeg library worked, so I just wrote my own code):

```
/************************************************************************************************************************
Rebecca Wilson
12/17/18

This program is for using an arduino nano to run a 2 digit 7 segment LED display. I made it as a life counter for
MTG, so it displays "20" to start and there are two buttons that can be used to change the life total by +/- 1.

These are the pieces I used:

1x Nano 3.0 Controller compaitible with arduino nano CH340 USB driver (taydaelectronics.com; SKU A-2864)
    *You must select "ATmega328P (Old Bootloader)" for the processor (otherwise it can't upload the file to the nano).
    *This also works with an arduino UNO, but I prefer to change the negativeButtonPin to 13 for the arduino Uno (I don't
     think pin 13 works on my nano because it is connected to the practice LED that comes attached to the board).

1x LED Display 7 segment 2 digit 0.28 Inch common anode HI RED (taydaelectronics.com; SKU A-1701)

2x Tact switch 6x6mm 5mm through hole SPST-NO (taydaelectronics.com; SKU A-5127)

2x 330 Ohm 1/4W 5% carbon film resistor (taydaelectronics.com; SKU A-2067)

breadboard and jumper wires

This is what I understand about the LED display:
  LOW means that the segment is turned on
  HIGH means that the digit is turned on and when that digit is turned on all segments are set to LOW (turned on)
*****************************************************************************************************************************/

//declare constants
int tensDigit = 10; //330 Ohm resistor between digit pin and nano pin
int onesDigit = 11; //330 Ohm resistor between digit pin and nano pin

int pinA = 2;
int pinB = 3;
int pinC = 4;
int pinD = 5;
int pinE = 6;
int pinF = 7;
int pinG = 8;
int pinDP = 9;

int positiveButtonPin = 12; //and the other side of the button is connected to the GND pin next to D2
int negativeButtonPin = A0; //and the other side of the button is connected to the GND pin next to D2

//declare variables
unsigned long lastPositiveDebounceTime = 0;
unsigned long lastNegativeDebounceTime = 0;
unsigned long debounceDelay = 100;
unsigned long previousMillis = 0;

int currentPositiveButtonState = HIGH;
int currentNegativeButtonState = HIGH;
int lastPositiveButtonState = LOW;
int lastNegativeButtonState = LOW;
int trueLastPositiveButtonState = LOW;
int trueLastNegativeButtonState = LOW;
int buttonPushCounter = 0;
int startingValue = 20;
int currentValue = startingValue;

//declare functions
void delayTime(unsigned long milliseconds);
void setDigit(int place, int number);
void setNumber(int number);

void setup() {

  pinMode(tensDigit, OUTPUT);
  pinMode(onesDigit, OUTPUT);
  pinMode(pinA, OUTPUT);
  pinMode(pinB, OUTPUT);
  pinMode(pinC, OUTPUT);
  pinMode(pinD, OUTPUT);
  pinMode(pinE, OUTPUT);
  pinMode(pinF, OUTPUT);
  pinMode(pinG, OUTPUT);
  pinMode(pinDP, OUTPUT);

  pinMode(positiveButtonPin, INPUT_PULLUP);
  pinMode(negativeButtonPin, INPUT_PULLUP);

  Serial.begin(9600);
}

void loop() {

  setNumber(currentValue);

  //read the current button state
  currentPositiveButtonState = digitalRead(positiveButtonPin);
  currentNegativeButtonState = digitalRead(negativeButtonPin);

  //if the positive button state has changed then record the new current time
  if (currentPositiveButtonState != lastPositiveButtonState)
  {
    lastPositiveDebounceTime = millis();
  }

  //if the button state did not change during the debounceDelay time, then consider it a true state change and...
  if ((millis() - lastPositiveDebounceTime) > debounceDelay)
  {
    //if the last true button state has changed then...
    if (currentPositiveButtonState != trueLastPositiveButtonState)
    {
      trueLastPositiveButtonState = currentPositiveButtonState;

      //if the button was pressed then increment the button pressed counter
      if (currentPositiveButtonState == LOW)
      {
        currentValue++;
        setNumber(currentValue);
        Serial.println(currentValue);
      }
    }
  }

  //change the last button reading to the current button reading
  lastPositiveButtonState = currentPositiveButtonState;

  //if the negative button state has changed then record the new current time
  if (currentNegativeButtonState != lastNegativeButtonState)
  {
    lastNegativeDebounceTime = millis();
  }

  //if the button state did not change during the debounceDelay time, then consider it a true state change and...
  if ((millis() - lastNegativeDebounceTime) > debounceDelay)
  {
    //if the last true button state has changed then...
    if (currentNegativeButtonState != trueLastNegativeButtonState)
    {
      trueLastNegativeButtonState = currentNegativeButtonState;

      //if the button was pressed then increment the button pressed counter
      if (currentNegativeButtonState == LOW)
      {
        currentValue--;
        setNumber(currentValue);
      }
    }
  }

  //change the last button reading to the current button reading
  lastNegativeButtonState = currentNegativeButtonState;

}

void setNumber(int number) {

  int onesPlace = number % 10;
  setDigit(1, onesPlace);
  delay(5);
  int tensPlace = number / 10;
  setDigit(10, tensPlace);
  delay(5);
}

//place is 1 if setting the ones place and 10 if setting the tens place
void setDigit(int place, int number) {
  switch(place)
  {
    case 1:
      digitalWrite(onesDigit, HIGH);
      digitalWrite(tensDigit, LOW);
      break;
    case 10:
      digitalWrite(onesDigit, LOW);
      digitalWrite(tensDigit, HIGH);
      break;
  }

  switch(number)
  {
    case 0:
      digitalWrite(pinA, LOW);
      digitalWrite(pinB, LOW);
      digitalWrite(pinC, LOW);
      digitalWrite(pinD, LOW);
      digitalWrite(pinE, LOW);
      digitalWrite(pinF, LOW);
      digitalWrite(pinG, HIGH);
      digitalWrite(pinDP, HIGH);
      break;
    case 1:
      digitalWrite(pinA, HIGH);
      digitalWrite(pinB, LOW);
      digitalWrite(pinC, LOW);
      digitalWrite(pinD, HIGH);
      digitalWrite(pinE, HIGH);
      digitalWrite(pinF, HIGH);
      digitalWrite(pinG, HIGH);
      digitalWrite(pinDP, HIGH);
      break;
    case 2:
      digitalWrite(pinA, LOW);
      digitalWrite(pinB, LOW);
      digitalWrite(pinC, HIGH);
      digitalWrite(pinD, LOW);
      digitalWrite(pinE, LOW);
      digitalWrite(pinF, HIGH);
      digitalWrite(pinG, LOW);
      digitalWrite(pinDP, HIGH);
      break;
    case 3:
      digitalWrite(pinA, LOW);
      digitalWrite(pinB, LOW);
      digitalWrite(pinC, LOW);
      digitalWrite(pinD, LOW);
      digitalWrite(pinE, HIGH);
      digitalWrite(pinF, HIGH);
      digitalWrite(pinG, LOW);
      digitalWrite(pinDP, HIGH);
      break;
    case 4:
      digitalWrite(pinA, HIGH);
      digitalWrite(pinB, LOW);
      digitalWrite(pinC, LOW);
      digitalWrite(pinD, HIGH);
      digitalWrite(pinE, HIGH);
      digitalWrite(pinF, LOW);
      digitalWrite(pinG, LOW);
      digitalWrite(pinDP, HIGH);
      break;
    case 5:
      digitalWrite(pinA, LOW);
      digitalWrite(pinB, HIGH);
      digitalWrite(pinC, LOW);
      digitalWrite(pinD, LOW);
      digitalWrite(pinE, HIGH);
      digitalWrite(pinF, LOW);
      digitalWrite(pinG, LOW);
      digitalWrite(pinDP, HIGH);
      break;
    case 6:
      digitalWrite(pinA, LOW);
      digitalWrite(pinB, HIGH);
      digitalWrite(pinC, LOW);
      digitalWrite(pinD, LOW);
      digitalWrite(pinE, LOW);
      digitalWrite(pinF, LOW);
      digitalWrite(pinG, LOW);
      digitalWrite(pinDP, HIGH);
      break;
    case 7:
      digitalWrite(pinA, LOW);
      digitalWrite(pinB, LOW);
      digitalWrite(pinC, LOW);
      digitalWrite(pinD, HIGH);
      digitalWrite(pinE, HIGH);
      digitalWrite(pinF, HIGH);
      digitalWrite(pinG, HIGH);
      digitalWrite(pinDP, HIGH);
      break;
    case 8:
      digitalWrite(pinA, LOW);
      digitalWrite(pinB, LOW);
      digitalWrite(pinC, LOW);
      digitalWrite(pinD, LOW);
      digitalWrite(pinE, LOW);
      digitalWrite(pinF, LOW);
      digitalWrite(pinG, LOW);
      digitalWrite(pinDP, HIGH);
      break;
    case 9:
      digitalWrite(pinA, LOW);
      digitalWrite(pinB, LOW);
      digitalWrite(pinC, LOW);
      digitalWrite(pinD, HIGH);
      digitalWrite(pinE, HIGH);
      digitalWrite(pinF, LOW);
      digitalWrite(pinG, LOW);
      digitalWrite(pinDP, HIGH);
      break;
  }
}

```

# Answer
> 1 votes
Consider the length of time needed with out external power and the average current the project demands. Multiply these two giving Amp-Hours. Then, given the Amp-Hours are reasonable, choose a battery with twice the Amp-Hour capacity. Battery ratings are usually ideal. In that the slower the power is pulled from the batteries the larger the battery capacity will appear.

It goes without saying you need enough cells to generate the specified voltage. Cell voltage varies by chemistry. Consequently note the exact voltage of a cell or pack of cells. Especially when building your own serial battery packs where slight differences add up to significant voltages.

Lastly consider if primary or secondary batteries are to be used. Primary cells such as alkaline batteries are long lasting and generally safer. Secondary batteries such as Lithium-ion offer good power density but are difficult to care for.

# Answer
> 1 votes
I don't think this will be a fully fledged answer, but I want to tell you a useful alternative to batteries you already used. I usually power my projects through a 5V "powerbank" that I do myself. All you need is a step-up board like for example 134N3P and any Li-Po/Li-Ion 3,7V cell. The 134N3P is very small and it contains a undervoltage and overcurrent protection circuits so you won't destroy the cell. It also allows to safely charge that cell using any USB charger. The Li-Po/Li-Ion cells come in all shapes and sizes. For miniature projects you can find one in size of a two coin batteries, but for regular size projects I suggest 18650 cells as the cheapest option.

---
Tags: arduino-nano, battery
---


title: String and heap confusion

text:
# Question
Title: String and heap confusion
I hope you all well.

Recently after view unknown crashes I decided it can be related with me messing with "heap"

After reading few sources on heaps and how it works it kind of confusing. Some sources mention that you can F() everything and it will be fine and others mention reserving space for strings with "reserve()"

I am looking for suggestions how possibly eliminate or or control?

I will post snapshot of code below where the evil "String" is used few times.

```
////////sending data
    senddata(String(temp), String(hum), String(dis), String(flood), String(heaterstatus), String(humidifierstatus));
    //////////sending data

void senddata(String temp1, String hum1, String dis1, String flood1, String heater1, String humid1) {   /////sending all field values in one go
  //////////sending data
  String getData = "GET /update?api_key=" + API + "&field1=" + temp1 + "&field2=" + hum1 + "&field3=" + dis1 + "&field4=" + flood1 + "&field5=" + heater1 + "&field6=" + humid1;
  sendCommand("AT+CIPMUX=1", 5, "OK");
  sendCommand("AT+CIPSTART=0,\"TCP\",\"" + HOST + "\"," + PORT, 15, "OK");
  sendCommand("AT+CIPSEND=0," + String(getData.length() + 4), 4, ">");
  esp8266.println(getData); delay(1500); countTrueCommand++;
  sendCommand("AT+CIPCLOSE=0", 5, "OK");
}

```

# Answer
> 0 votes
Yes, you could make a global String for `getData` and reserve space and reuse it every time the function is called. But what with `String(getData.length())`?

And the parameters? You create a new String for every parameter. And the function `senddata` doesn't take a reference to the String (String&), but it makes a new copy of each String parameter. So you create 12 small Strings with every call to this function. This is the evil of String. It does everything no matter at what cost.

And your sendCommand takes String too. That is why you can do `"AT+CIPSTART=0,\"TCP\",\"" + HOST + "\"," + PORT` and `"AT+CIPSEND=0," + String(getData.length() + 4)` as parameter to it. So every call to sendCommand creates two small Strings. That is 8. And every `+` on String can trigger a reallocation on heap.

Use C strings

```
void senddata(int temp1, int hum1, int dis1, int flood1, int heater1, int humid1) {
  char getData[256];
  snprintf(getData, sizeof(getData), "GET /update?api_key=%s&field1=%d&field2=%d&field3=%d&field4=%s&field5=%s&field6=%d",
      API, temp1, hum1, dis1, flood1, heater1, humid1);
  sendCommand("AT+CIPMUX=1", 5, "OK");
  char buff[32];
  snprintf(buff, sizeof(buff), "AT+CIPSTART=0,\"TCP\",\"%s\",%d" , HOST, PORT);
  sendCommand(buff, 15, "OK");
  snprintf(buff, sizeof(buff), "AT+CIPSEND=0,%d" , strlen(getData) + 4);
  sendCommand(buff, 4, ">");
}

void sendCommand(const char* command, const int timeout, const char* find) {

```

F macro optimizes memory use, by using data stored in flash memory. The snprintf\_P function is a version of snprintf for format string from flash.

```
snprintf_P(getData, sizeof(getData), (const char*) F("GET /update?api_key=%s&field1=%d&field2=%d&field3=%d&field4=%s&field5=%s&field6=%d"),
  API, temp1, hum1, dis1, flood1, heater1, humid1);

```

One of the classes of my StreamLib is CStringBuilder. With it the code could be:

```
char getData[256];
CStringBuilder sb(getData, sizeof(getData));
sb.printf(F("GET /update?api_key=%s&field1=%d&field2=%d&field3=%d&field4=%s&field5=%s&field6=%d"),
    API, temp1, hum1, dis1, flood1, heater1, humid1);
sendCommand("AT+CIPMUX=1", 5, "OK");
char buff[32];
CStringBuilder sb2(buff, sizeof(buff));
sb2.printf(F("AT+CIPSTART=0,\"TCP\",\"%s\",%d") , HOST, PORT);
sendCommand(buff, 15, "OK");
sb2.reset();
sb2.print(F("AT+CIPSEND=0,"));
sb2.print(sb.length() + 4);
sendCommand(buff, 4, ">");

```

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


# Question
Title: What could cause data to be printed correctly, then incorrectly and then repeated? CAN bus / general transmission
I am attempting to send data from an MPU6050 connected to an arduino uno to another uno via CAN bus, however i don't think this is a CAN bus specific issue.

In short, i am sending two packets of 8 bytes in the following formats

```
Packet 1 - (uint32_t/ int16_t/ int16_t)
Packet 2 - (int16_t/ int16_t/ int16_t/ int16_t)

```

all converted into bytes in this sort of fashion;

```
int16_t byte2Int(int16_t output, int pos, uint8_t data[2]){
      for (int i = 0; i < 2; i++)
    {
      output += ((int16_t)data[i + pos]) << (i * 8);
    }
    return output;
}

```

where everything should make sense apart from the "int pos" part which is just where in the buffer i want to start putting the data as packet 1 and 2 are different structures.

My issue is that with just one packet, i can print the values just fine, with the second packet added in i get the following on the serial monitor;

```
AccX    AccY    AccZ  GyX    GyY     GyZ

16832   -816    928 -440    16832   -816
16984   -940    992 -449    16984   -940
16896   -804    988 -462    16896   -804
209 55  0   0   209 55
16900   -852    1080    -471    16900   -852
16900   -852    1080    -471    16900   -852
16984   -760    948 -481    16984   -760
16880   -824    896 -459    16880   -824
230 102 0   0   230 102
16928   -860    996 -422    16928   -860
16928   -860    996 -422    16928   -860
17004   -856    864 -466    17004   -856
17004   -856    864 -466    17004   -856
214 105 0   0   214 105
16964   -828    944 -446    16964   -828
16964   -828    944 -446    16964   -828

```

As you can see i get some coherent messages, then some scrambled which don't make sense, then coherent again and the cycle continues. Not sure of relevance, but when i first start the serial monitor this doesn't happen, then after varying time, but around 5 seconds or so, it starts going amiss.

I believe this is down to my programming, and me not being able to code in a reliable way to wait for the first message to complete, then send the next one and them being read correctly. Below is my embarrassing attempt at sending an ACK message to the sender to say that the message has been received and to progress to the next message. I am not a programmer by nature and i am putting up this shoddy code that i've spent days trying to sort in the hope someone can point me in the right direction.

Apologies in advance.

```
// CAN Send Example
//

#include <mcp_can.h>
#include <SPI.h>
#include <Wire.h>

const int MPU_addr = 0x68; // I2C address of the MPU-6050
uint32_t TimeMicro;
int16_t AccX, AccY, AccZ, Tmp, GyX, GyY, GyZ;
int8_t data1[8], data2[8], rxBuf[8];
int Switch = 7;
long unsigned int rxId;
unsigned char len = 0;

#define CAN0_INT 2                              // Set INT to pin 2
MCP_CAN CAN0(10);     // Set CS to pin 10

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

  // Initialize MCP2515 running at 16MHz with a baudrate of 500kb/s and the masks and filters disabled.
  if(CAN0.begin(MCP_ANY, CAN_500KBPS, MCP_16MHZ) == CAN_OK) Serial.println("MCP2515 Initialized Successfully!");
  else Serial.println("Error Initializing MCP2515...");

  CAN0.setMode(MCP_NORMAL);   // Change to normal mode to allow messages to be transmitted

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

  Wire.begin();
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x6B);  // PWR_MGMT_1 register
  Wire.write(0);     // set to zero (wakes up the MPU-6050)
  Wire.endTransmission(true);

}

void loop()
{

  TimeMicro = millis();

  Wire.beginTransmission(MPU_addr);
  Wire.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(MPU_addr, 14, true); // request a total of 14 registers
  AccX = Wire.read() << 8 | Wire.read(); // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
  AccY = Wire.read() << 8 | Wire.read(); // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
  AccZ = Wire.read() << 8 | Wire.read(); // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
  Tmp = Wire.read() << 8 | Wire.read();
  GyX = Wire.read() << 8 | Wire.read(); // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
  GyY = Wire.read() << 8 | Wire.read(); // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
  GyZ = Wire.read() << 8 | Wire.read(); // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)

  double2Byte(TimeMicro, 0, data1);
  int2Byte(AccX, 4, data1);
  int2Byte(AccY, 6, data1);

  int2Byte(AccZ, 0, data2);
  int2Byte(GyX, 2, data2);
  int2Byte(GyY, 4, data2);
  int2Byte(GyZ, 6, data2);

  // send data:  ID = 0x100, Standard CAN Frame, Data length = 8 bytes, 'data' = array of data bytes to send
  byte sndStat = CAN0.sendMsgBuf(0x100, 0, 8, data1);

  if(!digitalRead(CAN0_INT))                         // If CAN0_INT pin is low, read receive buffer
  {
    CAN0.readMsgBuf(&rxId, &len, rxBuf);      // Read data: len = data length, buf = data byte(s)

    while(rxBuf[0] != 0x0A)
    {
      continue;
    }

  }
  delay(10);
  byte sndStat2 = CAN0.sendMsgBuf(0x100, 0, 8, data2);

    while(rxBuf[0] != 0x0A)
    {
      continue;
    }

  for(int i = 0; i < 8; i++)
  {
    data1[i] = 0;
    data2[i] = 0;
  }

}

//===================================================================================
//                                  FUNCTIONS
//===================================================================================
uint8_t int2Byte(int16_t input, int pos, uint8_t data[2]){
  for (int i = 0; i < 2; i++)
  {
    data[i+ pos] = ((input >> (i * 8)) & 0xff);
  }
return data[2];
}

uint8_t double2Byte(uint32_t input, int pos, uint8_t data[4]){
  for (int i = 0; i < 4; i++)
  {
    data[i+ pos] = ((input >> (i * 8)) & 0xff);
  }
return data[4];
}

/*********************************************************************************************************
  END FILE
*********************************************************************************************************/

```

Receiver

```
// CAN Receive Example
//

#include <mcp_can.h>
#include <SPI.h>

long unsigned int rxId;
unsigned char len = 0;
unsigned char rxBuf1[8];
unsigned char rxBuf2[8];
unsigned char txBuf[8];
char msgString[128];                        // Array to store serial string
uint32_t TimeMicro;
int16_t AccX, AccY, AccZ, GyX, GyY, GyZ;

#define CAN0_INT 2                              // Set INT to pin 2
MCP_CAN CAN0(10);                               // Set CS to pin 10

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

  // Initialize MCP2515 running at 16MHz with a baudrate of 500kb/s and the masks and filters disabled.
  if(CAN0.begin(MCP_ANY, CAN_500KBPS, MCP_16MHZ) == CAN_OK)
    Serial.println("MCP2515 Initialized Successfully!");
  else
    Serial.println("Error Initializing MCP2515...");

  CAN0.setMode(MCP_NORMAL);                     // Set operation mode to normal so the MCP2515 sends acks to received data.

  pinMode(CAN0_INT, INPUT);                            // Configuring pin for /INT input

  Serial.println("MCP2515 Library Receive Example...");
}

void loop()
{
  if(!digitalRead(CAN0_INT))                         // If CAN0_INT pin is low, read receive buffer
  {
    CAN0.readMsgBuf(&rxId, &len, rxBuf1);      // Read data: len = data length, buf = data byte(s)
  }

  for(int i; i < 8; i++){
    txBuf[i] = 0x0A;
  }

  byte sndStat = CAN0.sendMsgBuf(0x101, 0, 8, txBuf);

  if(!digitalRead(CAN0_INT))                         // If CAN0_INT pin is low, read receive buffer
  {
  CAN0.readMsgBuf(&rxId, &len, rxBuf1);      // Read data: len = data length, buf = data byte(s)
  }

  byte sndStat2 = CAN0.sendMsgBuf(0x101, 0, 8, txBuf);

  TimeMicro = byte2Double(TimeMicro, 0, rxBuf1);
  AccX = byte2Int(AccX, 4, rxBuf1);
  AccY = byte2Int(AccY, 6, rxBuf1);
  AccZ = byte2Int(AccZ, 0, rxBuf2);
  GyX = byte2Int(GyX, 2, rxBuf2);
  GyY = byte2Int(GyY, 4, rxBuf2);
  GyZ = byte2Int(GyZ, 6, rxBuf2);

  Serial.print(TimeMicro);
  Serial.print("\t");
  Serial.print(AccX);
  Serial.print("\t");
  Serial.print(AccY);
  Serial.print("\t");
  Serial.print(AccZ);
  Serial.print("\t");
  Serial.print(GyX);
  Serial.print("\t");
  Serial.print(GyY);
  Serial.print("\t");
  Serial.println(GyZ);

  TimeMicro = 0;
  AccX = 0;
  AccY = 0;
  AccZ = 0;
  GyX = 0;
  GyY = 0;
  GyZ = 0;

}

//===================================================================================
//                                  FUNCTIONS
//===================================================================================

uint32_t byte2Double(uint32_t output, int pos, uint8_t data[4]){
      for (int i = 0; i < 4; i++)
    {
      output += ((uint32_t)rxBuf1[i + pos]) << (i * 8);
    }
    return output;
}

int16_t byte2Int(int16_t output, int pos, uint8_t data[2]){
      for (int i = 0; i < 2; i++)
    {
      output += ((int16_t)rxBuf1[i + pos]) << (i * 8);
    }
    return output;
}
/*********************************************************************************************************
  END FILE
*********************************************************************************************************/

```

I've tried debugging this by the following;

* check that the MPU is sending correctly (Fine)
* check if it happens with just one packet (no problems)
* check if the packets are assembled correctly on the sender ( got the data, broke it into bytes and reassembled and printed that result. did what i expected)
* removed time from being sent incase that was causing an issue (same problem as illustrated above)
* removed all serial prints and just did one value (still an issue)

So i believe that it is down to a terrible and non working attempt at sending an acknowledgment message. I have tried researching but i couldn't find an example for CAN bus, and all the others were using protocol specific interrupt routines which i tried to implement but didn't work. obviously.

Thankyou for your patience

# Answer
> 1 votes
DISCLAIMER: Ok, I never worked with CAN on arduino, so I may be terribly wrong, nor I have the required boards to test this, so I may make a lot of errors; if you find any issue, please point them out, so I can fix them (or if you fixed them notify me, so I can update the reply for the future readers).

Ok, from what I can read you are have two packets, but only one CAN frame. This seems to me a huge inefficiency, because how can you know which frame have you just received?

To fix this, you can either use two frames or use something in the payload that informs you which frame you have received. In my opinion, since there are a lot of free IDs, you can use the first approach.

Moreover you are performing some checks in the processing (e.g. "did I receive an ack?"), but if this fails you go on without further checking. For instance, when in the sender you write:

```
byte sndStat = CAN0.sendMsgBuf(0x100, 0, 8, data1);
if(!digitalRead(CAN0_INT))
{
  ...
}
delay(10);
byte sndStat2 = CAN0.sendMsgBuf(0x100, 0, 8, data2);

```

what happens when CAN0\_INT is still high? Yes, it sends the data immediately.

I could not understand the `while(rxBuf[0] != 0x0A)` part; it will block your program forever...

Finally when you receive a message you never check the ID; this means you will check all the messages on CAN, and when you add another device on the net you will not be able to send any other message.

Ok, so this is what I'd try for your needs:

* The TX board will always transmit data, while the RX board will always receive it. No ack frames is needed
* There will be two frames on the network: frame 0x100 will have packet 1, while frame 0x101 will have packet 2
* The TX board will send one message every 100ms; this can be reduced, but specify a time rather than having the part send frames "continuously"
* The RX board will consider the data valid only after a 0x101 packet is received and a 0x100 packet was received before.

So, here is the code. Please note that I refactored some parts for easier understanding (putting some code in functions to have a smaller "higher level" setup and loop functions.

BTW what is the "Switch" in the sender? It is never used...

Sender:

```
// CAN Send Example
//

#include <mcp_can.h>
#include <SPI.h>
#include <Wire.h>

const int MPU_addr = 0x68; // I2C address of the MPU-6050

uint32_t lastTimeSent;
uint32_t currMillis;
const uint32_t intervalSendMs = 100; // Send period in milliseconds

int16_t AccX, AccY, AccZ, Tmp, GyX, GyY, GyZ;
uint8_t data1[8], data2[8];
int Switch = 7;

#define CAN0_INT 2    // Set INT to pin 2
MCP_CAN CAN0(10);     // Set CS to pin 10

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

    initializeMCP2515();

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

    initializeMPU6050();
}

void loop()
{
    currMillis = millis();

    if ((currMillis - lastTimeSent) >= intervalSendMs)
    {
        lastTimeSent += intervalSendMs;

        readFromMPU6050();

        convertDataToPackets();

        // Send the two frames; if the first sending is successful send also the second, otherwise abort
        // send data frame 1:  ID = 0x100, Standard CAN Frame, Data length = 8 bytes, 'data' = array of data bytes to send
        // send data frame 2:  ID = 0x101, Standard CAN Frame, Data length = 8 bytes, 'data' = array of data bytes to send
        if (CAN0.sendMsgBuf(0x100, 0, 8, data1) == CAN_OK)
            CAN0.sendMsgBuf(0x101, 0, 8, data2);
    }
}

//===================================================================================
//                                  FUNCTIONS
//===================================================================================
void initializeMCP2515()
{
    // Initialize MCP2515 running at 16MHz with a baudrate of 500kb/s and the masks and filters disabled.
    if(CAN0.begin(MCP_ANY, CAN_500KBPS, MCP_16MHZ) == CAN_OK)
        Serial.println("MCP2515 Initialized Successfully!");
    else
        Serial.println("Error Initializing MCP2515...");

    CAN0.setMode(MCP_NORMAL);   // Change to normal mode to allow messages to be transmitted
}

void initializeMPU6050()
{
    Wire.begin();
    Wire.beginTransmission(MPU_addr);
    Wire.write(0x6B);  // PWR_MGMT_1 register
    Wire.write(0);     // set to zero (wakes up the MPU-6050)
    Wire.endTransmission(true);
}

void readFromMPU6050()
{
    Wire.beginTransmission(MPU_addr);
    Wire.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)
    Wire.endTransmission(false);
    Wire.requestFrom(MPU_addr, 14, true); // request a total of 14 registers
    AccX = Wire.read() << 8 | Wire.read(); // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
    AccY = Wire.read() << 8 | Wire.read(); // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
    AccZ = Wire.read() << 8 | Wire.read(); // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
    Tmp = Wire.read() << 8 | Wire.read();
    GyX = Wire.read() << 8 | Wire.read(); // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
    GyY = Wire.read() << 8 | Wire.read(); // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
    GyZ = Wire.read() << 8 | Wire.read(); // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)
}

void convertDataToPackets()
{
    long2Byte(currMillis, 0, data1);
    int2Byte(AccX, 4, data1);
    int2Byte(AccY, 6, data1);

    int2Byte(AccZ, 0, data2);
    int2Byte(GyX, 2, data2);
    int2Byte(GyY, 4, data2);
    int2Byte(GyZ, 6, data2);
}

void int2Byte(int16_t input, int pos, uint8_t *data)
{
    for (int i = 0; i < 2; i++)
    {
        data[i + pos] = ((input >> (i * 8)) & 0xff);
    }
}

void long2Byte(uint32_t input, int pos, uint8_t *data)
{
    for (int i = 0; i < 4; i++)
    {
        data[i + pos] = ((input >> (i * 8)) & 0xff);
    }
}

/*********************************************************************************************************
  END FILE
*********************************************************************************************************/

```

Receiver:

```
// CAN Receive Example
//

#include <mcp_can.h>
#include <SPI.h>

long unsigned int rxId;
unsigned char len = 0;
unsigned char rxBuf[8];
uint8_t receivedFirstFrame;

char msgString[128];                        // Array to store serial string
uint32_t TimeMicro;
int16_t AccX, AccY, AccZ, GyX, GyY, GyZ;

#define CAN0_INT 2  // Set INT to pin 2
MCP_CAN CAN0(10);   // Set CS to pin 10

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

    initializeMCP2515();

    Serial.println("MCP2515 Library Receive Example...");
    receivedFirstFrame = 0;
}

void loop()
{
    if(!digitalRead(CAN0_INT))
    {
        // Received a message
        if (CAN0.readMsgBuf(&rxId, &len, rxBuf) == CAN_OK)
        {
            // Note: the above line is not like in the examples, but looking at the code the
            // function may return if no message was in the queue, so I think this is safer

            // Let's check if it is one of the known messages
            switch (rxId)
            {
            case 0x100:
                { // Received first frame
                    // Decode the content and store that the first frame was received
                    decodeFirstFrame(rxBuf);
                    receivedFirstFrame = 1;
                }
                break;
            case 0x101:
                if (receivedFirstFrame)
                { // Received second frame after a first frame
                    // Decode the content
                    decodeSecondFrame(rxBuf);

                    printDataToSerial();

                    receivedFirstFrame = 0;
                }
                break;
            }
        }
    }
}

//===================================================================================
//                                  FUNCTIONS
//===================================================================================

void initializeMCP2515()
{
    // Initialize MCP2515 running at 16MHz with a baudrate of 500kb/s and the masks and filters disabled.
    if(CAN0.begin(MCP_ANY, CAN_500KBPS, MCP_16MHZ) == CAN_OK)
        Serial.println("MCP2515 Initialized Successfully!");
    else
        Serial.println("Error Initializing MCP2515...");

    CAN0.setMode(MCP_NORMAL); // Change to normal mode to allow messages to be transmitted

    pinMode(CAN0_INT, INPUT); // Configuring pin for /INT input
}

void decodeFirstFrame(uint8_t *buffer)
{
    TimeMicro = byte2Double(0, buffer);
    AccX = byte2Int(4, buffer);
    AccY = byte2Int(6, buffer);
}

void decodeSecondFrame(uint8_t *buffer)
{
    AccZ = byte2Int(0, buffer);
    GyX = byte2Int(2, buffer);
    GyY = byte2Int(4, buffer);
    GyZ = byte2Int(6, buffer);
}

void printDataToSerial()
{
    Serial.print(TimeMicro);
    Serial.print("\t");
    Serial.print(AccX);
    Serial.print("\t");
    Serial.print(AccY);
    Serial.print("\t");
    Serial.print(AccZ);
    Serial.print("\t");
    Serial.print(GyX);
    Serial.print("\t");
    Serial.print(GyY);
    Serial.print("\t");
    Serial.println(GyZ);
}

uint32_t byte2Double(int pos, uint8_t *data)
{
    uint32_t output = 0;
    for (int i = 0; i < 4; i++)
    {
      output += ((uint32_t)data[i + pos]) << (i * 8);
    }
    return output;
}

int16_t byte2Int(int pos, uint8_t *data)
{
    int16_t output = 0;
    for (int i = 0; i < 2; i++)
    {
      output += ((int16_t)data[i + pos]) << (i * 8);
    }
    return output;
}
/*********************************************************************************************************
  END FILE
*********************************************************************************************************/

```

Please let me know if you have any comments or find some issues with this.

# Answer
> 1 votes
There are indeed a few coding issues in your sketch, especially in the receiver part. I will try to list them and suggest changes.

1. If you look closely to your received data, you will see that `AccX==GyY` and `AccY==GyZ` on every line of your output. This is because you use the global variable `rxBuf1` in your `byte2Int` and `byte2Double` functions on the receiver side. This causes the output to consume `rxBuf1` also for the second CAN frame. Instead you should use the pointer to `data` that you have prepared in the inputs for this purpose.
2. In the receiver sketch, for both times you read in the CAN message with `CAN0.readMsgBuf` you write the result to `rxBuf1`, although for the second read you most likely intended to write to `rxBuf2`. Now you simply overwrite `rxBuf1` and therefore the content of the first received CAN message in the loop is never evaluated.
3. The switched outputs every few lines, in my opinion, are most likely due to a mixed order of both messages on the receiver side, when you receive CAN message 2 before CAN message 1. In order to avoid this, please follow the nice suggestions by @frarugi87 to send both messages with separate CAN IDs and to check for receiption of both before printing them.
4. I also agree that you can get rid of the acknowledge reply from the receiver. The can protocol already contains an acknowledge mechanism on the CAN transceiver that will notify the sender that at least one listening node has correctly received the message. If the sender does not get this acknowledge indication, it will repeat to send the message for some time.

---
Tags: arduino-uno, serial, communication, mpu6050, can-bus
---


# Question
Title: Multiple I2C slave devices on Arduino - Pull-up values
This question is asked a lot and I've found many usable details on different forums regarding adding pull-up resistors on SDA/SCL lines. I know that only one resistor should be added on these lines regardless of how many devices are attached.

One thing that is not clear for me is that what if I2C devices are powered on from different sources, at different timing? In following schematic, I have used pull up resistors for both I2C devices. Considering devices might be turned on and off at different timing, or even one device might be absent, is it fine to remove the second pull up resistors (second I2C device) and connect them directly to SDA/SCL pins on uC? In this case (removing pull-up resistors from second device), what happens if device 1 is not available and only second device is connected?

---edit:

* Schematic was updated to include only one pair of pull up resistors connected to master side.
* I will not how swap or hot plug I2C devices.
* I2C devices are sensors (BME280 here, and Chirp capacitive soil moisture, here), not on breakout boards with preset pull up resistors.
* Is it possible to just connect resistors on master side and not slave side? In this case, would it be fine for both sensors?

simulate this circuit – Schematic created using CircuitLab

# Answer
You should consider adding some bus isolation between each slave and the master. The reason being is that the ESD diodes in the SCL/SDA pins of a slave that is powered down could be interfering with the I2C bus as they leech power from the bus to feed through the internals of the slave. Given the low current imposed by the pullup resistors being the only power source this shouldn't cause any damage to the slave, but it may well cause the I2C bus to be seen as LOW when it shouldn't, causing communication to fail.

You should add a buffer with an "enable" pin of its own between each slave and the bus. My device of choice is the PCA9306 from Texas Instruments. It also means that the slave has its own separate pullup resistors powered by its own 3.3V rail, keeping all the power separate.

You would then have sequences such as:

1. Power up slave
2. Give short powerup delay (if needed)
3. Enable PCA9306
4. Do I2C transactions
5. Disable PCA9306
6. Power off slave

The PCA9306 can also be used to connect 3.3V slaves to a 5V MCU if needed.

simulate this circuit – Schematic created using CircuitLab
> 2 votes

# Answer
I would include one resistor on each line at the master, powered by the master. That isn't the only option, just what I consider a cleaner simpler option.

The resistance is needed to provide the high seen on the line. The value of the resistance can vary. There is no one correct value. The pull up resistance needs to provide a high in the required time. There are specifications for this.

https://www.i2c-bus.org/specification/

If the lines do not have a lot of capacitance (wire and device capacitance) then a higher value resistance may be sufficient to meet the timing specification. If there is more capacitance then a lower resistance would be required to provide the stronger pull up in order to meet the timing requirements.

As far as multiple resistances. Yes there can be more than one on the line. But the accumulated resistance must be taken into account.

Many I2C devices mounted on a breakout board have pull up resistors. Typically these are around 5K Ohms. So if there are two devices, each with their own resistors, the combined total will still be within the lowest resistance that would be acceptable.

One thing to note. The specification does not list a lowest resistance that can be used. Instead it specifies the minimum sinking requirement of a device that would need to pull the voltage low enough. So a current is specified, and this current can be used to calculate the minimum resistance on the line.

The current spec (somewhere about 3ma I think, or maybe 2ma??) would calculate to being a 1k6 resistance when used with a 5 volt supply. With a 3.3 volt supply the calculated value would be about 1k1 Ohms. (again, this is a rough calculation, close enough for handgrenades)

This is enough of an answer considering what was asked. There are different modes/speeds and different combinations that can be applied and things can get very involved. And then you must spend the time and look at the specifications. But for most Arduino work this rough guide should cover most "normal" situations.

It really is quite an interesting technology.
> 1 votes

# Answer
I wanted to add this as a comment but I ran out of characters, so this isn't an answer, just more comment.

```
@Majenko "I would never suggest using I2C over anything other than short PCB traces. i2C + wires = no thank you sir."

```

And that made me write the following.

We had one product that needed an external radio module. I put a connector in to extend the I2C bus. Total length of the additional cable was about 4 feet. Enough to route it outside the box and mount the radio close by.

Much later I am asked to look at why the communications is failing. The engineering manager had the cable extended to 20 feet. It worked for him *on the bench* when he tested it. No scope check on waveforms. No calculations. (he was a firmware programmer with just enough hardware knowledge to do his job)

I looked at the waveforms with a scope and I was shocked that it worked at all. The I2C lines were cpu to cpu. The radio had a microcontroller that acted as a slave I2C device.

I put a couple of buffers on either end and all was back in spec and it worked reliably after that, in the field and not just on the bench.

We have a bigger control box that uses I2C to communicate to modules in the back of the box. I have a buffer at the CPU end. The cpu is 3.3v, the modules are 5 volts. The buffer does a level conversion and stronger drive than the cpu could handle. The back of the boxes are shown below. Space for 14 modules. The bigger box is about 2 feet wide and 3 feet tall. The I2C lines run vertically down the center of each of the columns on the back of the board.

There also can be a secondary slave box for an additional 14 modules. The same back board. I used a second I2C port with and isolated I2C buffer for driving the lines. The slave boax was to be mounted beside the main box. Again I specified a short cable, this time six feet in length.

So one day I am asked if the cable can be extended. The contractor installing the panels wanted to put the slave boax on the other side of the hall by another electrical panel. I ask how long do they need. I'm told it is ten feet away. Yeah, ten feet line of sight. Once the cable was touted up into the ceiling, across the hall, and then down to the other box, the 10 feet turned into 30 feet.

I did a check with a scope. The rise times were still in spec, it seemed to work, so we made up a cable and told them that it may or may not work. Use at their own risk. I told them this was an exception and it is not to be a part of the product offering. But I'm sure there will be more exceptions.

And while it can work over those kind of distances the following shows how I2C can fail over short distances.

Same equipment. The smaller box in the picture was expanded with an additional larger box. The smaller box was mounted eight inches above the bigger box. (display and main cpu in the front panel of the product) Only temperature input into the modules in the smaller box. The bigger box was loaded with modules with control relays. Four 17 amp relays per module. Same electronics as in the exception described above. But they were having lots of sporadic behaviour. Pictures of the wiring, the installation, looked clean and well done. I had no idea why it was failing.

After this had been going on for a couple of months I asked our customer service person to ask what they have connected to our relays. Normally it would be motor up to 1 hp. They were controlling bigger motors and they had our relays turning on power contactors in a different panel. Lots of power contactors. All generating voltage spikes when they were turned off. I had them put snubbers across the contactor coils and the problems went away.

So I2C can work over longer distances, and it can fail over shorter distances. The whole picture needs to be taken into account. The problem is the whole picture often is hard to see.
> 1 votes

---
Tags: i2c, resistor, pull-up
---


# Question
Title: Bad Communication with Multiple I2C Devices
I have an Arduino Micro connected to two I2C devices. An MPU-6050 that is powered by 5V (though it has its own voltage regulator on it) and a Altimeter that is powered by 3.3V. They are both connected to the SDA and SCL.

I noticed that when I have the MPU powered on but don't power the 3.3V altimeter, the MPU does not communicate with the Arduino. I need to have the 3.3V power on to just communicate with the MPU through I2C. Why does this happen?

Then unfortunately, I believe I may have shorted the 3.3V rail and broke the altimeter. When I remove the MPU from the equation and try to just communicate with the Altimeter, I get nothing. Does this mean that I did short the device, or is there something else going on with I2C that I don't understand?

I have attached a schematic below of how the devices are connected.

# Answer
> 1 votes
> I would like to know why when one device is bad (or not powered) on I2C, it screws up the other devices.

The I2C lines need to have a pull up resistor to provide the high. The master device, and the slave devices, ground the line to provide a low, but they release the line, and not drive it at all, in order to provide the high.

Consider switches a and b to be inside the I2C device. When the switch a is open point A will be at 5 volts. When switch a is closed, point A will be at 0 volts.

Now if you had a second set of R resistors on the same line, but powered from their own 5 volt power supply, the same voltages will be seen at A when switch a is open (5 volts) and switch a is closed (0 volts).

But now if we kill the supply feeding the second set of R resistors (sorry that I can't show them in a picture) instead of pulling up to 5 volts (because we killed the 5 volts) the resistors will be pulling down due to whatever other loads there are on the killed 5 volt supply. And just for argument sake, let's say the killed 5 volt supply was at 0 volts.

So if one set of resistors is pulling up to 5 volts (the still powered pair) and one pulling down (the killed pair) then the voltage at points A and B will not be as high as the 5 volts we would see when the switches are open. If all the resistors R were the same value, and the killed supply was at 0 volts, then the highest voltage at A or B would be 2.5 volts. And that is not a good high.

So the additional device, that is not being powered, has disrupted the communitations, preventing true highs. Lows are not affected as the switch will pull the line low.

I don't know the values of all your pull up resistors, and don't know how low the dead supply goes, so I can't say what the new lower highest voltage is. But it seems that it is low enough to make the communications stop working.

And the resistor are not the only thing that can be disgusting the high. The unpowered chip can be providing unexpected current paths. Most port pins have an internal diode to Vcc. And since the chip has no power on Vcc the current on the I2C lines can follow that path to ground.

Also, I think you have drawn the resistors wrong. If they were in series with the SDA and the SCL pins there would be no communications because the 1k resistors doesn't allow the SDA line to be pulled low enough. I think those resistors are pull up resistors. Maybe you can take another look and confirm the connection.

# Answer
> 1 votes
When a device is unpowered any voltage placed on an IO pin is leeched off and fed to the VCC pin through the internal ESD protection diodes. On a bus like I2C this then cripples the bus. (Note: even if there are no intentional protection diodes the MOSFETs that drive the lines have diodes built into them and these act as protection diodes, but they are very weak and can be easily broken).

**You cannot have an unpowered device on an I2C bus** and doing so risks damaging the unpowered device (although the limited current provided by the pullup resistors should mitigate this).

If you want to have an unpowered device on the bus you **must** isolate it from the bus. I use the PCA9306 as in this answer, but other devices are available.

Did you kill the device by shorting it out? Possibly. It depends what you shorted to where. 3.3V directly onto the SDA or SCL pin while the device is unpowered may well have killed that pin.

---
Tags: i2c
---


# Question
Title: How can we use two devices at the same time with arduino?
I am using fingerprint module r307 and LCD together. In that, I am using 2,3 digital pins of arduino for data transfer to the fingerprint.(I tried other pin configurations for this but it didn't work) But as I am connecting LCD, it also requires same 2,3 digital pins of arduino and it is not possible for me to use 2 and 3 pins of Arduino for both lcd and fingerprint sensor for data transfer. Can you please suggest an alternative to this. Can we use analog pins of arduino as digital ones and if so the how?? PLEASE HELP... Thank you!!

# Answer
> Can we use analog pins of arduino as digital ones and if so the how??

Yes. You just treat them the same as any other digital pin. On an Arduino all pins are digital. It's just that some have *additional* functionality, like analog input, or PWM, or serial, or SPI, etc.
> 1 votes

---
Tags: lcd, pins, digital
---


title: MPU6050 Calibration

text:
# Question
Title: MPU6050 Calibration
Why does the MPU6050 IMU sensor not require calibration? I've used other gyro sensors on RC helicopters that required calibration at boot. Also, how does it know what its neutral position is considering that I don't need to calibrate it?

# Answer
**It's not entirely true that it does not require any calibration at all.**

The MPU60X0 family's triple-axis MEMS gyroscope has certain features that **reduce** the need for calibration. These features are, as mentioned by Juraj, and on the datasheet:

* Enhanced bias
* Sensitivity temperature stability

This does not mean the sensor is 100% properly calibrated right out of the box, which means if you need it to be extremely accurate, you'd probably have to do some manual calibration on top of the built-in calibration features.

There is a discussion about this on this Github issue. I suggest reading up on that and you might be able to answer your own questions. They are also referring to this datasheet (Direct Download).
> 2 votes

---
Tags: serial, arduino-nano, mpu6050
---


# Question
Title: Arduino potentiometer (external power) with amplifier
i am trying to make some kind of an amplifier. I got an amp board but want to read out the value from the potentiometer. The problem is that this pot is connected to the amp and has to be connected to the amps power Is there any way i can still read data (with an arduino) so that i can have a volume percentage on a lcd? Or is this imposible?

Amp 24v Potentiometer = 6pin. B50k

also what zould happen if i connect a 10k resistor instead of a 50k ressistor (audio potentiometer) what would the effect be?

# Answer
> 1 votes
It's impossible. The pot is most probably acting as a passive variable attenuator. As such the top end will be the incoming audio signal, the lower end will be ground, and the wiper will be the attenuated incoming signal. There's not a lot you can do with that.

You would need to replace the pot with an equivalent triple pot (if such a thing exists) and have one third of it connected to the Arduino. The pot you have at the moment is a dual pot, and a log taper at that.

Alternatively adding some kind of quadrature (motor) encoder to the shaft of the pot may be a possibility.

# Answer
> 0 votes
A few options come to my mind:

* I see you're using a double potentiometer, if you're using only one of it's outputs to control, you can use the other output to measure it's setting. (Or indeed use a "triple potentiometer" or added encoder as Majenko suggested.)
* Use the Arduino as an intermediate (have the potentiometer as an input on the Arduino and control the output accordingly on the output of the Arduino).
* Measure the output of the potentiometer. I'm not quite sure but the resistance over the potentiometer shouldn't be anything different depending on what is connected as well. Though you could also measure the output voltage on the potentiometer and from there deduce what it's value is (which may be difficult if it's an audio signal on this point in your system).

---
Tags: electronics, audio, potentiometer
---


title: WiFi.setOutputPower();

text:
# Question
Title: WiFi.setOutputPower();
I'm trying to cut my esp8266 range down to about a meter to save power. I know that I can adjust output power but I don't know enough to understand what a given setting will actually yield.

I can set zero to kill it or 20.5 to set max range, but what setting is appropriate for a meter or so? Is there a rule of thumb?

# Answer
> 1 votes
The actual WiFi range is highly dependent on many more factors than just the TX power:

1. The antenna gain, directionality, and orientation of the receiver
2. The antenna gain, directionality, and orientation of the transmitter
3. The proximity of radio-reflective objects nearby (metal)
4. The proximity of radio absorbing objects nearby (humans)
5. RF Black Magic

In practice, test your situation by running a series of tests at lower and lower power settings until you get an unreliable connection, then bump it up a couple of notches from there.

Do not rely on transmitter power for security, however. You cannot stop someone from pointing a high-gain antenna at your device and communicating with it from a distance farther than 1 meter. TX power reduction should primarily be for energy conservation.

---
Tags: esp8266, wifi
---


title: ESP8266 like WiFi modules

text:
# Question
Title: ESP8266 like WiFi modules
I am trying to make a circuit using Nodemcu ESP8266 to control the speed and direction of 3 DC servo motors, however I am short of analog pins. So are there any ways to increase the number of analog pins? Or are there other WiFi modules like the ESP8266, but with more number of analog pins?

# Answer
> 4 votes
How many PWMs do you need?

Here you can find a useful description about PWMs on ESP8266 NodeMCU.

According to image, ESP8266 NodeMcu has 9 PWMs pin.

---
Tags: esp8266
---