title: Arduino Zero RTC alarm not running loop

text:
# Question
Title: Arduino Zero RTC alarm not running loop
Using an ATSAMD21 with the Arduino core, I'm running into an issue where the RTCZero alarm callback won't continue running the loop() function. If I schedule another alarm inside the callback, the second alarm will execute the loop() function after the callback is done. Every second time it works, every other time it doesn't.

Minimal example in which I expect the LED to change state every 2 seconds, which does not happen:

```
#include <RTCZero.h>
#include <time.h>

RTCZero rtc;

void setup()
{
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);

  rtc.begin();
  rtc.attachInterrupt(alarmMatch);
  schedule_wake_up();
  rtc.enableAlarm(rtc.MATCH_HHMMSS);
}

void loop()
{
  digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
  schedule_wake_up();
  rtc.standbyMode();    // Sleep until next alarm match
}

void schedule_wake_up() {
  time_t wakeupTimestamp = rtc.getEpoch();
  wakeupTimestamp += 2;
  struct tm *wakeupTimeStruct = gmtime(&wakeupTimestamp);

  rtc.setAlarmSeconds( wakeupTimeStruct->tm_sec );
  rtc.setAlarmMinutes( wakeupTimeStruct->tm_min );
  rtc.setAlarmHours( wakeupTimeStruct->tm_hour );
}

void alarmMatch()
{
  // Do nothing, just wake up
}

```
* Arduino IDE 1.8.9
* RTCZero ver 1.6.0
* SAMD core ver 1.8.4 and 1.6.20 tried

# Answer
> 0 votes
I ended up deleting my copy of RTCZero and installing a new one via the Arduino IDE library manager. This solved the issue.

The difference between my local copy and the upstream one is in the standbyMode() function. I had the following PR merged into my local copy of this function: https://github.com/arduino-libraries/RTCZero/pull/46/files

After I installed the clean copy I went and replaced the standbyMode() function's content with the following: https://github.com/arduino-libraries/ArduinoLowPower/blob/892594adbccf45b198fc067ea994048c76523936/src/samd/ArduinoLowPower.cpp#L18

---
Tags: rtc, arduino-zero, samd21g
---


title: Reduce Sketch Size Help!

text:
# Question
Title: Reduce Sketch Size Help!
I dont know what to do?

Sketch uses 3712 bytes (12%) of program storage space. Maximum is 30720 bytes.

Global variables use 210 bytes (10%) of dynamic memory, leaving 1838 bytes for local variables. Maximum is 2048 bytes.

Program:

```
String texto;
int flag;
void setup() {
Serial.begin(9600);
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);
pinMode(12, OUTPUT);
pinMode(7, OUTPUT);//luz stop
pinMode(8, OUTPUT);//faros
}
void loop() {
while (Serial.available())//
{
delay (10);
if (Serial.available() > 0) //verifica que este disponible el puerto serie y verifica que haya algun
caracter
{
char c = Serial.read(); //guara cualquier caracter que haya llegado por el puerto serie
texto += c; //concatenamos
}
} ///Sentencias de control///
if (texto == "1") //compara el contenido de la avariable "texto" con el numero 1
{
digitalWrite(7,LOW); //Apaga la luz stop
digitalWrite(11, LOW);
digitalWrite(12, HIGH);
digitalWrite(10, HIGH);
digitalWrite(9, LOW);
}
if (texto == "3") //compara el contenido de la avariable "texto" con el numero 3
{
digitalWrite(7,LOW); //Apaga la luz stop
digitalWrite(11, HIGH);
digitalWrite(12, LOW);
digitalWrite(10, LOW);
digitalWrite(9, HIGH);
}
if (texto == "2") //compara el contenido de la avariable "texto" con el numero 2
{
digitalWrite(7,LOW); //Apaga la luz stop
digitalWrite(11, LOW);
digitalWrite(12, HIGH);
digitalWrite(10, LOW);
digitalWrite(9, HIGH);
}
if (texto == "4") //compara el contenido de la avariable "texto" con el numero 4
{
digitalWrite(7,LOW); //Apaga la luz stop
digitalWrite(11, HIGH);
digitalWrite(12, LOW);
digitalWrite(10, HIGH);
digitalWrite(9, LOW);
}
if (texto == "5") //Compara el contenido de la avariable "texto" con el numero 5
{
digitalWrite(7,HIGH); //Enciende la luz stop
digitalWrite(11, LOW);
digitalWrite(12, LOW);
digitalWrite(10, LOW);
digitalWrite(9, LOW);
}
if (texto == "6") //Compara el contenido de la avariable "texto" con el numero 6
{
if (flag==1)
{digitalWrite(8, LOW);
flag=0;
}
else if (flag==0)
{digitalWrite(8, HIGH);
flag=1;
}
}
texto = "";
}

```

# Answer
Next time, select your code and press ctrl-K... Also align your code (indent it well).

However, you don't need help actually as you have plenty of memory left. As as written:

* You only use 12% of program storage space. This might seem a lot having such a small sketch, but most of it is because of library usage/framework (such as the `digitalWrite` call(s).
* 210 bytes of dynamic memory is also not something to worry. Btw, this is unrelated to the sketch size, but to your use of (global and other) variables.

So unless you know beforehand your sketch will be much bigger, don't change it because of that reason (too less space).

However, there is another reason, to shorten the sketch, and that is because of duplicated code. As you can see, there is in the entire sketch a lot of repetition (or almost repetition), as in:

```
if (texto == "5") //Compara el contenido de la avariable "texto" con el numero 5
{
  digitalWrite(7,HIGH); //Enciende la luz stop
  digitalWrite(11, LOW);
  digitalWrite(12, LOW);
  digitalWrite(10, LOW);
  digitalWrite(9, LOW);
}

```

What you can do to improve it is:

* Either use a `switch` statement instead of the `if`/`else` statements
* Or create a function that incorporates this condition, together with the following item. This solution is in your case the most clear.

What you do is creating a new function:

```
void setPins(bool condition, int pin7, int pin11, int pin12, int pin10, int pin9)
{
  if (condition)
  {
    digitalWrite(7, pin7);
    digitalWrite(11, pin11);
    digitalWrite(12, pin12);
    digitalWrite(10, pin10);
    digitalWrite(9, pin9);
  }
}

```

And you call your function with:

```
setPins(texto == "5", HIGH, LOW, LOW, LOW, LOW);

```

And the same for all other conditions. I only used 5 as example.
> 1 votes

---
Tags: programming, arduino-nano, memory-usage, memory, sketch-size
---


# Question
Title: How to add calibration to a humidity contoller using UNO and DHT22 sensor?
I am using a setup that helps controlling humidity in an enclosure used to store a humidity sensitive product. My original posting is here.

I'm using a NANO and a DHT22 temperature/humidity sensor to acquire information on the actual condition in the enclosure; I am also using a 75% RH calibration kit to check the accuracy oh the humidity reading by the UNO and I found the value 9 percentage points higher than the kit's calibration value. Right now, until I find a solution to calibrate the unit, I have set my setpoint 9 points higher to compensate for the error. Any ideas on how to tackle this issue would be highly appreciated.

At the moment I can read the DHT sensor and show the humidity value on the LCD like this:

```
[...]
  int chk = DHT.read22(DHT22_PIN);
  lastcheck = millis();

  lcd.setCursor(0, 0);
  lcd.print("Humidity: ");
  lcd.setCursor(13, 0);
  lcd.print(DHT.humidity);
[...]

```

---

@Thomas\_Weller, I'm running tests with your calibration routine and other code changes; I'm using your arbitrary values for testing purposes only; the compensation algorithm works, as sampled below, however the LCD output is the actual DHT22 reading, not compensated. I am testing with a different sensor, whose output is 9% below the actual RH value. Here's a sample of the serial output:

```
DHT value: 58
Compensated to: 55
DHT value: 59
Compensated to: 56
DHT value: 60
Compensated to: 57
DHT value: 61
Compensated to: 58
DHT value: 62
Compensated to: 59
DHT value: 63
Compensated to: 60
DHT value: 64
Compensated to: 60

setpoint = 72
DHT read = 66.80%
displ + backlights off
humidifier ON, fan OFF
setpoint = 72
displ + backlights off
humidifier ON, fan OFF
setpoint = 72
displ + backlights off
humidifier ON, fan OFF
setpoint = 72
DHT read = 66.80%
displ + backlights off
humidifier ON, fan OFF
setpoint = 72
displ + backlights off
humidifier ON, fan OFF
setpoint = 72
displ + backlights off
humidifier ON, fan OFF

```

# Answer
To get better calibration, you need more calibration points. In the example below, I use 8 measurement points.

Given 8 humidity calibration bags for 20, 30, 40, 50, 60, 70, 75 and 80%.

```
int calvalues[] = {20, 30, 40, 50, 60, 70, 75, 80};

```

You would take several samples with the DHT sensor and build a table using the averages:

```
int dhtvalues[] = {15, 28, 39, 51, 63, 75, 84, 89};

```

As you can see, the DHT is below the real values in the lower range and above the real values in the upper range. But it could also be the opposite way.

You can then write this function:

```
#define COMPENSATION_POINTS 8

int compensate(int sensor_value)
{
  for(int index=1; index<COMPENSATION_POINTS; index++)
  {
    if (dhtvalues[index]>sensor_value)
    {
      int dhtLow = dhtvalues[index-1];
      int dhtHigh = dhtvalues[index];
      int calLow = calvalues[index-1];
      int calHigh = calvalues[index];

      return map(sensor_value, dhtLow, dhtHigh, calLow, calHigh);
    }
  }
}

```

which does linear interpolation for all the values that fall somewhere in between.

Here's some test code, which goes through the values in the expected range.

```
void setup() {
  Serial.begin(9600);
  for(int hum=15; hum<=89; hum++)
  {
    Serial.print("DHT value: ");
    Serial.println(hum);
    Serial.print("Compensated to: ");
    Serial.println(compensate(hum));
  }
}

void loop() {
  delay(1000);
}

```

Output:

```
DHT value: 15
Compensated to: 20
DHT value: 16
Compensated to: 20
DHT value: 17
Compensated to: 21
DHT value: 18
Compensated to: 22
...
DHT value: 87
Compensated to: 78
DHT value: 88
Compensated to: 79
DHT value: 89
Compensated to: 79

```

Applied to your case:

```
[...]
  int chk = DHT.read22(DHT22_PIN);
  lastcheck = millis();

  lcd.setCursor(0, 0);
  lcd.print("Humidity: ");
  lcd.setCursor(13, 0);
  int compensated = compensate(DHT.humidity);   // <- new line
  lcd.print(compensated);                       // <- changed line
[...]

```
> 5 votes

---
Tags: arduino-nano, dht22
---


title: Simultaneous Serial reading and writing

text:
# Question
Title: Simultaneous Serial reading and writing
I am trying to read long strings from the Serial, using arduino. In order to spare some RAM I don’t use Serial.readString(). I use Serial.read() instead.

During the reading, I also print some debug info to the same Serial port.

Let's say I send 90 characters to the Serial from the PC. I read them with Serial.read(). If I call a few times Serial.println() between two calls of Serial.read(), I get only 67 character of 90 (`Serial.available()>0` is false).

I read all the 90 character when I don’t call Serial.println() at all.

Why? I was sure that it is possible to write to the serial and read from it simultaneously, that these are independent processes.

Am I wrong?

# Answer
You can indeed simultaneously read and write through the serial port. At the hardware level, the serial port (the UART) is a transmitter and a receiver, which are almost independent. At the software level, they are both handled through interrupts that read from / write to a software buffer.

There is, however, a limitation you should be aware of: the software buffers are not large, typically 64 bytes on AVR-based boards. If you try to write too much too often, the output buffer will fill out, and then all subsequent writes become *blocking*, and run as slow as the serial port itself. If you receive lots of data and do not read it soon enough, the input buffer will overflow, and you loose some data.

From your description of your issue, it would seem you are hitting the limits of both buffers. You `Serial.println()` too much, too often. Then these write operations take too long and, in the meanwhile, you do not `Serial.read()`. Since your PC is not waiting for you to `Serial.read()`, your input buffer eventually overflows, and you only get slightly more than a buffer worth of characters.
> 2 votes

---
Tags: serial
---


# Question
Title: How to Read ADC value without Common GND ? (Possible or not !)
I want to Read external signal with the microcontroller.

**But** the problem is that **ADC does not work** because the signal GND and the microcontroller are not Common,

My question is, have you encountered such a problem? Is there a way to do it?

# Answer
> 0 votes
The solution is to always use at least 2 electrodes. You need 1 electrode, that you connect to ground. You can put this electrode to somewhere neutral (this instructable suggest connecting it to your leg, but I don't know, if that position is really good).

An ADC measures voltage and voltage is the difference in potential between 2 points, so to measure voltage you by definition need 2 points/connections.

---

Note: The voltages from the EEG electrodes are normally very low, so that they completely vanish in the noise. To really get something useful, you need to amplify the signal. I think there are many tutorials out there, that explain how to do this.

---
Tags: arduino-uno, analogread, arduino-micro, adc, digital-analog-conversion
---


# Question
Title: Is Arduino Mega useing one buffer or multiple buffers?
So Arduino Mega has Serial, Serial1, Serial2, Serial3.

However, does those Serial lines use the same buffer? or four independent ones? i.e. are they truly receive single independently, or actually some sort of software sharing? How will that affect the coding?

# Answer
Actually there are 2 buffers per Serial hardware interface: The hardware buffer, that is 1 byte (per direction of data transfer). The Serial library then transfers this byte in an extra buffer (64 bytes big) from an ISR. Every hardware Serial interface (`Serial` and `Serial1` to 3 on the Mega) has it's own hardware buffer.

Then the `Serial` library is implemented as a class. Every hardware Serial interface get's it's own instance of this class, including the 64 byte buffer.

So the hardware and the memory is completely seperated. The only thing, what they share, is the CPU time for servicing the interrupts, which is no problem, until you are doing somehting very wrong with interrupts.
> 2 votes

# Answer
Every instance of class HardwareSerial has own buffers. Here you can see it in source code. The instances are declared/definded at the end of the HardwareSerial.h/.cpp.
> 1 votes

---
Tags: uart, buffer
---


# Question
Title: Accessing softwareserial.available in the arduino loop function always return 0 but in the setup function returns the available byte
I am working on an accident detection system using arduino, what i want to do is to store the recipient phonenumber received as an SMS in the arduino EEPROM, using `Serial1.available()` to check for bytes in the software serial within the loop() function always return 0, but using it in the setup() function work fine, i have tried my best to debug but am not getting, where could i be getting it wrong. the entire code is bellow:

```
#include<SoftwareSerial.h>
#include <EEPROM.h>
SoftwareSerial Serial1(2, 3); //make RX arduino line is pin 2, make TX arduino line is pin 3.
SoftwareSerial gps(10, 11);
#include<LiquidCrystal.h>
LiquidCrystal lcd(4, 5, 6, 7, 8, 9);

#define x A1
#define y A2
#define z A3

int xsample = 0;
int ysample = 0;
int zsample = 0;

#define samples 10

#define minVal -50
#define MaxVal 50

int i = 0, k = 0;
int  gps_status = 0;
float latitude = 0;
float logitude = 0;
String Speed = "";
String phoneNumber = "";
String gpsString = "";
char *test = "$GNRMC";

void initModule(String cmd, char *res, int t)
{
  while (1)
  {
    Serial.println(cmd);
    Serial1.println(cmd);
    delay(100);
    while (Serial1.available() > 0)
    {
      if (Serial1.find(res))
      {
        Serial.println(res);
        delay(t);
        return;
      }

      else
      {
        Serial.println("Error");
      }
    }
    delay(t);
  }
}

void writeString(char add, String data)
{
  int _size = data.length();
  int i;
  for (i = 0; i < _size; i++)
  {
    EEPROM.write(add + i, data[i]);
  }
  EEPROM.write(add + _size, '\0'); //Add termination null character for String Data

}

String read_String(char add)
{
  int i;
  char data[100]; //Max 100 Bytes
  int len = 0;
  unsigned char k;
  k = EEPROM.read(add);
  while (k != '\0' && len < 500) //Read until null character
  {
    k = EEPROM.read(add + len);
    data[len] = k;
    len++;
  }
  data[len] = '\0';
  delay(2000);
  return String(data);
}

void receive_store_phoneNumber() {
  String msg = Serial1.readString();
  Serial.println(msg);
  phoneNumber = msg.substring((msg.indexOf("***")) + 3);
  writeString(10, phoneNumber);
  lcd.clear();
  lcd.print("Phone num stored");
  delay(2000);
}

void setup()
{
  Serial1.begin(9600);
  Serial.begin(9600);
  lcd.begin(16, 2);
  lcd.print("Accident Alert  ");
  lcd.setCursor(0, 1);
  lcd.print("     System     ");
  delay(2000);
  lcd.clear();
  lcd.print("Initializing");
  lcd.setCursor(0, 1);
  lcd.print("Please Wait...");
  delay(1000);

  Serial.println("Initializing....");
  initModule("AT", "OK", 1000);
  initModule("ATE1", "OK", 1000);
  initModule("AT+CPIN?", "READY", 1000);
  initModule("AT+CMGF=1", "OK", 1000);
  initModule("AT+CNMI=1,2,0,0,0", "OK", 1000);
  initModule("AT+CMGDA=\"DEL ALL\"", "OK", 1000);
  delay(200);
  Serial.println("Initialized Successfully");
  lcd.clear();
  lcd.print("Initialized");
  lcd.setCursor(0, 1);
  lcd.print("Successfully");
  delay(2000);
  lcd.clear();
  lcd.print("Callibrating ");
  lcd.setCursor(0, 1);
  lcd.print("Acceleromiter");
  for (int i = 0; i < samples; i++)
  {
    xsample += analogRead(x);
    ysample += analogRead(y);
    zsample += analogRead(z);
  }

  xsample /= samples;
  ysample /= samples;
  zsample /= samples;

  Serial.println(xsample);
  Serial.println(ysample);
  Serial.println(zsample);
  delay(1000);

  lcd.clear();
  lcd.print("Waiting For GPS");
  lcd.setCursor(0, 1);
  lcd.print("     Signal    ");
  delay(2000);
  gps.begin(9600);
  get_gps();
  show_coordinate();
  delay(2000);
  lcd.clear();
  lcd.print("GPS is Ready");
  delay(1000);
  //  writeString(10, "+2348132450841");
  lcd.clear();
  lcd.print("System Ready");
  Serial.println("System Ready..");

}

void loop()
{
  if (Serial1.available() > 0) {
    receive_store_phoneNumber();
  }

  int value1 = analogRead(x);
  int value2 = analogRead(y);
  int value3 = analogRead(z);

  int xValue = xsample - value1;
  int yValue = ysample - value2;
  int zValue = zsample - value3;

  Serial.print("x=");
  Serial.println(xValue);
  Serial.print("y=");
  Serial.println(yValue);
  Serial.print("z=");
  Serial.println(zValue);

  if (xValue < minVal || xValue > MaxVal  || yValue < minVal || yValue > MaxVal  || zValue < minVal || zValue > MaxVal)
  {
    get_gps();
    show_coordinate();
    lcd.clear();
    lcd.print("Sending SMS ");
    Serial.println("Sending SMS");
    delay(1000);
    lcd.clear();
    lcd.print(read_String(10));
    Send();
    Serial.println("SMS Sent");
    delay(2000);
    lcd.clear();
    lcd.print("System Ready");
  }
}

void gpsEvent()
{
  gpsString = "";
  while (1)
  {
    while (gps.available() > 0)          //Serial incoming data from GPS
    {
      char inChar = (char)gps.read();
      gpsString += inChar;                   //store incoming data from GPS to temparary string str[]
      i++;
      //     Serial.println("88888888888888888888888888888888888888888888");
      //     Serial.println(inChar);

      if (i < 7)
      {
        if (gpsString[i - 1] != test[i - 1])    //check for right string
        {
          i = 0;
          gpsString = "";
        }
      }
      if (inChar == '\r')
      {
        if (i > 60)
        {
          gps_status = 1;
          break;
        }
        else
        {
          i = 0;
        }
      }
    }
    if (gps_status)
      break;
  }
}

void get_gps()
{
  lcd.clear();
  lcd.print("Getting GPS Data");
  lcd.setCursor(0, 1);
  lcd.print("Please Wait.....");
  gps_status = 0;
  int x = 0;
  while (gps_status == 0)
  {
    gpsEvent();
    int str_lenth = i;
    coordinate2dec();
    i = 0; x = 0;
    str_lenth = 0;
  }
}

void show_coordinate()
{
  lcd.clear();
  lcd.print("Lat:");
  lcd.print(latitude);
  lcd.setCursor(0, 1);
  lcd.print("Log:");
  lcd.print(logitude);
  Serial.print("Latitude:");
  Serial.println(latitude);
  Serial.print("Longitude:");
  Serial.println(logitude);
  Serial.print("Speed(in knots)=");
  Serial.println(Speed);
  delay(2000);
  lcd.clear();
  lcd.print("Speed(Knots):");
  lcd.setCursor(0, 1);
  lcd.print(Speed);
}

void coordinate2dec()
{
  String lat_degree = "";
  for (i = 20; i <= 21; i++)
    lat_degree += gpsString[i];

  String lat_minut = "";
  for (i = 22; i <= 28; i++)
    lat_minut += gpsString[i];

  String log_degree = "";
  for (i = 32; i <= 34; i++)
    log_degree += gpsString[i];

  String log_minut = "";
  for (i = 35; i <= 41; i++)
    log_minut += gpsString[i];

  Speed = "";
  for (i = 45; i < 48; i++)   //extract longitude from string
    Speed += gpsString[i];

  float minut = lat_minut.toFloat();
  minut = minut / 60;
  float degree = lat_degree.toFloat();
  latitude = degree + minut;

  minut = log_minut.toFloat();
  minut = minut / 60;
  degree = log_degree.toFloat();
  logitude = degree + minut;
}

void Send()
{
  Serial1.println("AT");
  delay(500);
  serialPrint();
  Serial1.println("AT+CMGF=1");
  delay(500);
  serialPrint();
  Serial1.print("AT+CMGS=");
  Serial1.print('"');
  Serial1.print(read_String(10));    //mobile no. for SMS alert
  Serial1.println('"');
  delay(500);
  serialPrint();
  Serial1.print("Latitude:");
  Serial1.println(latitude);
  delay(500);
  serialPrint();
  Serial1.print(" longitude:");
  Serial1.println(logitude);
  delay(500);
  serialPrint();
  Serial1.print(" Speed:");
  Serial1.print(Speed);
  Serial1.println("Knots");
  delay(500);
  serialPrint();
  Serial1.print("http://maps.google.com/maps?&z=15&mrt=yp&t=k&q=");
  Serial1.print(latitude, 6);
  Serial1.print("+");              //28.612953, 77.231545   //28.612953,77.2293563
  Serial1.print(logitude, 6);
  Serial1.write(26);
  delay(2000);
  serialPrint();
}

void serialPrint()
{
  while (Serial1.available() > 0)
  {
    Serial.print(Serial1.read());
  }
}

```

# Answer
As Juraj stated in the comments, you have 2 instances of `SoftwareSerial`, but only one of them can listen to it's receive pin at the same time (this is because they rely on the same interrupts to sample the pin). When you call `gps.listen()`, you set the `gps` interface to listen on it's receive pin. `Serial1` (the second `SoftwareSerial` instance) will then no longer listen and thus will not receive anything. When you call `Serial1.listen()` it will be vice versa.

So you need to decide, on which interface you want to listen. For example you could try listening to the GPS all the time, and only switch to the other interface, if you want to send or receive an SMS (since the SIM module seems to be only controlled via AT commands, it will not send data spontaneously).

Or, as an alternative, you could switch to a bigger Arduino, which has more hardware serial interfaces, like the Arduino Mega. It has 4 hardware Serial interfaces and all of them are listening at the same time, since it is implemented in hardware, not in software.
> 1 votes

---
Tags: softwareserial
---


# Question
Title: HTTP Post data from Arduino uno using WiFi
Please help me to post data from arduino uno to a webpage using wifi(ESP-01) module. I try with AT commands it didn't give the response from my webpage

```

#include <SoftwareSerial.h>
#include <ArduinoJson.h>
#define DEBUG true

#define RX 10
#define TX 11
String WIFI_SSID = "*****";       // Your WiFi ssid
String PASSWORD = "*****";         // Password
//String DEVICE_SECRET_KEY  = "**";

//String PATH = "/v1/events";
//String PORT = "8000";
//String HOST = "http://10.**.***.66:8000/data";

String HOST = "10.**.240.**";
String PATH = "/data";
String PORT = "8000";

String response;
int countTrueCommand;
int countTimeCommand;
boolean found = false;

SoftwareSerial esp8266(RX, TX);
StaticJsonBuffer<200> jsonBuffer;
JsonObject& root = jsonBuffer.createObject();

void setup()
{
  Serial.begin(115200);
  esp8266.begin(115200);
  esp8266.println("AT");
  Serial.println(esp8266.read());
  sendCommandToESP8266("AT", 5, "OK");
   sendCommandToESP8266("AT+CWMODE=3", 5, "OK");
  sendCommandToESP8266("AT+CWJAP=\"" + WIFI_SSID + "\",\"" + PASSWORD + "\"", 20, "OK");
}

void loop()
{
  root["key"] =  "sdfsdfsd";
  String key;
  root.printTo(key);
  String postRequest =   "POST " + PATH  + " HTTP/1.1\r\n" +
                         "Host: " + HOST + "\r\n" +
                         "Accept: *" + "/" + "*\r\n" +
                         "Content-Length: " + key.length() + "\r\n" +
                         "Content-Type: application/json\r\n"
                         "\r\n" + key;
  Serial.print("pst:" + postRequest);
  sendCommandToESP8266("AT+CIPMUX=1", 5, "OK");
  sendCommandToESP8266("AT+CIPSTART=0,\"TCP\",\"" + HOST + "\"," + PORT, 15, "OK");
  String cipSend = "AT+CIPSEND=0," + String(postRequest.length());//GET /test.php?Data=2\r\nHost:192.168.1.13\r\n\r\n
  sendCommandToESP8266(cipSend, 4, ">");
  sendData(postRequest);

  while (esp8266.available())
  {
    if (esp8266.find("+IPD,"))
    {
//      String msg;
      esp8266.find("?");
//      msg = esp8266.readStringUntil(' ');
      response = esp8266.readStringUntil(' ');
      Serial.print(response);
      Serial.println();
    }
  }
  printResponse;

  //  sendCommandToESP8266("AT+CIPCLOSE=0", 5, "OK");
}

void sendCommandToESP8266(String command, int maxTime, char readReplay[]) {
  Serial.print(countTrueCommand);
  Serial.print(". at command => ");
  Serial.print(command);
  Serial.print(" ");
  while (countTimeCommand < (maxTime * 1))
  {
    esp8266.println(command);
    if (esp8266.find(readReplay))
    {
      found = true;
      break;
    }

    countTimeCommand++;
  }

  if (found == true)
  {
    Serial.println("Success");
    countTrueCommand++;
    countTimeCommand = 0;
  }

  if (found == false)
  {
    Serial.println("Fail");
    countTrueCommand = 0;
    countTimeCommand = 0;
  }

  found = false;
}

void sendData(String postRequest) {
  Serial.println(postRequest);
  Serial.println();
  esp8266.println(postRequest);
  delay(15000);
  countTrueCommand++;
}

void printResponse() {
  while (esp8266.available()) {
    Serial.println();
    Serial.println(esp8266.readStringUntil('\n'));
  }
}

```

Please help me to get the response from the webpage using this code.

# Answer
Step 1) Upload software serial from example and send AT, you should get reply as AT OK if your connections are correct. Step 2) Once your connections are correct and if you are uploading the given code then make sure you put your SSID, password, and Server IP which would be the three Strings: HOST, PATH and PORT.

You could alternatively check your server first by sending it a GET or POST using your browser or another software for testing API's(I personally use POSTMAN).

Proceed further once you perform these checks.
> 1 votes

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


# Question
Title: Upload already compiled code on Linux CLI without arduino-cli
I have a sketch for an Arduino Nano. I'm compiling it on my build server and get these 3 files:

* `project.bin.elf`
* `project.bin.hex`
* `project.bin.with_bootloader.hex`

Now I need to be able to upload/flash them onto the board (connected via a serial interface) without `arduino-cli`. Mainly because I can't install it via `apt-get` which means I'd have to start jumping through loops to be able to use it (stuff like keeping it up to date, installing, etc. on hundreds of devices).
So I was wondering if there are any tools in the debian repositories I can use to upload the compiled sketch and if so how.

I've been looking for a solution and came across several answers and topic but strangely enough all either use `arduino-cli`, other specialized tools or link to dead pages or pages that no longer contain the answer.

Examples:

# Answer
Use `avrdude`.

The command format is simple, assuming you have installed it from the Linux repositories:

```
avrdude -carduino -patmega328p -P/dev/ttyUSB0 -b115200 -Uflash:w:/path/to/project.bin.hex:i

```

Depending on what bootloader is installed in your nano you may need to change the baud rate (`-b115200`) to 57600. Also, of course, the USB device should be set to what your board actually identifies as.

The breakdown of the command is:

```
-c<programmer type>
-p<part name>
-P<port>
-b<baud rate>
-U<instruction>

```

The programmer type, part name and baud rate can all be gleaned from the `boards.txt` file in the AVR core files. For example, for the Nano:

```
nano.upload.protocol=arduino
nano.menu.cpu.atmega328.upload.speed=115200
nano.menu.cpu.atmega328.build.mcu=atmega328p

```

relate to -c -b and -p respectively. The instruction will always be the same, and means "Write to flash the following file in IHEX8 format". "flash" is the destination memory, "w" is the write command, and ":i" at the end defines the expected file format.

On a Linux computer with `avrdude` installed you can find much more information with `man avrdude`.
> 3 votes

---
Tags: arduino-nano, uploading, linux
---


title: Arduino Uno lag in simple loop

text:
# Question
Title: Arduino Uno lag in simple loop
I have a simple Arduino sketch which I have been playing with on my Uno.

The idea is simple, the user turns a potentiate (pin A2), when they pass a certain threshold a LED is turned on (pin 7).

Here is the code:

```
// Digital pins
const byte ledPin = 7;

// Analog pins
const byte userInputPotPin = A2;

// Potentiometer constants
const int userInputPotMinimumValue = 0;
const int userInputPotMaximumValue = 1023;
const int userInputMinimumValue = 1;
const int userInputMaximumValue = 100;

// Variables
const int threshold = 90;

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

    // Digital pins
    pinMode(ledPin, OUTPUT);

    // Analog pins
    pinMode(userInputPotPin, INPUT);
}

void loop()
{
    int rawValue = analogRead(userInputPotPin);
    int mappedValue = map(rawValue, userInputPotMinimumValue, userInputPotMaximumValue, userInputMinimumValue, userInputMaximumValue);

    String messageText;
    messageText += "Raw:   " + String(rawValue) + "\t";
    messageText += "Mapped:" + String(mappedValue);

    if(mappedValue > threshold)
    {
        messageText += "\tThreshold exceeded!";
        digitalWrite(ledPin, HIGH);
    }
    else
    {
        digitalWrite(ledPin, LOW);
    }

    Serial.println(messageText);

    delay(100);
}

```

The problem is that when it is run the hardware is very unresponsive - I can turn the pot, but I don't see the light change for several minutes. The log messages in the serial monitor also seem to be lagging behind.

I have tried:
* Removing the Serial statements (so there is no serial communication when the sketch is running), and just observing the LED. This makes no difference.
* Increasing the value in the delay up to 1000. This makes no difference in the responsiveness.

However, when I run the sketch on my Mega2560 the problem goes away and the circuit is as responsive as I expect.

Is there something wrong with my Uno board?

# Answer
It turns out the problem was the A2 pin on the board.

When I used the A0 pin (or a different board) the problem goes away.

I realised something was wrong when I noticed the values from the pot were strange (I expected values in the range 0 - 1023, but was receiving values from 170-250 ish).
> 3 votes

# Answer
The String+ operator is very expensive. High likely what it does is:

* Create a new block of memory to accommodate the old string content and the to-be-concatenated text.
* Copy the current String to a new string location
* Concatenate the string
* Free the old memory

Besides creating memory gaps which can be disastrous for the just 2 KB SRAM of the Arduino Uno, it takes a lot of time.

Some tips:

* Do not use Strings
* Do not concatenate strings if not needed
* To save more time, use short strings instead

If you really need to debug a time critical part, copy numbers you want to print to an array, and AFTER you do all 'real' code, start printing the numbers.
> 2 votes

---
Tags: arduino-uno, potentiometer, atmega2560
---


# Question
Title: Is there any DS2482 I2C to 1-Wire bridge functional library?
Please let me know if you know any good library for DS2482 I2C to 1-Wire bridge. I tried to use the DS2482\_OneWire library but I got errors when trying to run the library examples (**Read\_temp\_sensors** and **Scan\_1Wire\_Bus**):

Error for Read\_temp\_sensors:

> Read\_temp\_sensors:2:10: fatal error: DallasTemperature.h: No such file or directory

Error for Scan\_1Wire\_Bus:

> Scan\_1Wire\_Bus
> C:\Users\myuser\Documents\Arduino\libraries\DS2482\_OneWire-master\OneWire.cpp: In member function 'uint8\_t OneWire::waitOnBusy()':
> C:\Users\myuser\Documents\Arduino\libraries\DS2482\_OneWire-master\OneWire.cpp:121:3: error: 'delayMicroseconds' was not declared in this scope
> delayMicroseconds(20);
> ^~~~~~~~~~~~~~~~~
> exit status 1 Error compiling for board Arduino Nano.\**

Thank you.

# Answer
I guess to solve the first error, you also need this library, which contains the DallasTemperature.h file. The file get's included, but is not contained in the DS2482 library. Unfortunately there is no clue for that in the readme of the library. The author didn't commit anything since 2014, so the development of the library can be considered dead from that side. Though some people have forked the library to make little changes.

And the solution to the second error is described in this issue of the DS2482 library (just adding an include of "Arduino.h" in the OneWire.cpp file).
> 0 votes

---
Tags: i2c, 1-wire
---


# Question
Title: Error compiling for Arduino Nano 33 BLE with LiquidCrystal library
I recently started coding in the Arduino IDE for the Arduino Nano 33 BLE I bought. When I choose the Nano 33 BLE as my board, I get the following Error:

```
Arduino: 1.8.11 (Windows 10), Board: "Arduino Nano 33 BLE"

In file included from C:\Users\Niels\Documents\Arduino\libraries\LiquidCrystal\src\LiquidCrystal.cpp:1:0:

C:\Users\Niels\Documents\Arduino\libraries\LiquidCrystal\src\LiquidCrystal.h:45:36: error: expected class-name before '{' token

 class LiquidCrystal : public Print {

                                    ^

C:\Users\Niels\Documents\Arduino\libraries\LiquidCrystal\src\LiquidCrystal.h:86:9: error: 'Print' has not been declared

   using Print::write;

         ^~~~~

exit status 1
Error compiling for board Arduino Nano 33 BLE.

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

```

I do not get this error when compiling for a normal Arduino nano board. This is my code:

```
#include <Arduino_LSM9DS1.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(12,11,5,4,3,2);

//pins:
const int measurePin = 13, calibratePin = 14, xHighPin = 15, xLowPin = 16, yHighPin = 17, yLowPin = 18;

//constants:
const int interval = 10;
const float delta = 10;

//variables:
boolean measureSts = LOW, calibrateSts = LOW, xyOK = true;
int count = 0, timer = 0;
float measurements[100], current, x, y, z, xZero, yZero, zZero;

//programm:
void setup() {
  lcd.begin(16,2);

  pinMode(measurePin, INPUT);
  pinMode(calibratePin, INPUT);
  pinMode(xHighPin, OUTPUT);
  pinMode(xLowPin, OUTPUT);
  pinMode(yHighPin, OUTPUT);
  pinMode(yLowPin, OUTPUT);
}

void loop() {
  if ( IMU.accelerationAvailable() ) {
    IMU.readAcceleration(x, y, z);
    calibrate();
    checkXY();
    measure();
    current = z - zZero;
    printValues();
  }
  else lcd.print("--geen  sensor--");
}

void checkXY() {
  xyOK = true;
  if ( x < xZero - delta ) {
    xyOK = false;
    digitalWrite(xLowPin, HIGH);
    digitalWrite(xHighPin, LOW);
  }
  else if ( x > xZero + delta ) {
    xyOK = false;
    digitalWrite(xLowPin, LOW);
    digitalWrite(xHighPin, HIGH);
  }
  if ( y < yZero - delta ) {
    xyOK = false;
    digitalWrite(yLowPin, HIGH);
    digitalWrite(yHighPin, LOW);
  }
  else if ( y > yZero + delta ) {
    xyOK = false;
    digitalWrite(yLowPin, LOW);
    digitalWrite(yHighPin, HIGH);
  }
}

void measure(){
  if ( digitalRead(measurePin) == LOW && measureSts == HIGH && xyOK ) {
    measurements[count] = z - zZero;
    zZero = z;
    timer = interval;
    count++;
  }
  measureSts = digitalRead(measurePin);
}

void printValues() {
  if ( timer >= interval ) {
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Meting: " + String(measurements[count]) + (char)223);
    lcd.setCursor(0,1);
    lcd.print("Huidig: " + String(current) + (char)223);
    timer = 0;
  }
  timer++;
}

void calibrate() {
  if ( digitalRead(calibratePin) == LOW && calibrateSts == true ) {
    xZero = x;
    yZero = y;
    lcd.setCursor(0,3);
    lcd.print("kalibreren");
    lcd.setCursor(1,4);
    lcd.print("voltooid");
    digitalWrite(xHighPin, HIGH);
    digitalWrite(xLowPin, HIGH);
    digitalWrite(yHighPin, HIGH);
    digitalWrite(yLowPin, HIGH);
    delay(100);
    lcd.clear();
    digitalWrite(xHighPin, LOW);
    digitalWrite(xLowPin, LOW);
    digitalWrite(yHighPin, LOW);
    digitalWrite(yLowPin, LOW);
  }
  calibrateSts = digitalRead(calibratePin);
}

```

For context: I am trying to create an angle-measuring device using the built-in accelerometer and a 2x16 LCD.

I hope someone can help me fixing this. Thanks in advance.

-Niels

# Answer
The Arduino core for Nano 33 BLE is based on Mbed and can be used in Mbed as library. To achieve this, the Arduino API classes in this core are put in a namespace `arduino::`. This causes problems for libraries which include individual includes of Arduino API historically copied into cores for different MCU architecture platforms. The Arduino.h file includes the API files in the right way so in this case replacing `#include"Print.h"` with `#include <Arduino.h>` in LiquidCrystal.h solves the compilation problem.
> 2 votes

---
Tags: arduino-nano, lcd, library
---


# Question
Title: Different ways (and the fastest) to compute sines (and cosines) in Arduino
I am using an Arduino Uno board to compute the angles of my system (robotic arm). The angles are actually 10 bit values (0 to 1023) from the ADC, using the full range of the ADC. I am only going to be operating in the 1st quadrant (0 to 90 deg), where both sines and cosines are positive, so there is no problem with negative numbers. My doubts can be expressed in 3 questions:

1. What are the different ways to compute these trigonometric functions on Arduino?
2. What is the fastest way to do the same?
3. There are the sin() and cos() functions in the Arduino IDE, but how does the Arduino actually calculate them (as in do they use look-up tables, or approximations etc.)? They seem like an obvious solution, but I would like to know their actual implementation before I try them out.

PS: I am open to both standard coding on the Arduino IDE and assembly coding, as well as any other options not mentioned. Also I have no problems with errors and approximations, which are inevitable for a digital system; however if possible it would be good to mention the extent of possible errors

# Answer
> 11 votes
The two basic methods are mathematical calculation (with polynomials) and lookup tables.

The Arduino's math library (libm, part of avr-libc) uses the former. It is optimised for the AVR in that it is written with 100% assembly language, and as such is almost impossible to follow what it's doing (there's zero comments as well). Rest assured though it will be the most optimised pure-float implementation brains far superior to ours could come up with.

However the key there is *float*. Anything on the Arduino involving floating point is going to be heavyweight by comparison to pure integer, and since you are only requesting integers between 0 and 90 degrees a simple lookup table is by far the simplest and most efficient method.

A table of 91 values will give you everything from 0 to 90 inclusive. However if you make that a table of floating point values between 0.0 and 1.0 you still then have the inefficiency of working with floats (granted not as inefficient as calculating `sin` with floats), so storing a fixed point value instead would be far more efficient.

That may be as simple as storing the value multiplied by 1000, so you have between 0 and 1000 instead of between 0.0 and 1.0 (for instance sin(30) would be stored as 500 instead of 0.5). More efficient would be to store the values as, for instance, a Q16 value where each value (bit) represents 1/65536th of 1.0. These Q16 values (and the related Q15, Q1.15, etc) are more efficient to work with since you have powers-of-two which computers love to work with instead of powers-of-ten which they hate working with.

Don't forget as well that the `sin()` function expects radians, so you first have to convert your integer degrees into a floating point radians value, making the use of `sin()` even more inefficient compared to a lookup table that can work directly with the integer degrees value.

A combination of the two scenarios, though, is possible. *Linear interpolation* will allow you to get an approximation of a floating point angle between two integers. It's as simple as working out how far between two points in the lookup table you are and creating a weighted average based on that distance of the two values. For instance if you are at 23.6 degrees you take `(sintable[23] * (1-0.6)) + (sintable[24] * 0.6)`. Basically your sine wave becomes a series of discrete points joined together by straight lines. You trade accuracy for speed.

# Answer
> 8 votes
There are some good answers here but I wanted to add a method which hasn't been mentioned yet, one very well suited to computing trigonometric functions on embedded systems, and that's the CORDIC technique Wiki Entry Here It can compute trig functions using only shifts and adds and a small look-up table.

Here's a crude example in C. In effect, it implements the C libraries' atan2() function using CORDIC (i.e. find an angle given two orthogonal components.) It uses floating point, but can be adapted for use with fixed-point arithmetic.

```
/*
 * Simple example of using the CORDIC algorithm.
 */

#include <stdio.h>
#include <math.h>

#define CORDIC_TABLE_SIZE  16

double cordic_table[CORDIC_TABLE_SIZE];

void init_table(void);
double angle(double I, double Q);

/*
 * Given a sine and cosine component of an
 * angle, compute the angle using the CORIDC
 * algoritm.
 */
double angle(double I, double Q)
{
    int L;
    double K = 1;
    double angle_acc = 0;
    double tmp_I;

    if (I < 0) {
        /* rotate by an initial +/- 90 degrees */
        tmp_I = I;
        if (Q > 0.0) {
            I = Q;           /* subtract 90 degrees */
            Q = -tmp_I;
            angle_acc = -90;
        } else {
            I = -Q;          /* add 90 degrees */
            Q = tmp_I;
            angle_acc = 90;
        }
    } else {
        angle_acc = 0;
    }

    /* rotate using "1 + jK" factors */
    for (L = 0, K = 1; L <= CORDIC_TABLE_SIZE; L++) {
        tmp_I = I;
        if (Q >= 0.0) {
            /* angle is positive: do negative roation */
            I += Q * K;
            Q -= tmp_I * K;
            angle_acc -= cordic_table[L];
        } else {
            /* angle is negative: do positive rotation */
            I -= Q * K;
            Q += tmp_I * K;
            angle_acc += cordic_table[L];
        }
        K /= 2.0;
    }
    return -angle_acc;
}

void init_table(void)
{
    int i;
    double K = 1;

    for (i = 0; i < CORDIC_TABLE_SIZE; i++) {
        cordic_table[i] = 180 * atan(K) / M_PI;
        K /= 2.0;
    }
}
int main(int argc, char **argv)
{
    double I, Q, A, Ar, R, Ac;

    init_table();

    printf("# Angle,    CORDIC Angle,  Error\n");
    for (A = 0; A < 90.0; A += 0.5) {

        Ar = A * M_PI / 180; /* convert to radians for C's sin & cos fn's */

        R = 5;  // Arbitrary radius

        I = R * cos(Ar);
        Q = R * sin(Ar);

        Ac = angle(I, Q);
        printf("%9f, %9f,   %12.4e\n", A, Ac, Ac-A);
    }
    return 0;
}

```

But try the native Arduino trig functions first - they might be fast enough anyway.

# Answer
> 6 votes
I have been playing a bit with computing sines and cosines on the Arduino using fixed-point polynomial approximations. Here are my measurements of average execution time and worst case error, compared with the standard `cos()` and `sin()` from avr-libc:

```
function    max error   cycles   time
-----------------------------------------
cos_fix()   9.53e-5     108.25    6.77 µs
sin_fix()   9.53e-5     110.25    6.89 µs
cos()       2.98e-8     1720.8   107.5 µs
sin()       2.98e-8     1725.1   107.8 µs

```

It's based on a 6th degree polynomial computed with only 4 multiplications. The multiplications themselves are done in assembly, as I found that gcc implemented them inefficiently. The angles are expressed as `uint16_t` in units of 1/65536 of a revolution, which makes the arithmetic of angles naturally work modulo one revolution.

If you think this can suit your bill, here is the code: Fixed-point trigonometry. Sorry, I still did not translate this page, which is in French, but you can understand the equations, and the code (variable names, comments...) is in English.

---

**Edit**: Since the server seems to have vanished, here is some info on the approximations I found.

I wanted to write angles in binary fixed-point, in units of quadrants (or, equivalently, in turns). And I also wanted to use an even polynomial, as these are more efficient to compute than arbitrary polynomials. In other words, I wanted a polynomial P() such that

cos(π/2 x) ≈ P(x2) for x ∈ \[0,1\]

I also required the approximation to be exact at both ends of the interval, to ensure that cos(0) = 1 and cos(π/2) = 0. These constraints led to the form

P(u) = (1 − u)(1 + uQ(u))

where Q() is an arbitrary polynomial.

Next, I searched for the best solution as a function of the degree of Q() and found this:

```
        Q(u)             │ degree of P(x²) │ max error
─────────────────────────┼─────────────────┼──────────
          0              │         2       │  5.60e-2
       −0.224            │         4       │  9.20e-4
−0.2335216 + 0.0190963 u │         6       │  9.20e-6

```

The choice among the solutions above is a speed/accuracy trade-off. The third solution gives more accuracy than achievable with 16-bits, and it's the one I chose for the 16-bit implementation.

# Answer
> 4 votes
You could create a couple of functions that uses linear approximation to determine the sin() and cos() of a particular angle.

I am thinking something like this:
For each I have broken the graphical representation of sin() and cos() into 3 sections and have done a linear approximation of that section.

Your function would ideally first check that the range of the angel is between 0 and 90.
Then it would use an `ifelse` statement to determine what of the 3 sections it belongs and then does the corresponding linear calculation (ie `output = mX + c`)

# Answer
> 4 votes
I looked for other people that had approximated cos() and sin() and I came across this answer:

dtb's answer to "Fast Sin/Cos using a pre computed translation array"

Basically he computed that the math.sin() function from the math library was faster than using a look-up table of values. But from what I can tell, this was computed on a PC.

Arduino has a math library included that can calculate sin() and cos().

# Answer
> 3 votes
A lookup table will be the fastest way to find sines. And if you're comfortable computing with fixed-point numbers (integers whose binary-point is somewhere other than to the right of bit-0), your further calculations with the sines will be much faster as well. That table can then be a table of words, possibly in Flash to save RAM space. Note that in your math you may need to use longs for large intermediate results.

# Answer
> 3 votes
Just for the fun of it, and to prove it can be done, I finished an AVR assembly routine to calculate sin(x) results in 24 bits (3 bytes) with one bit of error. The input angle is in degrees with one decimal digit, from 000 to 900 (0~90.0) for the first quadrant only. It uses less than 210 AVR instructions and runs on average of 212 microseconds, varying from 211us (angle=001) to 213us (angle=899).

It took several days to do it all, more than 10 days (free hours) just thinking about the best algorithm for the calculation, considering the AVR microcontroller, no floating point, eliminating all possible divisions. What took more time was to make the right step-up values for integers, to have good precision it needs to step-up values of 1e-8 to binary integers 2^28 or more. Once all the errors culprits of precision and rounding up were found, increased their calculation resolution by extra 2^8 or 2^16, the best results were met. I first simulated all the calculations on Excel taking care of having all values as Int(x) or Round(x,0) to represent exactly the AVR core processing.

For example, in the algorithm the angle must be in Radians, the input is in Degrees to facilitate for the user. To convert Degrees to Radians the trivial formula is rad=degrees\*PI/180, it seems nice and easy, but it is not, PI is an infinite number - if using few digits it will create errors at the output, division by 180 requires AVR bit manipulation since it has no division instruction, and more than that, the result would require floating point since involves numbers far below integer 1. For example, Radian of 1° (degree) is 0.017453293. Since PI and 180 are constants, why not reverse this thing for simple multiplication? PI/180 = 0.017453293, multiply it by 2^32 and it results as a constant 74961320 (0x0477D1A8), multiply this number by your angle in degrees, lets say 900 for 90° and shift it 4 bits right (÷16) to obtain 4216574250 (0xFB53D12A), that is the radians of the 90° with 2^28 expansion, fit in 4 bytes, without a single division (except the 4 bit shift right). In a way, the error included in such trick is smaller than 2^-27.

So, all further calculations need to remember it is 2^28 higher and taken care of it. You need to divide the on-the-go results by 16, 256 or even 65536 just to avoid it use unnecessary growing hunger bytes that would not help resolution. That was a painstaking job, just finding the minimum quantity of bits in each calculation results, keeping the results precision around 24 bits. Each one of the several calculations where done in try/error with higher or lower bits count in the Excel flow, watching the overall quantity of error bits at the result in a graph showing 0-90° with a macro running the code 900 times, once per tenth of a degree. That "visual" Excel approach was a tool I created, helped a lot to find the best solution for every single part of the code.

For example, rounding up this particular calculation result 13248737.51 to 13248738 or just lose the "0.51" decimals, how much it will affect the final result precision for all the 900 input angles (00.1 ~ 90.0) tests?

I was able to keep the animal contained within 32 bits (4 bytes) on every calculation, and ended up with the magic to obtain precision within 23 bits of the result. When checking the whole 3 bytes of the result, the error is ±1 LSB, outstanding.

The user may grab one, two or three bytes from the result for its own requirements of precision. Of course, if just one byte is enough I would recommend to use a single 256 bytes sin table and use AVR 'LPM' instruction to grab it.

Once I had the Excel sequence running smooth and neat, the final translation from Excel to AVR assembly took less than 2 hours, as usual you should think more first, work less later.

At that time I was able to squeeze yet more and reduce registers usage. The actual (not final) code uses around 205 instructions (~410 bytes), runs a sin(x) calculation in average of 212us, clock at 16MHz. At that speed it can calculate 4700+ sin(x) per second. Not being important, but it can run a precise sinewave up to 4700Hz with 23 bits of precision and resolution, without any lookup tables.

The base algorithm is based on Taylor series for sin(x), but modified a lot to fit my intentions with the AVR microcontroller and precision in mind.

Even that using a 2700 bytes table (900 entries * 3 bytes) would be speed attractive, what is the fun or learning experience on that? Of course, CORDIC approach was also considered, maybe later, the point here is to squeeze Taylor into the AVR core and take water from a dry rock.

I wonder if Arduino "sin(78.9°)" can run Processing (C++) with 23 bits of precision in less than 212us and the necessary code smaller than 205 instructions. May be if C++ uses CORDIC. Arduino sketches can import assembly code.

Makes no sense to post the code here, later I will edit this post to include a weblink to it, possibly on my blog at this url. The blog is mostly in portuguese.

This hobby-no-money venture was interesting, pushing the limits of the AVR engine of almost 16MIPS at 16MHz, without division instruction, multiplication only in 8x8 bits. It allows to calculate sin(x), cos(x) \[=sin(900-x)\] and tan(x) \[=sin(x)/sin(900-x)\].

Above it all, this helped to keep my 63 years old brain polished and oiled. When teenagers say the 'old people' know sh\*nothing about technology, I answer "think again, who do you think created the bases for everything you enjoy today?".

Cheers

# Answer
> 2 votes
I had a simillar question to OP. I wanted to make a LUT table to calculate the first quadrant of the sine function as unsigned 16 bit integers starting from 0x8000 to 0xffff. And i ended up writing this for fun and profit. Note: This would work more efficiently if i used 'if' statements. Also it's not very accurate, but would be accurate enough for a sine wave in a sound synthesiser

```
void sin_lut_ctor(){

//Make a Look Up Table for 511 terms of the sine function.
//Plugin in some polynomials to do some magic
//and you get an aproximation for sines up to π/2.
//

//All sines yonder π/2 can be derived with math

const uint16_t uLut_d = 0x0200; //maximum LUT depth for π/2 terms.
uint16_t uLut_0[uLut_d];        //The LUT itself.
//Put the 2 above before your void setup() as global variables.
//This coefficients will only work for uLut_d = 511.

uint16_t arna_poly_0 = 0x000a; // 11
uint16_t arna_poly_1 = 0x0001; // 1
uint16_t arna_poly_2 = 0x0007; // 7
uint16_t arna_poly_3 = 0x0001; // 1   Precalculated Polynomials
uint16_t arna_poly_4 = 0x0001; // 1
uint16_t arna_poly_5 = 0x0007; // 7
uint16_t arna_poly_6 = 0x0002; // 2
uint16_t arna_poly_7 = 0x0001; // 1

uint16_t Imm_UI_0 = 0x0001;              //  Itterator
uint16_t Imm_UI_1 = 0x007c;              //  An incrementor that decreases in time

uint16_t Imm_UI_2 = 0x0000;              //
uint16_t Imm_UI_3 = 0x0000;              //
uint16_t Imm_UI_4 = 0x0000;              //
uint16_t Imm_UI_5 = 0x0000;              //
uint16_t Imm_UI_6 = 0x0000;              //  Temporary variables
uint16_t Imm_UI_7 = 0x0000;              //
uint16_t Imm_UI_8 = 0x0000;              //
uint16_t Imm_UI_9 = 0x0000;              //
uint16_t Imm_UI_A = 0x0000;
uint16_t Imm_UI_B = 0x0000;

uint16_t Imm_UI_A = uLut_d - 0x0001;     //  510

uLut_0[0x0000] = 0x8000;        //Assume that the middle point is 32768 (0x8000 hex)
while (Imm_UI_0 < Imm_UI_A) //Construct a quarter of the sine table
  {
Imm_UI_2++;                                   //Increase temporary variable by 1

Imm_UI_B = Imm_UI_2 / arna_coeff_0;           //Divide it with the first coefficient (note: integer division)
Imm_UI_3 += Imm_UI_B;                         //Increase the next temporary value if the first one has increased up to the 1st coefficient
Imm_UI_1 -= Imm_UI_B;                         //Decrease the incrementor if this is the case
Imm_UI_2 *= 0x001 - Imm_UI_B;                 //Set the first temporary variable back to 0

Imm_UI_B = Imm_UI_3 / arna_poly_1;           //Do the same thing as before with the next set of temporary variables
Imm_UI_4 += Imm_UI_B;
Imm_UI_1 -= Imm_UI_B;
Imm_UI_3 *= 0x0001 - Imm_UI_B;

Imm_UI_B = Imm_UI_4 / arna_poly_2;           //And again... and again... you get the idea.
Imm_UI_5 += Imm_UI_B;
Imm_UI_1 -= Imm_UI_B;
Imm_UI_4 *= 0x0001 - Imm_UI_B;

Imm_UI_B = Imm_UI_5 / arna_poly_3;
Imm_UI_6 += Imm_UI_B;
Imm_UI_1 -= Imm_UI_B;
Imm_UI_5 *= 0x0001 - Imm_UI_B;

Imm_UI_B = Imm_UI_6 / arna_poly_4;
Imm_UI_7 += Imm_UI_B;
Imm_UI_1 -= Imm_UI_B;
Imm_UI_6 *= 0x0001 - Imm_UI_B;

Imm_UI_B = Imm_UI_7 / arna_poly_5;
Imm_UI_8 += Imm_UI_B;
Imm_UI_1 -= Imm_UI_B;
Imm_UI_7 *= 0x0001 - Imm_UI_B;

Imm_UI_B = Imm_UI_8 / arna_poly_6;
Imm_UI_9 += Imm_UI_B;
Imm_UI_1 -= Imm_UI_B;
Imm_UI_8 *= 0x0001 - Imm_UI_B;

Imm_UI_B = Imm_UI_9 / arna_poly_7          //the last set won't need to increment a next variable so skip the step where you would increase it.
Imm_UI_1 -= Imm_UI_B;
Imm_UI_9 *= 1 - Imm_UI_B;

uLut_0[Imm_UI_0] = (uLut_0[Imm_UI_0 - 0x0001] + Imm_UI_1); //Set the current value as the previous one increased by our incrementor
Imm_UI_0++;              //Increase the itterator
  }
  uLut_0[Imm_UI_A] = 0xffff; //Lastly, set the last value to 0xffff

  //And there you have it. A sine table with only one if statement (a while loop)
}

```

Now to get back the values, use this function.It accepts a value from 0x0000 to 0x0800 and returns the appropriate value from the LUT

```
uint16_t lu_sin(uint16_t lu_val0)
{
  //Get a value from 0x0000 to 0x0800. Return an appropriate sin(value)
  Imm_UI_0 = lu_val0/0x0200; //determine quadrant
  Imm_UI_1 = lu_val0%0x0200; //Get which value
  if (Imm_UI_0 == 0x0000)
  {
    return uLut_0[Imm_UI_1];
  }
  if (Imm_UI_0 == 0x0001)
  {
    return uLut_0[0x01ff - Imm_UI_1];
  }
  if (Imm_UI_0 == 0x0002)
  {
    return 0xffff - uLut_0[Imm_UI_1];
  }
  if (Imm_UI_0 == 0x0003)
  {
    return 0xffff - uLut_0[0x01ff - Imm_UI_1];
  }
}// I'm using if statements here but similarly to the above code block,
 //you can do without. just with integer divisions and modulos

```

Remember, this is not the most efficient approach to this task, i just couldn't figure out how to make taylor series to give out results in the appropriate range.

# Answer
> 2 votes
As others have mentioned lookup tables are the way to go if you want speed. I've recently been investigating computation of trig functions on an ATtiny85 for use of fast vector averages (wind in my case). There's always trade off's...for me I only needed 1 deg angular resolution so a lookup table of 360 int's (scaling -32767 to 32767, only working with int's) was the best way to go. Retrieving the sine is just a matter of supplying an index 0-359...so very fast! Some numbers from my tests:

FLASH lookup time (us): 0.99 (table stored using PROGMEM)

RAM lookup time (us): 0.69 (table in RAM)

Lib time (us): 122.31 (Using Arduino Lib)

Note these are averages across a 360 point sample for each. Testing was done on a nano.

# Answer
> 1 votes
generally, look-up table \> approximation -\> calculation. ram \> flash. integer \> fixed point \> floating point. pre-calclation \> real time calculation. mirroring (sine to cosine or cosine to sine) vs. actual calculation / look-up....

each has its pluses and minuses.

you can make all sorts of combinations to see which works best for your application.

edit: I did a quick checking. using 8-bit integer output, calculating 1024 sin values with look-up table takes 0.6ms, and 133ms with floaters, or 200x slower.

---
Tags: arduino-uno, arduino-ide, assembly, mathematics
---


# Question
Title: LCD screen stops displaying after DC motor starts
LCD screen stops displaying after DC motor starts I have 3 main components: LCD, thermal resistor, and a DC motor running a fan. The LCD displays the temperature reading from the thermal resistor and then after it hits a certain temperature the motor turns on.

A few seconds after the motor has been turned on the LCD will go blank (but still powered on). I tried connecting a 100uF electrolytic capacitor across between the logic supply pins on the LCD and a 0.47 µF ceramic between the motor terminals.

I did this because i'm assuming since the motor in operation (its commutator) produces voltage/ current "spikes" they can be coupled back through the common power supply. This could provide some immunity against them actually getting to the display driver and interfering with its operation.

What I did kind of helped, but I feel like I am missing something. Any suggestions?

(the link is to the picture of my circuit I quickly made online)

# Answer
> 3 votes
A brush DC electric motor and many other similar devices will produce random noise as well as uneven power demands and should be powered independently of logic circuits such as processors and LCDs. It is very difficult to mediate noise sources and almost always better to remove them from where they are causing harm or unexpected results.

It is also important to power a project with a supply capable of providing more than the expected amperage during highest demand. Many will calculate the highest amperage demand and select a power supply which is rated at double the amperage.

If you are using batteries, note that a 9 volt battery (which usually contains 6 cells) on average supplies about 500mAh. Not much and likely not enough to run a motor with out momentarily dropping the voltage. Where as a D-size battery supplies about 15000mAh. Different battery chemistries change the mAh rating drastically. 500mAh and 15000mAh are about what one may expect from Alkaline batteries.

If using a USB power source, note that older USB ports are only obliged to supply 500mA at any given time. If this current limit is exceeded, the voltage may drop under 5 volts.

There are many designs on the internet where the motor is powered from the Arduino. This may be possible for smaller motors however you are having unexpected behavior. Consider using one or more of the following suggestions to mitigate your problems:

1. Avoid low mAh batteries such as common 9 volt batteries. Instead use a battery that can provide higher mAh like D Size cells.
2. Avoid powering noisy or current demanding devices directly from the Arduino. Consider an independent power supply and use a common ground.
3. It may be possible to use a single power supply with good results if the power supply is rated at higher amperage than the peak total maximum amperage.

---
Tags: arduino-uno, lcd
---


# Question
Title: i want to make Node Mcu a bride for other devices but its self connected with home wifi not providing internet to others
i there! i have Node Mcu which i want to connected with my home wifi after it it made it own station mode then i want to make it access point for other but now problem is that it is now in both mode mean (AP+Station ). when i want to connect any other phone or Pc it connected successfully but not providing internet to other devices. Question?

1. is problem in wifi configuration of acess point?
2. which ip,gate way and subnet mask i would assign to the access point?

# Answer
> 1 votes
The NodeMCU under the Arduino framework cannot do what you want. There are basically three methods for what you want:

1. Configure the IP stack to enable routing - not possible in Arduino, and also requires configuration of your upstream router to work.
2. Configure the IP stack to enable routing and Network Address Translation - not possible in Arduino, and I am not sure if the stack even supports NAT.
3. Write a sketch to act as a proxy server - only works for certain types of traffic (HTTP) and requires a lot of coding. May be possible, but not an easy task.

1) and 2) certainly can't be don in Arduino. There are rumours on the internet that it is possible to configure and compile your own lwIP stack version with routing enabled, but that is so far outside the scope of this website.

Option 3 is the more realistic, but certainly not something even I would consider doing. Creating a sketch that works like squid, for example, would be a mammoth task, and may even hit the limitations of the ESP8266.

It would be more beneficial to perhaps get an old wireless router that is supported by OpenWRT and learn how to hack that to act as you want.

---
Tags: esp8266, nodemcu
---


# Question
Title: AutoConnect module does not broadcast SSID on ESP32 Dev Board
This is my first post so I apologize if I'm missing all required info about my Arduino setup. I'm a little new to this type of development.

Arduino 1.8.9

ESP32 Dev Module on /dev/cu.SLAB\_USBtoUART

Mac OSX High Sierra 10.13.

I'm using the AutoConnect by Hieromon Ikasama v1.1.3 library to create an access point (AP), but the SSID (network name) is not being broadcasted even with the simplest code example.

Why isn't "ESP-78e9" showing up in my network list on my MAC or iPhone?

```
⸮⸮⸮8Y8⸮
[D][WiFiGeneric.cpp:337] _eventCallback(): Event: 0 - WIFI_READY
[D][WiFiGeneric.cpp:337] _eventCallback(): Event: 14 - AP_STOP
[D][WiFiGeneric.cpp:337] _eventCallback(): Event: 2 - STA_START
[D][WiFiGeneric.cpp:337] _eventCallback(): Event: 2 - STA_START
[D][WiFiGeneric.cpp:337] _eventCallback(): Event: 2 - STA_START
[D][WiFiGeneric.cpp:337] _eventCallback(): Event: 2 - STA_START
[D][WiFiGeneric.cpp:337] _eventCallback(): Event: 2 - STA_START
[D][WiFiGeneric.cpp:337] _eventCallback(): Event: 2 - STA_START
[E][Preferences.cpp:38] begin(): nvs_open failed: NOT_FOUND
[D][WiFiGeneric.cpp:337] _eventCallback(): Event: 4 - STA_CONNECTED
[D][WiFiGeneric.cpp:337] _eventCallback(): Event: 7 - STA_GOT_IP
[D][WiFiGeneric.cpp:381] _eventCallback(): STA IP: 192.168.1.192, MASK: 255.255.255.0, GW: 192.168.1.1
WiFi connected: 192.168.1.192 on ESP-78e9

```

Full code sample below, written with the Arduino IDE

```
#include <WiFi.h>
#include <WebServer.h>
#include <AutoConnect.h>

WebServer         Server;
AutoConnect       Portal(Server);
AutoConnectConfig Config;

void rootPage() {
  char content[] = "Hello, world";
  Server.send(200, "text/plain", content);
}

void setup() {

  Config.apid = "ESP-" + String((uint32_t)(ESP.getEfuseMac() >> 32), HEX);
  Config.psk = "Password1";
  Portal.config(Config);

  delay(5000);
  Serial.begin(9600);
  Serial.println();

  Server.on("/", rootPage);
  if (Portal.begin()) {
    // Serial.println("WiFi connected: " + WiFi.localIP().toString());
    Serial.println("WiFi connected: " + WiFi.localIP().toString() + " on " + Config.apid);
  }
}

void loop() {
    Portal.handleClient();
}

```

I've tried looking into why "nvs\_open failed: NOT\_FOUND" is occurring as that feels like the next step, but can't find any information on how to fix it.

I've also tried this on two boards of the same model.

Any ideas?

\** Update \** I've modified the code to include the following, but still no AP and captive portal.

https://hieromon.github.io/AutoConnect/advancedusage.html#on-demand-start-the-captive-portal

According to the link above, that SHOULD start a captive portal before attempting to connect to WiFi.

```
  Config.autoRise = false;
  Config.immediateStart = true;

```

Instead I get the debug text here:

```
[D][WiFiGeneric.cpp:337] _eventCallback(): Event: 0 - WIFI_READY
[D][WiFiGeneric.cpp:337] _eventCallback(): Event: 2 - STA_START
[D][WiFiGeneric.cpp:337] _eventCallback(): Event: 14 - AP_STOP
[D][WiFiGeneric.cpp:337] _eventCallback(): Event: 14 - AP_STOP
[D][WiFiGeneric.cpp:337] _eventCallback(): Event: 0 - WIFI_READY
[D][WiFiGeneric.cpp:337] _eventCallback(): Event: 14 - AP_STOP
[D][WiFiGeneric.cpp:337] _eventCallback(): Event: 14 - AP_STOP
[D][WiFiGeneric.cpp:337] _eventCallback(): Event: 14 - AP_STOP
[D][WiFiGeneric.cpp:337] _eventCallback(): Event: 14 - AP_STOP
[D][WiFiGeneric.cpp:337] _eventCallback(): Event: 14 - AP_STOP
[D][WiFiGeneric.cpp:337] _eventCallback(): Event: 2 - STA_START
[D][WiFiGeneric.cpp:337] _eventCallback(): Event: 2 - STA_START

```

*Update 2*

There may be a bug in the documentation. I changed "autoRise" to true and the SSID was broadcasted.

```
  Config.autoRise = true;
  Config.immediateStart = true;

```

# Answer
It looks like your ESP32 is already successfully connecting to an access point as a STA (station) and does not start its own Access Point (AP). You probably have already previously configured an SSID and password and the ESP32 is successfully reusing those, so it will not start the Captive Portal (as its own AP).

You should force AutoConnect to start up the Captive Portal or to forget its pre-programmed SSID and password. This can be achieved by On-demand starting of the Captive Portal like described on this page. According to the documentation you should put the following lines in your code (I have not tested this myself):

```
Config.autoRise = true;
Config.immediateStart = true;
Portal.config(Config);
....
Portal.begin();

```

NOTE: The documentation actually states Config.autoRise = false but it seems this does not have the desired effect.
> 2 votes

---
Tags: esp32
---


# Question
Title: LCD Backlight doesn’t work even at 5V. Using 330 Ohm resistor
I’ve been trying to make this project: https://create.arduino.cc/projecthub/chummer1010/electronic-safe-with-arduino-25d039

I’m confident that I’ve assembled everything correctly, but my LCD doesn’t display characters. Other projects seem to have fixed it by changing the potentiometer but I’m not using one.

Arduino code:

```
/*
Made by Marco Fusco
May 20, 2016
Contact me at: marcofusco111@gmail.com
*/

#include <LiquidCrystal.h>
#include <EEPROM.h>
#include <Servo.h>

int address = 0;
static unsigned long SaveTimer;
static unsigned long SaveDelay = (30 * 1000);

char CODE[10] = "1234E";
char Str[10];
char CodeLength = 4;
int Pos = 0;
bool Unlocked;
static unsigned long DisplayTimer;
static unsigned long DisplayDelay = 200;

LiquidCrystal lcd(12, 11, 9, 8, 7, 6);

int buttonPin1 = 2;
int buttonPin2 = 3;
int buttonPin3 = 4;
int buttonPin4 = 5;

int enterbutton = 10;
int clearlockbutton = 13;

Servo myServo;

void setup() {

  myServo.attach(A1);

  int EEPROMCodeOK = true;
  for (Pos = 0; Pos <= (CodeLength); Pos++) {
    Str[Pos] =  EEPROM.read(Pos);
    if (!(strrchr("1123456789", Str[Pos]))) {
      // not a valid code
      EEPROMCodeOK = false;
    }
  }
  Pos++;
  Str[Pos] =  EEPROM.read(Pos);
  if (Str[CodeLength + 1] != 'E') EEPROMCodeOK = false;
  if (EEPROMCodeOK) {
    Str[CodeLength + 2] = '\0';
    strncpy(CODE, Str, CodeLength + 1);
  }
  ClearCode();

  pinMode(buttonPin1, INPUT_PULLUP);
  pinMode(buttonPin2, INPUT_PULLUP);
  pinMode(buttonPin3, INPUT_PULLUP);
  pinMode(buttonPin4, INPUT_PULLUP);

  pinMode(enterbutton, INPUT_PULLUP);
  pinMode(clearlockbutton, INPUT_PULLUP);

  lcd.begin(16, 2);
  lcd.setCursor(0, 0);
  lcd.print("Hello.");
  delay(2000);
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Password:");

  DisplayTimer = millis() + 200;
}

void loop() {

  Lock();

  Pos = constrain(Pos, 0, CodeLength);

  int buttonState1 = digitalRead(buttonPin1);
  int buttonState2 = digitalRead(buttonPin2);
  int buttonState3 = digitalRead(buttonPin3);
  int buttonState4 = digitalRead(buttonPin4);

  int clButtonState = digitalRead(clearlockbutton);
  int enterButtonState = digitalRead(enterbutton);

  lcd.setCursor(9, 0);

  if (buttonState1 == LOW) {
    Str[Pos] = '1';
    Pos++;
    Str[Pos] = '\0';
    delay(250);
    while (digitalRead(buttonPin1) == LOW);

  }

  else if (buttonState2 == LOW) {
    Str[Pos] = '2';
    Pos++;
    Str[Pos] = '\0';
    delay(250);
    while (digitalRead(buttonPin2) == LOW);

  }

  else if (buttonState3 == LOW) {
    Str[Pos] = '3';
    Pos++;
    Str[Pos] = '\0';
    delay(250);
    while (digitalRead(buttonPin3) == LOW);
  }

  else if (buttonState4 == LOW) {
    Str[Pos] = '4';
    Pos++;
    Str[Pos] = '\0';
    delay(250);
    while (digitalRead(buttonPin4) == LOW);

  }
  else if (enterButtonState == LOW) {
    Str[Pos] = 'E';
    Pos++;
    Str[Pos] = '\0';
    delay(250);
    while (digitalRead(buttonPin1) == LOW);
     if (strcmp (Str,CODE) == 0) {
      Unlocked = true;
      lcd.setCursor(0, 0);
      lcd.print(" Access Granted");
      delay(2000);
      lcd.clear();
      lcd.print("    Unlocked");
    }
    else if (SaveTimer > millis() && (Pos + 1) == CodeLength) {

      strcpy(CODE, Str);
      for (Pos = 0; Pos <= (CodeLength + 1); Pos++) {
        EEPROM.write(Pos, Str[Pos]);
      }
      lcd.setCursor(0, 0);
      lcd.print("Saving Code:");
      lcd.setCursor(0, 1);
      lcd.print(Str);

      Unlocked = true;
    }

    else {

      lcd.clear();
      lcd.print(" Access Denied.");
      delay(2000);
      lcd.clear();
      lcd.print("Password:");

    }

    while (Unlocked) {
      Unlock();
      if (digitalRead(clearlockbutton) == LOW) {
        delay(200);
        lcd.clear();
        lcd.print("     Locked");
        delay(2000);
        lcd.clear();
        Unlocked = false;
        SaveTimer = millis() + 30000;
      }
    }

    ClearCode();

  }

  else if (clButtonState == LOW) {
    delay(500);

    while (clearlockbutton == LOW);
    if ((millis() - SaveTimer) > 4500) {

    }

    ClearCode();

  }

  if ( (long)( millis() - DisplayTimer ) >= 0) {
    DisplayTimer += DisplayDelay;
    lcd.setCursor(9, 0);
    lcd.print(Str);
    lcd.print("     ");

  }
}

void ClearCode() {

  Pos = 0;
  Str[Pos] = '\0';
  lcd.setCursor(0, 0);
  lcd.print("Password:");
  lcd.setCursor(0, 1);
  lcd.print("          ");

}

void Unlock() {

  myServo.write(150);

}

void Lock() {

  myServo.write(50);

}

```

# Answer
Please add a foto of the display. Most likely you have problem with a contrast. Schematic at the link you've provided is very strange: pin 3, which is responsible for the contrast, is tied directly to GND, which sets the display to the minimum contrast. You should use either a potentiometer, or a voltage divider for this pin.
> 2 votes

# Answer
Start with the Liquid Crystal, HelloWorld, Example. Find out if it's your pin configuration or pot/no pot issue, or if you have a doofed LCD.

Some LCD 1602 have an on board pot, so make sure that's not there too.

Process of elimination.
> 0 votes

---
Tags: arduino-uno, lcd
---


# Question
Title: I think i worn out all of my Arduino Uno memory
Hi my Arduino Uno stacked with a motor driver shield was working perfectly however I am using the same board for a while now and suddenly my board stopped working. When I upload a code no matter what code is the LED's on the board respond however the code is not executed it does nothing , the board doesn t even beep anymore. Is there a way to clean the memory or something? Please help.

# Answer
To check if you really cannot upload anymore (assuming it's not a software error), try the following sketch

https://www.arduino.cc/en/tutorial/blink

This will blink the BUILTIN led.

There is very low chance to wore out your memory, you can write lots of times to it (like 10,000 times guaranteed, in practice mostly more).

But there can be another hardware problem, but first check if this simple sketch works.

Also (based on jsotola's comment), remove shields/wires.

Especially wires/shields using RX/TX since these pins are (somehow) used for loading a sketch.
> 4 votes

---
Tags: arduino-uno, memory-usage, memory
---


# Question
Title: Why do people use 115200 instead of 9600?
So I came across lots of Arduino program setting serial speed to 115200 instead of 9600, while many people just kept using 9600 for the same purpose.

Why did people choose to use 115200 or other available speed? Why not just use 9600?

# Answer
https://www.arduino.cc/en/Reference/softwareSerial Because 115200 band was also the fastest communication enabled by the software serial.
> 2 votes

---
Tags: serial, serial-data
---


# Question
Title: Reading RAM from SH1106 OLED Controller through I2C
<sub>*Summary: I'm having trouble with writing a program to get RAM data from an SH1106 OLED controller via i2c. In the first part of the question I've written the assumptions I've made to get informations I couldn't find in the datasheet, in the second part I've posted a program which should read that data but doesn't (obviously, since I'm writing here...).*</sub>

I'm working on a program to control an SH1106 OLED display. I read the datasheet to find out how to send commands to it and it works, I can write to my display.
Now in the datasheet there is one thing I don't understand: how can I read the RAM?

Consider the picture below, taken from the command table at pages 30 and 31 of the SH1106 datasheet; the last line is the one about reading RAM.
This chip can be connected to a microcontroller through different interfaces: 6800 and 8800 8-bit parallel, 3 and 4 wire SPI and i2c. Since I'm using SPI I don't have any `A0`, `RD` or `WR` pin, and I didn't found anywhere in the datasheet a "translation" of the boolean value given to those signals in the command table to some i2c signal. I assume that WR corresponds with the lsb of the i2c address, since it is 0 for writing and 1 for reading. And my assumption seems to be true since I can read the status (line 25).
Then I assumed that `A0` should match `DC` (Data/Command, see second screenshot), a bit of the Control byte. The control byte is a byte that has to be sent before each byte or group of bytes to tell the chip how to interpret it (command or data). But I tried to send it before an i2c reading with different values and I always get the status byte (never the RAM data).

How could I read the memory of an SH1106 chip through i2c? The datasheet doesn't states that it is impossible (neither that it is possible...), maybe I simply can't?

**Command table**  (I removed lines 1-16, which contain commands like those at lines 17-23)
**Control byte**

---

**EDIT**

Here is the shortest working program I could write which shows the problem (i.e. which contains my implementation errors). I tested it on an Arduino UNO.

```
#define ADDR  0x78

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

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

void i2c_send(uint8_t data) {
  TWDR = data;
  TWCR = (1 << TWINT) | (1 << TWEN);
  while (!(TWCR & (1 << TWINT)));

}

uint8_t i2c_read(bool isLastByte) {

  if (isLastByte) TWCR = (1 << TWINT) | (1 << TWEN);
  else TWCR = (1 << TWEA) | (1 << TWINT) | (1 << TWEN);
  while (!(TWCR & (1 << TWINT)));
  return TWDR;
}

void display_init() {
  i2c_start();
  i2c_send(ADDR);
  i2c_send(0x00); //................ control byte
  i2c_send(0xAE); //................ displayOff
  i2c_send(0x8D); //................   *
  i2c_send(0xD5); i2c_send(0x80); // clockFrequency
  i2c_send(0x32); //................ pumpVoltage0123
  i2c_send(0xA1); //................ segmentRemap
  i2c_send(0xC8); //................ flipVertically
  i2c_send(0xDA); i2c_send(0x12); // comConfiguration
  i2c_send(0xA8); i2c_send(0x3F); // multiplex
  i2c_send(0xD3); i2c_send(0x3F); // displayOffest
  i2c_send(0x10); i2c_send(0x00); // columnAddr
  i2c_send(0x40); //................ startLine
  i2c_send(0xB0); //................ pageAddr
  i2c_send(0xAF); //................ displayOn
  i2c_stop();
}

void setup() {

  // Initialization
  Serial.begin(115200);
  display_init();

  // Request RAM data
  i2c_start();
  i2c_send(ADDR);
  i2c_send(0x80); //   control byte
  i2c_send(0xB0); // page address
  i2c_send(0x80); //   control byte
  i2c_send(0x10); // column address high
  i2c_send(0x80); //   control byte
  i2c_send(0x00); // column address low
  i2c_send(0x40); //   control byte
  i2c_send(0xE3); // nop
  i2c_stop();

  // get RAM data
  uint8_t a[10];
  i2c_start();
  i2c_send(ADDR + 1);
  for (int i = 0; i < 9; i++) a[i] = i2c_read(false);
  a[9] = i2c_read(false);
  i2c_stop();

  // print results
  for (int i = 0; i < 10; i++) {
    Serial.print("0x");
    Serial.println(a[i], HEX);
  }

}

void loop() {}

```

I've tried as many possibilities as I could imagine in the `// Request RAM data` section. To avoid confusion I leave only the posted one to your kind analysis, but of course if someone would like to see them just write it in a comment and I'll post all the (unsuccessful) test I have made.

The output on the serial monitor is always a list of `0x3`s.

I've not reduced the initialisation routine I use in my code because maybe the issue comes from there. BTW, I have no idea about what the `i2c_send(0x8D); //................ *` line does, I've added it because all the others SH1106 libraries I found had it, but I didn't found it in my datasheet. Maybe there are multiple versions of the chip or of the datasheet?

# Answer
> 1 votes
My version of the data sheet has a flowchart (Figure 10) for doing a "read-modify-write". In there is a clue - there has to be a dummy read before the actual read is done. Here is my function for plotting a pixel, which requires a read-modify-write to add a pixel to the existing data. It's not clear dummy read is needed before every byte read, or just on the first of a sequence of bytes, but that's easy enough to test.

```
#define CTRL_LAST_CMD 0x00
#define CTRL_NEXT_CMD 0x80
#define CTRL_LAST_RAM 0x40
#define CTRL_NEXT_RAM 0xC0

void MySH1106_PlotPixel(char x, char y, char on) {
  unsigned char curDisp;
  MySH1106_SetPage(y/8);
  MySH1106_SetCol(x);

  Wire.beginTransmission(SLAVE_ADDR);
  Wire.write(CTRL_LAST_CMD);
  Wire.write(0xE0); //R-M-W enable
  Wire.endTransmission(1);

  Wire.beginTransmission(SLAVE_ADDR);
  Wire.write(CTRL_LAST_RAM);
  Wire.endTransmission(1);

  Wire.requestFrom(SLAVE_ADDR, 2, 1);
  while(Wire.available()<2);
  curDisp = Wire.read(); //dummy read
  curDisp = Wire.read(); //real read.

  Wire.beginTransmission(SLAVE_ADDR);
  Wire.write(CTRL_LAST_RAM);
  if (on) {
    Wire.write((0x1<<(y%8)) | curDisp);
  } else {
    Wire.write(~(0x1<<(y%8)) & curDisp);
  }
  Wire.beginTransmission(SLAVE_ADDR);
  Wire.write(CTRL_LAST_CMD);
  Wire.write(0xEE);//end R-M-W
  Wire.endTransmission(1);

}

```

This is woefully inefficient for plotting one pixel, but it's a start.

Edit: I've subsequently confirmed that only 1 byte of dummy read is needed, even if the reads are stopped/restarted. As long as you're only doing RAM reads, no further dummy reads are needed.

# Answer
> 0 votes
It's slightly tricky understanding the protocol with I2C. The bit to watch is:

> If the R/ W bit is set to one in the slave-address, the chip will output data immediately after the slave-address according to the D/C bit, **which was sent during the last write access.** If no acknowledge is generated by the master after a byte, the driver stops transferring data to the master.

So you have to set the D/C bit in the transaction *before* you want to access the RAM.

It's unclear from the datasheet if you have to send a data byte after the control byte for it to be accepted, but if you do you can use the NOP command.

So you do a write of NOP with D/C (which, yes, corresponds to A0 in the other interfaces) set to 1 in the control byte (i.e., write the bytes 0x40 0xE3) and then you can do a read which should return the RAM contents at the current page/column address, which will auto-increment for each subsequent byte.

It's quite an unclear datasheet when it comes to explaining how I2C reading works...

---
Tags: arduino-uno, i2c, display
---


# Question
Title: Please help me read this Schematic Diagram
So, i'm trying to build an Obstacle Avoiding Robot by refering this site "Robot Obstacle Avoiding Car On the website they have provided with very poor Circuit Diagram. Please help me read the positions of capacitors. I have completed connection of all other components.

Help would be appreciated

# Answer
They are not poorly described.

All capacitors need to be put from the VCC to GND directly (this will not cause a shortcut).

The left 3 are related to the motor; as it uses a lot of current, it can take the current from the capacitors instead of flowing all the way to the power supply, causing problems of a voltage reduction that can cause other components to fail (temporarily).

The middle two are for the ultrasonic sensor as it also uses some current. 0.1 uF capacitors (the one for the ultrasonic sensor) is typically used for ICs and are called bypass capacitors. These needs to be placed as close as the VCC of the IC (in this case ultrasonic as possible).

And the right two for the power supply itself to remove noise/ripple.

For all capacitors, place them close to where the power is needed (for the motor/ultrasonic) and for the power supply close to the VCC input.

**EDIT**

Below I added the capacitors for the motor, sorry for using MS paint, having no better option right now. I assume the two red wires from the L293D other than going to the breadboard are the 9V lines (VDD).

Also don't put the capacitors in the same pin as the L293D IC pins, but I didn't want to obfuscate the picture. This might destroy your breadboard or IC pins as there is too less space for both.
> 1 votes

---
Tags: arduino-uno, capacitors
---


# Question
Title: Is it possible to measure analog output?
I'm using PWM to control LED brightness using MOSFET, using `analogWrite(pwmPin,val)`, while `val` is a 12 bit bit value.

`pwmPin` is defined as- `pinMode(pwmPin, OUTPUT);`

Since `val` changes in time due to external lightning, I wish to measure PWM value, for later use in code. Using `analogRead(pwnPin)` yielded a changing value ranges 7-14.

Is there a way to measure PWM value defined as an output ?

**EDIT 1:**

Saving `val`'s value won't save the problem I'm looking for, since code reaches a `deepSeleep` phase, which `val` can be stored, but I want an actual incidication of its value, and if it actually on.

# Answer
First: Why would you need to measure the PWM value. You already know it; it's saved in the `val` variable. Why not just use this variable for later use in code?

Second: Doing the analogRead on the same pin as the PWM output is not going to work. Internally there are 2 different hardware peripherals, that are responsible for these functions: The ADC is responsible for measuring analog voltages, while one of the Timers is responsible for generating the PWM output. Only one of them can connect to the pin at any time. Thus you are not measuring the PWM signal, when you do an `analogRead(pwmPin)`. This function set's the pin for measuring analog voltages (means it connect it to the ADC and configures the ADC) and thus disconnects the Timer hardware.

Third: Doing an `analogRead()` directly on a PWM signal is not going to work. PWM is still a digital signal, so measuring it's analog voltage would yield only values around 0 and 1023. This signal is transformed to a real analog voltage through a low pass filter, either electrically or mechanically (here I mean because mechanical elements often cannot follow the relatively fast PWM signal - like a motor or a speaker - which results effectively in a low pass filter).

**How to measure a PWM signal then?** First you definitely need to use a different pin, than the PWM output pin. Then you have 2 ways of measuring the current PWM value:

1. You can connect the PWM output to a low pass filter (combination of resistor and capacitor; you can google this and get very detailed descriptions), and the output of the low pass filter to an analog input pin of the Arduino. Then you can do `analogRead()`s to measure the current value.
2. You can measure the PWM signal directly, meaning measuring the actual pulse width of the signal. There are multiple ways of doing this, one being the `pulseIn()` function, which wait's for a pulse to complete and returns the length of the pulse.
> 6 votes

---
Tags: pwm, analogread
---


# Question
Title: How do i send data from a Master to another Master?
I am using an ESP32 to receive data from web. However in an I2C communication, the EPS32 does not work as a Slave and i already have an Atmega as the Master.

i have seen sites saying Master-Master I2C Connection is possible however, how do i do this? or are there other solutions to have the ESP32 communicate to the ATMega?

# Answer
Both your master devices must support Multimaster mode, i.e. Arbitration and Synchronization. See I2C Spec here for a description of the arbitration process.
It's up to you to handle a lost arbitration in your software.

> or are there other solutions to have the ESP32 communicate to the ATMega?

Of course. As you considered I2C to be sufficient, UART and SPI are feasible alternatives supported by almost all microcontrollers.
> 1 votes

---
Tags: i2c, communication, esp32
---


# Question
Title: VSCode Platformio Schedule.h: No such file or directory
I suppose this might be more an environment question regarding Platform.io and VSCode, as my code works great in the Arduino IDE, however the lack of syntax highlighting is driving me mad.

I've setup a Platform.io project in VSCode, copied my code across and setup my board (Wemos D1 Mini)

My `platformio.ini` file looks like:

```
[env:wemos_d1_mini32]
platform = espressif32
board = wemos_d1_mini32
framework = arduino

```

There are a couple of headers that are highlighted as having errors:

```
#include "FirebaseESP8266.h"
#include <ESP8266WiFi.h>

```

I've installed FirebaseESP8266 to my project from the PlatformIO libraries, however it still says:

> include errors detected. Please update your includePath. Squiggles are disabled for this translation unit (C:\Users\Greg\Documents\PlatformIO\Projects\Lovebox\src\main.cpp).C/C++(1696)

If I try to build it errors with `src\main.cpp:1:22: fatal error: Schedule.h: No such file or directory`

As for the ESP8266WiFi library, it simply says `cannot open source file "ESP8266WiFi.h"`

Anyone know where I'm going wrong?

# Answer
Did you install the libraries you need / use?

You could do it either via the platformio screen or add the names directly to the `platformio.ini`

```
lib_deps =
    Firebase ESP8266 Client@>=2.7.8

```

And additionally `ESP8266WiFi.h` is an ESP8266 library
for the ESP32 you should use the lib `#include <WiFi.h>`

EDIT: To update the project libraries, select 'Update Project Libraries' from the project tasks.
> 2 votes

---
Tags: c++
---


# Question
Title: How can I power an ESP8266 using a 9V 1A barrel connector power supply?
I have a Huzzah Feather ESP8266 (pinout) and due to the requirements of my project, I need to supply it with a 9V power adapter with a barrel connector, such as this one. I'm *REALLY* new to all of this, so I am trying to figure out how to do this and understand reading dev board specs.

It looks like this development board has a regulator that will adjust a power source down to the appropriate voltage... but how do I know what parameters it allows?

If I'm understanding correctly, on the pinout sheet above it looks like I would connect a power supply to the "VBUS" and "GND" (right?) pins. It also says "500mA Max", so does that mean a 1A power supply won't work? Also, why wouldn't it specify a maximum voltage?

If just connecting a barrel connector to those pins will not work, what am I missing that would get me there?

# Answer
> 1 votes
You cannot. If you look at the datasheet:

https://cdn-learn.adafruit.com/downloads/pdf/adafruit-feather-huzzah-esp8266.pdf

you can read all details on page 25/26:

> **Alternative Power Options**
>
> The two primary ways for powering a feather are a 3.7/4.2V LiPo battery plugged into the JST portor a USB power cable.
>
> If you need other ways to power the Feather, here's what we recommend:
>
> Here's what you cannot do:
>
> * Do not use alkaline or NiMH batteries and connect to the battery port - this will destroy the LiPoly charger and there's no way to disable the charger
> * Do not use 7.4V RC batteries on the battery port - this will destroy the board
>
> The Feather is not designed for external power supplies - this is a design decision to make the board compact and low cost. It is not recommended, but technically possible:
>
> * Connect an external 3.3V power supply to the 3V and GND pins. Not recommended, this may cause unexpected behavior and the EN pin will no longer. Also this doesn't provide power on BAT or USB and some Feathers/Wings use those pins for high current usages. You may end up damaging your Feather.
> * Connect an external 5V power supply to the USB and GND pins. Not recommended, this may cause unexpected behavior when plugging in the USB port because you will be back-powering the USB port, which could confuse or damage your computer.

# Answer
> 0 votes
If you read the docs on that Feather board, the barrel connector is meant for a LiPo battery.

It's a 3V unit, not meant for an external power supply, and 9V is too much for it. You would need to run your 9V supply through a buck converter (or a linear regulator) and drop it down to 5V, which you could feed into the USB connector. That does mean that when you want to connect it to USB to power it it will lose power, unless you also plug a LiPo battery into the barrel connector.

---
Tags: esp8266, power
---


title: esp8266 ip address issues

text:
# Question
Title: esp8266 ip address issues
I have android studio app and arduino codes they are connected to each other using esp8266 but it works only on one network when I use another network it doesn't recognise it's ip address instead it gives 0.0.0.0  Only this worked

```
 #include <LCD5110_Graph.h>
    #include <Adafruit_MLX90614.h>

    #define DEVICE_ID "Monitor1"

    #define DEBUG true
    #define REQ_CODE_ACK 1
    #define REQ_CODE_VALUES 2

    //84w * 48h
    LCD5110 myGLCD(8,9,10,12,11);
    extern uint8_t SmallFont[];   //8h * 6w font

    Adafruit_MLX90614 mlx = Adafruit_MLX90614();
    int pinLM35 = A0;         //Pin A0 is for LM35
    int fsrAnalogPin = A2;    //Pin A2 is for force sensor
    int blinkPin = 13;        // Pin 13 is the on-board LED

  String mSSID = "LibyaADSL-9a86";    //initial ssid and password
  String mPASS = "BYRTPCRJAHPWQ";

    //http request code
    int service_code;

    //wifi listen variables
    String wifiBuf = "";
    char character;
    int connectionId = 0 ;

    //sensor values
    float sensor_mlx, sensor_heart, sensor_lm35;
    int sensor_force;

    void setup() {
      //init LCD
      myGLCD.InitLCD();
      myGLCD.setFont(SmallFont);
      randomSeed(analogRead(7));

      //init MLX90614
      mlx.begin();

      //init serial
      Serial.begin(115200);           //Arduino-PC
      Serial3.begin(115200);          //Arduino-ESP8266\

      //init esp8266
      init8266();

      pinMode(blinkPin,OUTPUT);         // pin that will blink to your heartbeat!

      delay(200);
    }

    //init esp8266
    void init8266()
    {
        Serial.println("Init ESP...");
        String stationConCmd = make8266InitCommand();

        sendCommand("AT+RST\r\n",2000,DEBUG);       // reset module
        sendCommand("AT+CWMODE=1\r\n",1000,DEBUG);  // configure as access point
       // sendCommand("AT+CWDHCP=1,1\r\n",1000,DEBUG);
       // sendCommand("AT+CIPSTA=192.168.0.101,192.168.0.1,255,255,255,0\r\n",1000,DEBUG);    // HI اني ضفته
        sendCommand(stationConCmd, 1000, DEBUG);

        delay(1000);
        sendCommand("AT+CIFSR\r\n",1000,DEBUG);     // get ip address
    ///
        sendCommand("AT+CIPMUX=1\r\n",1000,DEBUG);  // configure for multiple connections
        sendCommand("AT+CIPSERVER=1,80\r\n",1000,DEBUG); // turn on server on port 80
    }

    //Make command string for connect to AP
    String make8266InitCommand()
    {
        String cmd = "AT+CWJAP=\"" ;
        cmd += mSSID;
        cmd += "\",\"";
        cmd += mPASS;
        cmd += "\"";
        cmd += ",11,0\r\n";

        return cmd;
    }

```

i still can't figure it out

Hope someone can help

Thank you

# Answer
If you configure the esp as an access point then it should also be the DHCP server and be supplying ip addresses to it's clients. Only if you configure it to be a client station itself (eg. connect to your router as client) will it be assigned an ip address.
> -1 votes

---
Tags: arduino-uno, esp8266, arduino-ide, c
---


title: Bootloader vs. Programmer

text:
# Question
Title: Bootloader vs. Programmer
I have just started using Arduino boards and I am not sure what the programmers are. I read that you can use a bootloader or a programmer to run your code on an Arduino board. I also read that running with a programmer does not take up any memory space for the bootloader and does not take any time to go through the bootloader.

My question is then, why should I not upload my code during development using a programmer?

# Answer
> 2 votes
The bootloader is a 'program' that resides inside the Atmel IC and makes that IC an 'Arduino'. The bootloader takes care that a sketch can be retrieved by UART (via the USB) and stored inside the Arduino.

The programmer is an external hardware device that can upload a sketch without using the bootloader. Another Arduino can also be used as programmer.

In both cases, when a sketch is loaded, it can be run by the Arduino. The programmer does not need a bootloader, so the memory that normally is taken by the bootloader can be saved.

You could use a programmer, but normally there's plenty space for a sketch. Note, it's not the SRAM memory that is saved, only the Flash memory. And if you are reaching the limit of the Flash memory, you should either optimize it, or move to an Arduino with more Flash memory.

Also, the bootloader is much more easy to use, since you can upload the sketch (to the boatloader) with the Arduino IDE. Programming can be done too by the IDE but is less trivial.

---
Tags: bootloader, programmer
---