# Question
Title: How to blink led and run another code at same time?
I had written a code to calculate rpm of the motors using IR sensor and Arduino nano and displaying it on OLED . With that I want an LED to blink always. Here is the code what I did:

You can **skip** the declarations and `setup()` part. Just move directly to `loop()`. I have **problem in loop**. In `loop()`, only LED goes on blinking and further rpm calculation with OLED displaying codes are not performed.

```
#include "avr/sleep.h"
#include "avr/power.h"
#include "SPI.h"
#include "Wire.h"
#include "Adafruit_GFX.h"
#include "Adafruit_SSD1306.h"

#define OLED_RESET 4

Adafruit_SSD1306 display(OLED_RESET);

int led = 12;
int in = 13;
int pushbutton=10;
unsigned long duration = 0;
float rpm = 0;
float rpm_a = 0;
int counter = 0;
int present = 0;
int previous = 0;
unsigned long elapsed = 0;
unsigned long elapsed_prev = 0;
int disabled = 0;

void setup() {
    Serial.begin(9600);
    pinMode(led, OUTPUT);
    pinMode(in,INPUT);
    pinMode(pushbutton,INPUT);
    display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
    display.clearDisplay();
    display.setTextSize(1);
    display.setTextColor(WHITE);
    display.setCursor(35,1);
    display.print("xyz");
    display.display();
    display.setTextSize(2);
    display.setTextColor(WHITE);
    display.setCursor(25,13);
    display.print("abc");
    display.display();

    delay(5000);

    display.clearDisplay();
    display.setTextSize(1);
    display.setTextColor(WHITE);
    display.setCursor(0,0);
    display.println("RPMmeter");
    display.display();
    display.setTextSize(2);
    display.setTextColor(WHITE);
    display.setCursor(0,19);
    display.println("RPM:");
    display.setCursor(80,19);
    display.println(rpm);
    display.display();

    elapsed = micros();
}

void loop()
{
    /** led blink part **/
    digitalWrite(led, HIGH);
    delay(70);
    digitalWrite(led, LOW);
    delay(70);
    digitalWrite(led, HIGH);
    delay(70);
    digitalWrite(led, LOW);
    delay(900);

    /** led blink part over and rpm calculation and displaying on
     * oled part starts **/

    if(digitalRead(pushbutton))
    {
        //Arduino low power enabled
        if(disabled==0)
        {
            sleep_disable();
            disabled = 1;
        }
        if (digitalRead(in) == 1 && previous == 0)
        {
            previous = 1;
            duration = elapsed - elapsed_prev;
            elapsed_prev  = micros();
        }
        if (digitalRead(in) == 1 && previous == 1)
        {
            previous = 1;
        }
        if (digitalRead(in) == 0 && previous == 1)
        {
            previous = 0;
        }
        if (digitalRead(in) == 0 && previous == 0)
        {
            previous = 0;
            elapsed = micros();
        }

        rpm = 60000000/duration;

        //We add a small error in the rpm value (in this case +-2)
        if ((rpm_a-2) < rpm  &&  rpm < (rpm_a+2))
        {
            rpm_a = rpm;
            counter = counter + 1;
            if (counter == 50)
            {
                display.clearDisplay();
                display.setTextSize(1);
                display.setTextColor(WHITE);
                display.setCursor(0,0);
                display.println("JARVIS RPMmeter");
                display.setTextSize(2);
                display.setTextColor(WHITE);
                display.setCursor(0,19);
                display.println("RPM:");
                display.setCursor(80,19);
                display.println(rpm);
                display.display();
                counter = 0;
            }
        }
        if (!( (rpm_a-2) < rpm  &&  rpm < (rpm_a+2)))
        {
            rpm_a=rpm;
        }

    }//end if pushbutton=1
    else {
        display.display();
        display.clearDisplay();
        delay(10);
        duration = 0;
        rpm = 0;
        rpm_a = 0;
        counter = 0;
        present = 0;
        previous = 0;
        //Arduino low power enabled
        set_sleep_mode(SLEEP_MODE_PWR_DOWN);
        sleep_enable();
        disabled = 0;
    }
}

```

This was the code. The problem is **without** that led blinking code part in the **loop**, the code works fine, but if we include that LED blinking part, the code *doesn't move further*. I mean only LED goes on blinking and further codes are *not performed*. Why is it so? And how to make both **rpm calculation with display on OLED** as well as **LED blinking** happen through a single code simultaneously?

# Answer
While executing the 'Delay' commands your arduino doesn't really do anything. The best thing you can do is have a look at BlinkWithoutDelay and adapt your code accordingly.
> 2 votes

# Answer
Look at my answer to a similar question. Apply the same principle to your problem:

* Move each task (blinking; calculating RPM) into its own separate function.
* Make loop() call those functions as often as possible.
* Make each function decide whether it is time to do its task, do it or not, and return.
* Those functions must never wait.

This kind of program organization - called non-blocking - is extendable to as many tasks as you wish, until you run out of memory, or the processor runs out of time to do everything as fast as you need it to (that will be a great many more than the two you've described!).
> 2 votes

# Answer
There are a few options to use millis() for this. Is it okay if I change the 900ms into a multiple of 70ms? Then I can count intervals of 70ms.

```
// blink led: 70ms on, then 70ms off, then 70ms on, then 910ms off

unsigned long previousMillis;
int count = 0;

void setup() {
  pinMode(13, OUTPUT);
}

void loop() {
  unsigned long currentMillis = millis();

  if(currentMillis - previousMillis >= 70) {
    previousMillis = currentMillis;

    switch(count) {
      case 0:
        digitalWrite(13, HIGH);
        break;
      case 1:
        digitalWrite(13, LOW);
        break;
      case 2:
        digitalWrite(13, HIGH);
        break;
      case 3:
        digitalWrite(13, LOW);
        break;
    }
    count++;

    if(count >= 16)
      count = 0;
  }
}

```

When the values of the intervals are in a array, then the code is probably smaller.

```
// blink led: 70ms on, 70ms off, 70ms on, 900ms off

unsigned long previousMillis;
const int intervals[4] = {70, 70, 70, 900};
int index = 0;

void setup() {
  pinMode(13, OUTPUT);
  digitalWrite(13, HIGH);  // turn led on, after 70ms it will be turned off
}

void loop() {
  unsigned long currentMillis = millis();

  if(currentMillis - previousMillis >= intervals[index]) {
    previousMillis = currentMillis;

    int level = (index % 2) == 0 ? LOW : HIGH;
    digitalWrite(13, level);

    index++;

    if(index > 3)
      index = 0;
  }
}

```

This second sketch is smaller, but I prefer the first one.
> 1 votes

# Answer
The only thing that I can see that makes your code faulty is the fact that you use a if statement to check if your button is pushed and then you have a lot of code to be executed in that statement rather set up a bool outside of your loop and set it with the if function then use a while to do all the rest of the work that was in your if statement that way when the button is released the code will still be executed and when it is pressed again it will happen again

Almost forgot the good stuff yes the blinkwithoutdelay is the way to go on the blink code
> 0 votes

---
Tags: arduino-uno, programming, arduino-nano
---


# Question
Title: Arduino controlling a heavy solenoid water valve
So after burning up a couple Arduinos, I'm running out of ideas...

I am trying to power both a Solenoid valve and the Arduino(nano) with the same 12V-2amp power supply. I've tried it with both a relay breakout board, and via transistor switching, and both are giving me sporadic behavior for the Solenoid.

Early failures came from realizing that the solenoid water value was actually a coil (duh), and thus needed some kind of diode placed over its connections, so I'm assuming the back voltage spike is what fried the first two boards.

At first I added a small diode that helped but wasn't enough, so I beefed it up to a 3 amp "rectifier diode" 200PIV, which stopped the board frying.

Here is a link to the solenoid water valve. Not much to go on I'm afraid. 12V 0.02-0.8Mpa.

The behavior that I'm seeing now, is that the solenoid will engage, but it won't disengage.

Do I need to add a Capacitor for the solenoid? If so, any recommendations on sizing?

```
int relayPin = 2;

void setup()
{
  pinMode(relayPin, OUTPUT);
  Serial.begin(115200);
}

void loop()
{
  Serial.println("starting");
  digitalWrite(relayPin, HIGH);
  delay(2000);
  digitalWrite(relayPin, LOW);
  delay(2000);
}

```

# Answer
> 0 votes
I have setup Arduino UNO and succeeded turning solenoid on when pot soil moisture dry, I was adding rain sensor when I mistakenly disvmcoonected the diode it fried my board, but atleast I had it working . I am using 24 volt normally closed solenoid , since I was monitoring over web I also had ethernet shield attached. And I was powering over ethernet using splitter and extracter.

The vin should only feed in 3.3 volt which you can get using stepdown buck converter , and use remains power to connect to solenoid. The transistor should be on the ground same as arduino nano the ground The top became messy later

# Answer
> 0 votes
Try This Circuit...

1. I think you are overpowering Arduino Board.
2. Transistor Will not Carry heavy current for long duty period.
3. It easy to use Simple 5v relay board then you don't have to worry about Current limits and all...

# Answer
> 0 votes
The fact that the solenoid turns on but not off makes me think the Arduino might just not switch off the GPIO. This could happen if the current drawn by the solenoid is so high that the power supply voltage drops below the threshold needed for the Arduino, resulting in a reset.

The result would be that the Arduino repeatedly switches on the solenoid but is reset before it can switch it off again.

Try to flash the built in LED in the same main loop to verify that the loop is still alive.

---
Tags: arduino-nano
---


# Question
Title: error 404 in HTTP GET request with Arduino Uno and ESP8266 using AT commands
when I try to send http get request I get error 404

```
AT+CIPMTX=1

OK
AT+CIPSTART=4,"TCP","alirezaabrhshami.ir",80
4,CONNECT
OK
AT⸮⸮R5U9⸮⸮b⸮⸮j
OK
>
Recv 47 qytes
SEND OK
+IPD,4,223;HTTP/1.1 404 Not Found
Cache-Contsol: public, max-age=0:a1n CeK⸮

```

this is my code:

```
#include <SoftwareSerial.h>

const byte rxPin = 2;
const byte txPin = 3;
SoftwareSerial ESP8266 (rxPin, txPin);

unsigned long lastTimeMillis = 0;

void setup() {
  Serial.begin(9600);
  ESP8266.begin(115200);
  delay(2000);
}

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

void loop() {

  if (millis() - lastTimeMillis > 30000) {
    lastTimeMillis = millis();

    ESP8266.println("AT+CIPMUX=1");
delay(1000);
printResponse();

ESP8266.println("AT+CIPSTART=4,\"TCP\",\"alirezaabrishami.ir\",80");
delay(1000);
printResponse();

String cmd = "GET /greencare/login.php?product_id=123456 ";
ESP8266.println("AT+CIPSEND=4," + String(cmd.length() + 4));
delay(1000);

ESP8266.println(cmd);
delay(1000);
ESP8266.println("");
  }

  if (ESP8266.available()) {
    Serial.write(ESP8266.read());
  }

}

```

# Answer
your HTTP request is incomplete. it should be

```
String cmd = "GET /greencare/login.php?product_id=123456 HTTP/1.1\r\nHost:alirezaabrishami.ir\r\n\r\n"

```

if the wen server host has more hostnames for the same IP address, the Host header is used on HTTP server to direct the request to the right web application
> 1 votes

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


# Question
Title: Access is denied. Error compiling for board Arduino/Genuino Uno
Having this error- Arduino: 1.8.8 Hourly Build 2018/11/30 12:33 (Windows 10), Board: "Arduino/Genuino Uno"

open sketch\LCD.ino.cpp: Access is denied. Error compiling for board Arduino/Genuino Uno.

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

# Answer
High likely one of the intermediate/binary files is in use. For example:

* When you have it already opened in a debug session
* Having it opened in multiple instances of your IDE
* Having it opened in another application
* Having closed an application that locked the intermediate/binary file(s).

What you can do:

* Close the debug session
* Close all applications related to the project
* Restart your computer
> 0 votes

---
Tags: arduino-uno
---


title: MISO pin issue in SPI

text:
# Question
Title: MISO pin issue in SPI
I have interfaced sd card and ADS1262 (ADC module) with Arduino mega board and sharing the SPI control pin i.e. SCK, MISO and MOSI. I have found that sd card is not initialized and ADS1262 is giving garbage value. Now if I remove the MISO pin of sd card then ADS1262 is giving right (although SD card is not initialized.) Vice-versa, if I remove the MISO pin of ADS1262, sd card is initialized and working perfectly (although ADS1262 is giving garbage value.)

Certainly, there is issue of MISO pin. How can I share MISO pin with both slaves so that both can work properly.

Any comments please.

I am using shifter - TXS0108E.

For SPI interfacing, I have tested two slaves with Mega board and found the below result when MISO is connected with both slaves and MISO pin is removing one by one from slaves.

From Above result, I thing it may be the problem of MISO pin.

I am not getting the idea, how to solve the problem in SPI interfacing in multiple slaves.

Schematic:

# Answer
> 1 votes
You probably want to use two SPI busses. If you absolutely need to use one bus, attach a digital out pin to each of the CS pins, one on the 1262 and one on the SD card. When you need to talk to one of the deviced, pull its CS line low to enable it.

# Answer
> 0 votes
Some sd card modules which use 5v-3.3v logic level shifters may not have a proper circuit wich is very well explained in this guys blog

http://www.vishnumaiea.in/projects/hardware/interfacing-catalex-micro-sd-card-module

so until you don't make some changes in the sd card module you wont be able to have multiple slaves on your spi bus.

---
Tags: arduino-mega, spi
---


title: addt instruction of Nextion Display

text:
# Question
Title: addt instruction of Nextion Display
I'm new to Nextion display. I'm doing a model of oscilloscope with the display and an Arduino Uno. I used the waveform component. I went through the instruction set and found two instructions to send data to the waveform component. The instruction "add" is clear to me. Tried and got the output. But the instruction "addt" is not clear to me. I sent the instruction

```
addt 1,0,30\xFF\xFF\xFF

```

I got something on the display which I'm not able to understand. Please someone explain what the instruction "addt" does....... I also came across the term "data pass through mode" under this instruction in the documentation. Please explain that too.....

Thanks in Advance.....

# Answer
> 1 votes
`addt` is the *volume* variant of `add`.

Instead of using something like:

```
add 1, 0, 19
add 1, 0, 39
add 1, 0, 85
add 1, 0, 98

```

you can group them all together with an `addt`:

```
addt 1, 0, 4
<5ms delay>
\x13\x27\x55\x62

```

The third parameter of the `addt` command is the number of values you want to send. Then you have to leave at least 5ms after sending the command so the display is ready to receive (it will actually send a "go" signal to you of `\xFE\xFF\xFF\xFF`. You send the data as raw binary values (shown as C string escape sequences above), and after it has received the specified number it responds with an "ok" signal of `\xFD\xFF\xFF\xFF`.

The maximum number of values you can send in one batch is 128.

---
Tags: arduino-uno
---


title: Arduino NANO hardware SPI not working

text:
# Question
Title: Arduino NANO hardware SPI not working
I have an Arduino NANO clone and a 2.4" ILI9341 TFT display. The VCC and LCD pins of the display are connected to the 5V pin of the board. The GND to the GND. All the logic pins are connected to voltage dividers (2k2 and 4k3 resistors), their connections checked and delivering 3.3V when 5V is supplied to them.

If I understand the source correctly, if I specify all the pins to the constructor, then I use software SPI, but if I don't, then I use hardware SPI.

Now, if I use the software SPI, everything is working fine, I can get the info, I can draw, etc. However if I use the hardware SPI then it is not giving me anything.

```
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>

// Adafruit_ILI9341 tft = Adafruit_ILI9341(10, 9);              // NOT WORKING!
Adafruit_ILI9341 tft = Adafruit_ILI9341(10, 9, 11, 13, 8, 12);  // WORKING!

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

    Serial.println("ILI9341 Test!");

    tft.begin();

    // read diagnostics (optional but can help debug problems)
    uint8_t x = tft.readcommand8(ILI9341_RDMODE);
    Serial.print("Display Power Mode: 0x"); Serial.println(x, HEX);
    x = tft.readcommand8(ILI9341_RDMADCTL);
    Serial.print("MADCTL Mode: 0x"); Serial.println(x, HEX);
    x = tft.readcommand8(ILI9341_RDPIXFMT);
    Serial.print("Pixel Format: 0x"); Serial.println(x, HEX);
    x = tft.readcommand8(ILI9341_RDIMGFMT);
    Serial.print("Image Format: 0x"); Serial.println(x, HEX);
    x = tft.readcommand8(ILI9341_RDSELFDIAG);
    Serial.print("Self Diagnostic: 0x"); Serial.println(x, HEX);
}

void
loop()
{
    // pass
}

```

However, what really makes me totally confused is when I use the SD card reader with the `SD Library` alone (the SD card reader is on the ILI9341 board), then that is working fine as well (as if the hardware SPI would be working, unless the SD Library is switching to software SPI magically). Anyway, the following is the working code:

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

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

    Serial.println("ILI9341 Test!");

    if (!SD.begin(7))
    {
        Serial.println("Cannot initialise SD card");
        while (true);
    }

    File file;

    if ((file = SD.open("file.txt", FILE_WRITE)))
    {
        Serial.print("Writing to file...");
        file.println("Hello, World!");
        file.close();
        Serial.println(" DONE");
    }
    else
        Serial.println("Cannot open file for writing");

    if ((file = SD.open("file.txt")))
    {
        Serial.println("Opening file...");
        while (file.available())
            Serial.write(file.read());
        file.close();
        Serial.println("DONE");
    }
    else
        Serial.println("Cannot open file for reading");
}

void
loop()
{
    // pass
}

```

---

**So what exactly is going on here? Am I doing something obviously wrong? Or is the board's hardware SPI not working? Or is there a problem with the Adafruit library?**

---

**Extra info:**

I'm using the `arduino-cli` to upload sketches the following ways:

```
# To compile:
arduino-cli                                     \
    compile                                     \
    --fqbn arduino:avr:nano:cpu=atmega328old    \
    --warnings all                              \
    MyArduinoSketch;

# To upload
sudo arduino-cli                                \
     upload                                     \
     --verify                                   \
     --verbose                                  \
     --port /dev/ttyUSB0                        \
     --fqbn arduino:avr:nano:cpu=atmega328old   \
     MyArduinoSketch;

```

I installed the mentioned libraries via `arduino-cli`.

# Answer
> 2 votes
Use constructor `Adafruit_ILI9341(10, 9, 8);` to make the reset that works with software SPI.

To SD card as second device on the bus:

Every SPI device on SPI bus must be controlled by slave select pin. If a device is connected to the bus and the SS pin is left floating the device disturbs the bus.

The empty SD card adapter is not a device on the bus, only the inserted card is a device. If it is on the bus the corresponding SS pin must be set HIGH. If you use the SD libray SD.begin(SD\_SS\_PIN), the library initializes the pin. If you don't use the library in the sketch (because it takes much memory), remove the SD card or set the SS pin to OUTPUT and HIGH.

# Answer
> 0 votes
Hi Peter First Adafruit spends a lot of time creating their libraries and i do appreciate that but my luck is that I never get anything working with their libraries it is just me

I use this library:

https://github.com/Bodmer/TFT\_ILI9341

and it works wonders if I want to add other SPI devices like your SD card I edit the User\_Setup File that is included in your sketch right at the bottom of the file you can find the following line:

```

// #define SUPPORT_TRANSACTIONS

```

uncomment that line and your Touch part as well as SD card will functional normally I have had a setup working with the screen, touch controller, RFID board and a SD card all working on SPI each with their own SS or Chip select pin

NB! if you are going to try the library it is best you remove the ADAfruit one first because there are some files with the same names and the IDE tends to include the first one it finds AKA Adafruit

---
Tags: arduino-nano, spi, sd-card, adafruit, tft
---


# Question
Title: Servo starts rotating whenever it is plugged
I am making a fish feeder using an Arduino Mega 2560, a servo motor SG90 and an RTC DS3231. I want to make it rotate twice a day, i.e. morning and 9 o'clock evening.

Whenever I plug my Arduino board to my laptop for the first time it rotates correctly during specified time 9 o'clock and I change the time to 9 o'clock 10 mins to check again and it rotates after I plug it to my laptop for 180 degrees and then rotates during the specified time.

What should I do to avoid that initial rotation?

Here is my code:

```
#include<Wire.h>
#include<LiquidCrystal.h>
#include "RTClib.h"
#include <Servo.h>

Servo myservo;

int pos = 0;
RTC_DS3231 rtc;
DateTime now;
const int OnHour = 9;
const int OnMin = 15;

void setup() {
  Serial.begin(9600);
  rtc.begin();
  myservo.attach(9);
  rtc.adjust(__DATE__,__TIME__));
}

void loop() {
  now = rtc.now();
  Serial.print(now.hour);
  Serial.print(" hour(s), ");
  Serial.print(now.min);
  Serial.print(" minute(s)");
  Serial.println(" ");
  delay(1000);
  if (now.hour == OnHour && now.min == OnMin) {
    Serial.println("feeder ON");
    myservo.write(90);
    delay(1000);
    myservo.write(180);
  } else {
    Serial.println("feeder OFF");
    delay(10);
  }
}

```

# Answer
> 0 votes
I'm not fully understanding the problem, but I assume you want it on for 9:00 / 9AM and 21:00 / 9 PM on for 15 minutes.

```
const int onTime1 =  9 * 60 +  0; // 9:00 AM
const int onTime2 = 21 * 60 + 30; // 9:30 PM
const int onMinutes   = 15; // Minutes

void loop()
{
  now = rtc.now();
  int nowTime = now.hour * 60 + now.min; // Minutes from current day

  if (((onTime1 <= nowTime) && (nowTime < onTime1 + onMinutes)) ||
      ((onTime2 <= nowTime) && (nowTime < onTime2 + onMinutes)))
  {
     myservo.write(90); // On
  }
  else
  {
     myservo.write(180); // Off
  }
  delay(1000); // 1 s delay
}

```

You can make the above if statement easier by:

```
  mysesrvo.write(180 - 90 * (int) (
   ((onTime1 <= nowTime) && (nowTime < onTime1 + onMinutes)) ||
   ((onTime2 <= nowTime) && (nowTime < onTime2 + onMinutes))));

```

---
Tags: arduino-mega, programming, servo, rtc
---


# Question
Title: esp8266 esp-01 printing garbage values on serial monitor
I am trying to up an esp8266 esp-01. While monitoring the serial monitor it's printing garbage values. I am using arduino-mega to write the code to the esp8266. The sample code i'm trying to write is

```
#include <ESP8266WiFi.h>
const char* ssid     = "SSID";
const char* password = "PASSWORD";

void setup() {
  Serial.begin(9600);// tried other rates as well
  delay(10);
  Serial.println('\n');

  WiFi.begin(ssid, password);
  Serial.print("Connecting to ");
  Serial.print(ssid); Serial.println(" ...");

  int i = 0;
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.print(++i); Serial.print(' ');
  }

  Serial.println('\n');
  Serial.println("Connection established!");
  Serial.print("IP address:\t");
  Serial.println(WiFi.localIP());
}

void loop() { }

```

Before this I tried to test the esp with a blink program, and it seems working. The connections between esp and arduino are as below

```
Arduino | ESP
------------------------------------------------------------
3.3V    | VCC(through a button)
3.3V    |CH_PD
TX      | TX
RX      | RX (connected through a voltage divider to arduino)
GPIO 0  | GND (through a push button to GND)
GPIO 2  | 3.3V (through a 1K resistor to 3.3V)

```

Arduino's the RESET and GND are shorted. What I'm trying to achieve to make the wifi module to act as message que, sending and receiving data to and from a device which is connected to it via internet.

# Answer
The "garbage values" are most likely messages from the bootloader, output at 74880bps. Try watching its serial out at that speed. You'll probably see messages that look something like:

```
ets Jan  8 2013,rst cause:2, boot mode:(3,7)
load 0x4010f000, len 1384, room 16
tail 8
chksum 0x2d
csum 0x2d

```

The `rst cause` number will give you an indication of why the chip rebooted.

The most common reset causes are

1. power on
2. hardware watchdog timer
3. fatal exception (most likely error in your code or power issue)
4. software watchdog timer
5. software reset
6. deep sleep
7. hardware reset

If it's a "fatal exception", you should see another line that looks like this:

```
Fatal   exception   (28):
epc1=0x4025bfa6,    epc2=0x00000000,    epc3=0x00000000,    excvaddr=0x0000000f,
depc=0x00000000

```

Look up the exception number; if it's not obvious what it means, google it to learn about the causes.
> 2 votes

---
Tags: arduino-mega, esp8266
---


# Question
Title: to measure the time between the ON signal and OFF signal
```
int pin_state = LOW;
struct Channel {
    byte pin;
    byte state;
    byte count;
    unsigned long fell, rose;
};

const int CHANNEL_COUNT = 3;
Channel channels[CHANNEL_COUNT] = {
    { 2, LOW, 0, 0 },
    { 3, LOW, 0, 0 },
    //{ 4, LOW, 0, 0 },
    //{ 5, LOW, 0, 0 },
    //{ 6, LOW, 0, 0 }
};

void setup()
{
    for (int i = 2; i <= CHANNEL_COUNT; ++i) {
        pinMode(channels[i].pin, INPUT);
    }
    Serial.begin(9600);
    //Serial.println("pin,fell,rose,low time");
    Serial.println("Minutes, Seconds, Count");
}

void loop()
{
    for (int i = 0; i < CHANNEL_COUNT; ++i)
    {
        Channel &c = channels[i];
        byte new_state = digitalRead(c.pin);
        if (c.state == LOW && new_state == HIGH)
        {
            c.rose = millis();
            c.count = c.count + 1;
        }
        else if (c.state == HIGH && new_state == LOW)
        {
            c.fell = millis();
            display_channel(c);
        }
        c.state = new_state;
    }
}

void display_channel(const Channel &c)
{
  int minutes, seconds;
  unsigned long difference;
  difference = c.fell - c.rose;
  seconds = int(difference/1000);
  if (seconds >= 60)
  {
       minutes = seconds / 60;
       seconds = seconds % 60;
  }
    //Serial.print(difference/1000);
    //Serial.print(",");
    Serial.print(minutes);
    Serial.print(",");
    Serial.print(seconds/1000);
    Serial.print(",");
    Serial.println(c.count-1);
    //Serial.print(",");
  }

```

When I try to run the program, I don't get any output. Is there anything wrong with the code, that must be solved before any output can get displayed?

# Answer
> 3 votes
Here's the catalog of errors I see at first glance:

```
const int CHANNEL_COUNT = 3;
Channel channels[CHANNEL_COUNT] = {
    { 2, LOW, 0, 0 },
    { 3, LOW, 0, 0 },
    //{ 4, LOW, 0, 0 },
    //{ 5, LOW, 0, 0 },
    //{ 6, LOW, 0, 0 }
};

```

You set up space for 3 entries but only fill 2. Also, the Channel structure has 5 entries, not 4. You don't initialize the 5th (`rose`) entry (although it will be initialized to 0 for you - best to be explicit though).

---

```
for (int i = 2; i <= CHANNEL_COUNT; ++i) {
    pinMode(channels[i].pin, INPUT);
}

```

You start from entry number 2 (the third entry) and iterate to the 4th (non-existent) entry to set the pin mode of either undefined or invalid pins.

---

```
for (int i = 0; i < CHANNEL_COUNT; ++i)

```

You have only filled in 2 of the three entries. Yet you use the third as if it were filled in.

---

```
Serial.print(minutes);

```

If `seconds` is less than 60 then `minutes` is undefined here.

---

I would suggest changing your code so that `Channel` is a class and embed the code to manage that class within it.

---

* Bonus Time

Here's your program re-written using a class. As an added bonus I have added automatic allocation of a channel number to each object as it's created. To add more channels just add the pin number into the initialization list.

```
class Channel {
    private:
        uint8_t _pin;
        uint8_t _state;
        uint32_t _rise;
        uint32_t _fall;
        uint8_t _count;
        uint8_t _channel;

        static uint8_t channelCount;

        void display() {
            uint32_t diff = (_fall - _rise) / 1000;
            uint32_t secs = diff % 60;
            uint32_t mins = diff / 60;
            Serial.print(_channel);
            Serial.print(",");
            Serial.print(mins);
            Serial.print(",");
            Serial.print(secs);
            Serial.print(",");
            Serial.println(_count);
        }

    public:
        Channel(int pin) : _pin(pin), _count(0) {
            _pin = pin;
            _count = 0;
            _channel = channelCount;
            channelCount++;
        }
        void process() {
            int s = digitalRead(_pin);
            if (s != _state) {
                _state = s;
                if (s == LOW) { // Fell
                    _fall = millis();
                    _count++;
                    display();
                } else {
                    _rise = millis();
                }
            }
        }
        void begin() {
            pinMode(_pin, INPUT);
        }
};

uint8_t Channel::channelCount = 0;

Channel channels[] = { 2, 3 };
#define NUM_CHANNELS (sizeof(channels) / sizeof(channels[0]))

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

    Serial.println("Channel,Minutes,Seconds,Count");

    for (unsigned int i = 0; i < NUM_CHANNELS; i++) {
        channels[i].begin();
    }
}

void loop() {
    for (unsigned int i = 0; i < NUM_CHANNELS; i++) {
        channels[i].process();
    }
}

```

---
Tags: arduino-uno, millis
---


title: Management issues through Blynk

text:
# Question
Title: Management issues through Blynk
I wrote a sketch for controlling the stepper motor under the controls of the Blynk application, the sketch was compiled but there was a problem in that no control was taking place. Receipts and controls occur on virtual pins V1, V2, V3. (The problem is that nothing is controlled), please help solve the problem.

```
//#include <Stepper.h>
//#define BLYNK_WRITE
//#include <ESP8266WiFi.h>
//#include <BlynkSimpleEsp8266.h>

const int stepsPerRevolution = 200;  // change this to fit the number of steps per revolution
// for your motor
Stepper myStepper(stepsPerRevolution, 1, 2, 3, 4);

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "[private]";

// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "S30mini";
char pass[] = "12345678";

int pinData;
int pinData1;
int pinData2;
BLYNK_WRITE(V3) //Button Widget is writing to pin V1
{
  int pinData = param.asInt();
 }
BLYNK_WRITE(V2) //Button Widget is writing to pin V1
{
  int pinData1 = param.asInt();
 }
BLYNK_WRITE(V1) //Button Widget is writing to pin V1
{
  int pinData2 = param.asInt();
 }

void setup()
{
  // Debug console
  Serial.begin(115200);
  Blynk.begin(auth, ssid, pass);
}

void loop()
{
    Blynk.run();

  // map it to a range from 0 to 100:
  int motorSpeed = map(pinData, 0, 1023, 0, 100);
  // set the motor speed:
  if (motorSpeed > 0) {
    myStepper.setSpeed(motorSpeed);
    // step 1/100 of a revolution:
    myStepper.step(stepsPerRevolution / 100);
  }

   if (pinData1 == 1){
      myStepper.step(stepsPerRevolution);
   }

   if (pinData2 == 1){
     myStepper.step(-stepsPerRevolution);
    }

}

```

# Answer
> 1 votes
By prefixing your `pinData` variables with `int`, you are declaring local variables in your `BLYNK_WRITE()` functions, whose scope is only in that function. The local version is written to, instead of the global.

To fix this, do not declare a new variable in `BLYNK_WRITE()`:

```
BLYNK_WRITE(V3) //Button Widget is writing to pin V1
{
  pinData = param.asInt();
}
BLYNK_WRITE(V2) //Button Widget is writing to pin V1
{
  pinData1 = param.asInt();
}
BLYNK_WRITE(V1) //Button Widget is writing to pin V1
{
  pinData2 = param.asInt();
}

```

---
Tags: esp8266, blynk
---


# Question
Title: Accessing multiplexed I2C and UART pins of STM32F103 in arduino IDE
I want to access both of the multiplexed I2C and UART pins in the same program. I am programming in Arduino IDE.Can anyone please tell me how to access same pins for different functionalities?

# Answer
> 1 votes
In order to use two different peripherals on the same pins, you have to initialize I2C and de-intialize UART when using I2C and doing the opposite when using UART.

It’s **not** possible to initialize two different peripherlas on the same pins, concurrently.

# Answer
> 1 votes
You can't. (Well, you can, but you mustn't).

I2C and UART are electrically incompatible bus systems. UART is a Push-Pull system, whereas I2C is an Open-Drain system. The Push-Pull connections will interfere with the Open-Drain outputs and I2C will not function.

If you want to have both you will need to include extra hardware (and the necessary control pins) to physically isolate the different devices from their respective bus when not in use.

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


# Question
Title: ESP8266 SoftwareSerial not receiving any character
I want to use a ESP8266 (ESP12) to receive data from a counter at 9600 baud via SotwareSerial. But my program does not receive any data. I broke it down to the code i attach here. I tried it using different libraries (Arduino SoftwareSerial and also espsoftwareserial) i found. I connected and tested RX and TX in different combinations of the available pins 4/5/12/13/14. But no combination is receiving data at all. I only can send data - checked by oscilloscope. Running my test program attached i connected the RX and TX pin together so i should loop back the data from tx.

I hopefully find somebody in the community who can give me a helpful hint. Thank you in advance!

```
#include <SoftwareSerial.h>
SoftwareSerial mySerial1(14, 12, false, 256);  // RX, TX

void setup() {
mySerial1.begin(9600);   //  Kommunikation mit Zähler
mySerial1.setTimeout(5000);
mySerial1.listen();
//delay(100);
//mySerial1.listen();

Serial.begin(9600);
delay(1000);
Serial.print(__DATE__);Serial.print(" ");Serial.println(__TIME__);

char ch;
while(1){
  wdt_reset();
  Serial.println("\nSoftware serial test started");
  Serial.print("Data sent: ");
  for (byte i = 32; i < 128; i++) { mySerial1.write(i);
  Serial.print(char(i)); }
  Serial.println();
  mySerial1.println();
  ESP.wdtFeed();
  delay(100);
  Serial.print("Data recv: ");
  if(mySerial1.available()) {
    while(mySerial1.available()){
      ch = mySerial1.read();
      Serial.print(ch);
    }
    Serial.println("_");
  }
  delay(400);
}
}

void loop() {}

```

# Answer
> 2 votes
If the ESP8266's software serial is anything like the Arduino's software serial, it cannot receive data while it's transmitting. It's strictly half-duplex.

To test your system you will need to test the transmission and reception completely separately, and that means having some external device sending data for you to attempt to receive.

---
Tags: esp8266, softwareserial
---


# Question
Title: Why my LCD does not work with this if statement?
```
#include <LiquidCrystal.h>
LiquidCrystal lcd(1, 2, 4, 5, 6, 7);
int greenLedPin = 12;
int blueLedPin = 11;
int redLedPin = 8;
int yellowLEdPin = 9;

int lightSensorPin = A0;
int analogValue = 0;

void setup() {
  // put your setup code here, to run once:
  lcd.begin(16, 2);
  pinMode(greenLedPin, OUTPUT);
  pinMode(blueLedPin, OUTPUT);
  pinMode(redLedPin, OUTPUT);
  pinMode(yellowLEdPin, OUTPUT);
  Serial.begin(9600);
  while (! Serial);

}

void loop() {
  // put your main code here, to run repeatedly:
  Serial.println(analogRead(lightSensorPin));
  analogValue = analogRead(lightSensorPin);
  if (analogValue < 50) {

digitalWrite(redLedPin, HIGH);

  }
  else if (analogValue >= 50 && analogValue <= 99) {
    digitalWrite(yellowLEdPin, HIGH);
  }
  else if (analogValue >= 100 && analogValue <= 300) {

    digitalWrite(blueLedPin, HIGH);
    lcd.print("its bright");
 }
  else {
      digitalWrite(greenLedPin, HIGH);
      lcd.print("its bright");
      }

  delay(3000);
  digitalWrite(greenLedPin, LOW);
  digitalWrite(blueLedPin, LOW);
  digitalWrite(redLedPin, LOW);
  digitalWrite(yellowLEdPin, LOW);
  lcd.clear();

}

```

I'm very new to this so sorry if its a dumb mistake and I know my LCD is working right, since I have tested it so all the pins are good.

# Answer
> 1 votes
On the Uno, pin 0 and 1 are used for Serial. You can't use pin 1 for Serial in addition to the LCD. In general, it's best to avoid using pins 0 and 1.

You need to change the LCD wiring to use a different pin and update the code accordingly. For example, if you moved the LCD's RS pin connection from pin 1 on your Arduino to pin 13, you would update this line from:

```
LiquidCrystal lcd(1, 2, 4, 5, 6, 7);

```

to:

```
LiquidCrystal lcd(13, 2, 4, 5, 6, 7);

```

After that, your LCD should work correctly.

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


# Question
Title: How to check whether my arduino-mega ADC is sampling correctly?
I have a code which samples the given input signals with sampling rate 256hz. I plotted the graph of FFT and was able to see the peaks at the expected frequencies.But I would like to know whether my ADC is sampling correctly or not?Is there a way to do it?\`

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

const unsigned long READ_PERIOD = 3906;  // 3906 us: 256 Hz
void loop() {
    static unsigned long lastRead;
    if (micros() - lastRead >= READ_PERIOD) {
        lastRead += READ_PERIOD;
        int val_a0 = analogRead(A0);
        int val_a1 = analogRead(A3);
        int val_a2 = analogRead(A5);
        int val_a3 = analogRead(A7);
       Serial.print(val_a0);
       Serial.print("  ");
       Serial.print(val_a1);
       Serial.print("  ");
      Serial.print(val_a2);
      Serial.print("  ");
        Serial.println(val_a3);
    }
}

```

# Answer
> 2 votes
In this case the baud rate will be real bottleneck. You have to send from 110 to 230 bits per reading (1 start bit, 8bits data, 1 stop bit)\*(3\*2 spaces + 4-16 number characters + 1 line feed).

That means best case (all numbers are less than 10) 349 readings per second. And worst case is 166 readings per second (all readings are more than 999).

So it's about 10% probability to be sampled correctly.

You can check if the next time (with misleading name `lastReading`) is less than current time. That means you are already too slow.

---
Tags: arduino-mega, adc
---


title: Nan values in Egg Incubator

text:
# Question
Title: Nan values in Egg Incubator
I've recently built my Arduino Incubator, which consists of a DHT22 sensor, an LCD Keypad Shield, some fans, resistors, e.t.c.

I uploaded the sketch, and everything seemed fine. However, when I try to select the temperature and humidity I want, it won't let me change anything, and it says "Temperature: NanC, Humidity: Nan%".

What am I doing wrong? I didn't write the code myself. I copied it from a guy who made his incubator and wrote his code himself. He has the incubator project on github.

As you can see in the pictures he posted, everything appears to be working fine. What would be the problem? I don't have a lot of Arduino knowledge, although I am OK with reading and tinkering with code.

The display below, shows NaN when I try to select my own temperature/humidity. When I see the current temperature/humidity, it works fine. The sensor works with no problems at all, though I didn't connect a pullup resistor. I am going to try adding one. However, to me it seems like the problem isn't that. I get NaN errors when trying to select my own value. The buzzer beeps, the servo turns and the fan works fine. As said above, DHT sensor works and sends the values.

Useful Links:

The code (Github)

The schematic (Github)

The whole incubator project (Github)

***Update - 7/1/2019*** Thanks to Jot, everything works fine now! He corrected my code, and he adviced me to reset the values in the EEPROM. I would have given up the project, unless he had helped me. I have now fully finished the build, even though I plan to add some features in the future.

**I want to add:**

* A backup power source (lead acid battery)
* Bigger ventilation holes
* Design improvements
* The ability to control everything using the serial monitor, so I can connect to the Arduino via Internet (Using an MFP Storage Server which I have)
* A larger box for more eggs
* A system which turns the eggs automatically
* A pump which pumps water to the sponge automatically as well

However, nothing could be done without Jot's help. Again, thanks a lot to Jot for his help, and the efforts he put in order to help me. I really appreciate that, since I have not any kind of Arduino knowledge (I'm 14 years old), and I found his advices and comments very very useful.

I have now put 5 eggs inside the incubator, and it is right now working. I am counting backwards from today, and in about 21 days I am going to have chickens!

**Here are some pictures of the machine for those who are interested (or just curious!):**

The incubator working, with the screen turned on:

The "egg hatching" room: (Inside, there is a wet sponge, all the devices and of course, 5 eggs!)

# Answer
Hi Lefteris the builder,
StackExchange is about questions and answers.
Arduino is about learning and fast prototyping.

For guidance with your project, the forum at http://forum.arduino.cc/ is more appropriate.

I suppose that a number of us have read the code that you use. We really do read code.
That code is not bad, but there are a few weak spots in that code:

* Not enough comments to explain what is going on.
* Many conditions with flags. That is okay, but the flags are sometimes a boolean and sometimes a byte, and there is no explanation what the flag is used for.
* Many checks for isnan(). Does that indicate that a floating point "nan" problem might pop up at any time in the sketch?
* Most of the code is in the loop(). I don't mind that, but others prefer to put large blocks of code in functions.

It seems that your hardware is working okay.

It is hard to confirm that the code for the Holt-Winters algoritme is working.

All this together is too confusing for us at the moment.

---

I have changed my answer, the hardware seems to be working.

---

Below is the changed sketch to test it without extra hardware.
I use the serial monitor. The sadw keys (followed by enter) are the cursor keys and the space bar (followed by enter) is select.

```
#include <avr/wdt.h>
// #include <Servo.h>
// #include <LiquidCrystal.h>
// #include <DHT.h>
#include <EEPROM.h>

// stty -F /dev/ttyACM0 115200 cs8 cread clocal -hupcl time 30 && tee incubator.log </dev/ttyACM0

#define WDT_TIMEOUT WDTO_8S // if defined, enable hardware watchdog
#define DHTPIN 3 // data pin of the DHT T/H sensor
#define T_OFFSET 0.9 // temperature sensor offset
#define FAN_PIN 2 // fan tacho signal pin
#define FAN_THRES 500 // fan alarm threshold
#define BEEPER A2 // pin where beeper is attached
#define BRIGHTNESS 10 // display brightness pin
#define HEATER A1 // heater MOSFET pin
#define DELAY 2000 // loop delay in ms
#define TS_ADDR 0 // temperature set point EEPROM address
#define HS_ADDR 4 // humidity set point EEPROM address
#define HC_ADDR 8 // humiditiy control mode EEPROM address
#define TI_RESET 1 // integral reset threshold, set integral to 0 when T error greater than this
#define HI_RESET 5 // integral reset threshold, set integral to 0 when H error greater than this
#define ALARM_T 2 // temperature alarm threshold, alert if T error greater than this
#define ALARM_H 8 // humidity alarm threshold, alert if H error greater than this
#define H_AUTO_THRES 3 // disable vent control in auto mode if H error < this
#define H_AUTO_COUNT 200 // disable for n cycles
#define HWAT 0.25 // holt winters parameters for temperature smoothing
#define HWBT 0.2
#define HWAH 0.7 // holt winters parameters for humidity smoothing
#define HWBH 0.5
#define A 0.005 // long average parameter
#define VENTCLOSED 80 // consider vent closed if under this angle
#define VENTOPENMS  480000L // open vent if closed longer
#define VENTRESETMS 600000L // reset vent after this time (>VENTOPENMS!)

// Servo vent;
// DHT dht(DHTPIN, DHT22);
// LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

#define RIGHT 16
#define UP 8
#define DOWN 4
#define LEFT 2
#define SELECT 1
#define NO_KEY 0

// added define to show messages on serial monitor.
#define lcd Serial

byte getKey() {
//  int key = analogRead(0);
//  if (key < 50) {
//    return RIGHT;
//  } else if (key < 150) {
//    return UP;
//  } else if (key < 300) {
//    return DOWN;
//  } else if (key < 500) {
//    return LEFT;
//  } else if (key < 800) {
//    return SELECT;
//  } else {
//    return NO_KEY;
//  }
  if (Serial.available() > 0) {
    int inChar = Serial.read();
    switch (inChar)
    {
      case 'w': return UP;
      case 'a': return LEFT;
      case 's': return DOWN;
      case 'd': return RIGHT;
      case ' ': return SELECT;
    }
  } else {
    return NO_KEY;
  }
}

void eeread(int address, int length, void* p) {
  byte* b = (byte*)p;
  for (int i = 0; i < length; i++) {
    *b++ = EEPROM.read(address + i);
  }
}

void eewrite(int address, int length, void* p) {
  byte* b = (byte*)p;
  for (int i = 0; i < length; i++) {
    EEPROM.write(address + i, *b++);
  }
}

void write_byte(int address, byte &value) {
  eewrite(address, sizeof(value), &value);
}

byte read_byte(int address) {
  byte value;
  eeread(address, sizeof(value), &value);
  return value;
}

void write_int(int address, int &value) {
  eewrite(address, sizeof(value), &value);
}

int read_int(int address) {
  int value;
  eeread(address, sizeof(value), &value);
  return value;
}

void write_float(int address, float &value) {
  eewrite(address, sizeof(value), &value);
}

float read_float(int address) {
  float value;
  eeread(address, sizeof(value), &value);
  return value;
}

void heater(boolean on) {
//  digitalWrite(HEATER, !on ? LOW : HIGH);
}

boolean heater() {
//  return digitalRead(HEATER) == HIGH;
  return true;
}

volatile int fancount;

void count() {
  ++fancount;
}

void beep(unsigned long f, unsigned long l) {
//  pinMode(BEEPER, OUTPUT);
  byte v = 0;
  f = 500000 / f;
  l = (1000 * l) / f;
  for (int i = 0; i < l; ++i) {
//    digitalWrite(BEEPER, v = !v);
//    delayMicroseconds(f);
  }
//  pinMode(BEEPER, INPUT);
}

float Ts, Hs; // set points
byte Hcontrol; // H control mode
byte Ts_changed, Hs_changed; // setpoint changed flags
float ET, dETdt, IETdt; // prop/diff/integ terms for T
float EH, dEHdt, IEHdt; // prop/diff/integ terms for H
float T, Tavg = NAN, Tvar, Tstd;
float H, Havg = NAN, Hvar, Hstd;
float Hpower, Hduty; // heater current power, average duty cycle
unsigned long t0, Hon, talarm, tventclosed;
byte displayMode;
byte key, bri = 255, alarm;
boolean ventclosed;
int fanrpm;

void setup() {
#if defined(WDT_TIMEOUT)
//  wdt_enable(WDT_TIMEOUT);
#endif
  Serial.begin(9600);
  Serial.println("Egg Incubator");
  Serial.println("Use wsad and space is select");

//  pinMode(HEATER, OUTPUT);
//  heater(0);
//  pinMode(BRIGHTNESS, OUTPUT);
//  analogWrite(BRIGHTNESS, bri = 255);
//  lcd.begin(16, 2);
//  lcd.noCursor();
  lcd.print("Incubator 0.7");
//  lcd.setCursor(0, 1);
  Serial.println();
  lcd.print(__DATE__);
//  dht.begin();
//  vent.setMinimumPulse(800);
//  vent.setMaximumPulse(2600);
//  vent.attach(11);
  //  write_float(TS_ADDR, Ts=37.8);  write_float(HS_ADDR, Hs=55);
  Ts = read_float(TS_ADDR);
  Hs = read_float(HS_ADDR);
  Hcontrol = read_byte(HC_ADDR);
//  pinMode(FAN_PIN, INPUT_PULLUP);
//  attachInterrupt(0, count, FALLING);
//  sei();
//  beep(800, 100);
//  beep(1000, 100);
//  beep(1200, 100);
//  beep(1600, 100);
}

void loop() {
  unsigned long t1 = millis();
  int dt = t1 - t0;

  if (!key) {
    key = getKey();
  }

  if (key) {
//    analogWrite(BRIGHTNESS, bri = 255);
  }

  if (t1 - Hon > Hpower * DELAY) {
//    heater(0);
  }

  if (Hcontrol && Hcontrol < H_AUTO_COUNT) {
//    vent.refresh();
  }

  if (alarm && !(alarm & 8)) {
//    beep(1000, 50);
//    beep(1414, 50);
  }

  if (dt > DELAY || key) {

    if (!key) {
      //    beep(2000, 50);
//      T = dht.readTemperature() + T_OFFSET;
      T = 30.0 + T_OFFSET;             // set to fixed value !
//      H = dht.readHumidity();
      H = 60.0;                        // set to fixed value !

      if ((isnan(T) || T < 10 || T > 60) || (Hcontrol && (isnan(H) || H < 5 || H > 95))) {
//        heater(0);
//        lcd.clear();
        lcd.print("SENSOR ERROR!");
//        lcd.setCursor(0, 1);
        Serial.println();
        lcd.print("T=");
        lcd.print(T);
        lcd.print("C H=");
        lcd.print(H, 1);
        lcd.print("%");
        beep(2000, 1000);
        return;
      }

      float dts = dt * 1e-3;

      if (dt > DELAY) {
        fanrpm = fancount * 60 / dts;
        fancount = 0;
      }

      if (fanrpm < FAN_THRES) {
        alarm |= 4;
      } else {
        alarm &= ~4;
      }

      // temperature Holt-Winters smoothing
      float E0 = ET;
      ET = HWAT * (T - Ts) + (1 - HWAT) * (ET + dETdt * dts); // smoothed T error (deviation from set point)
      dETdt = HWBT * (ET - E0) / dts + (1 - HWBT) * dETdt; // smoothed derivative
      IETdt += ET * dts; // integral of error
      if (abs(ET) > TI_RESET) // reset integral on big deviation
        IETdt = 0;
      float pidT = 1.1765 * (ET + 0.010526 * IETdt + 23.75 * dETdt); // PID value, adjust coefficients to tune
      Hpower = fanrpm > FAN_THRES ? max(0, min(1, -pidT)) : 0;
      heater(Hpower > 0.1);
      Hon = millis();

      if (abs(ET) > ALARM_T) {
        alarm |= 1;
//        vent.write(ET < 0 ? 0 : 180);
        if (Hcontrol > 1) {
          Hcontrol = 2;
        }
      } else {
        alarm &= ~1;
      }

      // humidity Holt-Winters smoothing
      E0 = EH;
      EH = HWAH * (H - Hs) + (1 - HWAH) * (EH + dEHdt * dts); // smoothed H error (deviation from set point)
      dEHdt = HWBH * (EH - E0) / dts + (1 - HWBH) * dEHdt; // smoothed derivative
      IEHdt += EH * dts; // integral of error
      if (abs(EH) > HI_RESET) // reset integral on big deviation
        IEHdt = 0;
      float pidH = 0.1176 * (EH + 0.09091 * IEHdt + 2.75 * dEHdt); // PID value, adjust coefficients to tune
//      vent.write(pidH * 180);

      if (Hcontrol && abs(EH) > ALARM_H) {
        alarm |= 2;
      } else {
        alarm &= ~2;
      }

      boolean ventclosed0 = ventclosed;
//      ventclosed = vent.read() < VENTCLOSED;
      ventclosed = VENTCLOSED;

      if (ventclosed && ventclosed != ventclosed0) {
        tventclosed = millis();
      }

      boolean openvent = ventclosed && millis() - tventclosed > VENTOPENMS;
      if (openvent) {
//        vent.write(180);
        if (millis() - tventclosed > VENTRESETMS) {
          tventclosed = millis();
        }
      }

      if (Hcontrol > 1) {
        if (abs(EH) > H_AUTO_THRES || openvent) {
          Hcontrol = 2;
        } else {
          if (Hcontrol < H_AUTO_COUNT) {
            ++Hcontrol;
          } else {
            IEHdt = 0;
          }
        }
      }

      // long term averages
      Tavg = A * T + (1 - A) * (isnan(Tavg) ? T : Tavg);
      Tvar = A * pow(T - Tavg, 2) + (1 - A) * (isnan(Tvar) ? 0 : Tvar);
      Tstd = sqrt(Tvar);

      Havg = A * H + (1 - A) * (isnan(Havg) ? H : Havg);
      Hvar = A * pow(H - Havg, 2) + (1 - A) * (isnan(Hvar) ? 0 : Hvar);
      Hstd = sqrt(Hvar);

      Hduty = A * Hpower + (1 - A) * Hduty;

      if (Ts_changed) {
        if (Ts_changed-- == 1)
          write_float(TS_ADDR, Ts);
      }

      if (Hs_changed) {
        if (Hs_changed-- == 1)
          write_float(HS_ADDR, Hs);
      }
    }

    if (key & SELECT) {
      displayMode = ++displayMode % 8;
    }

//    lcd.clear();
    Serial.println();
    lcd.print("T=");
    lcd.print(Ts + ET);
    lcd.print("C H=");
    lcd.print(Hs + EH, 1);
    lcd.print("%");

//    lcd.setCursor(0, 1);
    Serial.println();

    float uptime;
    char unit;
    switch (displayMode) {
      case 0: // raw values
        lcd.print("T=");
        lcd.print(T);
        lcd.print("C H=");
        lcd.print(H, 1);
        lcd.print("%");
        break;
      case 1: // temperature setpoint
        if (key & (UP | DOWN | LEFT | RIGHT)) {
          Ts = max(20, min(50, Ts + (key & (UP | RIGHT) ? +1 : -1) * (key & (UP | DOWN) ? 0.1 : 1)));
          Ts_changed = 10;
        }
        lcd.print("Ts=");
        lcd.print(Ts);
        lcd.print("C");
        break;
      case 2: // humidity setpoint
        if (key & (UP | DOWN)) {
          Hs = max(10, min(90, Hs + (key & UP ? +1 : -1)));
          Hs_changed = 10;
        }
        if (key & RIGHT) {
          if (Hcontrol < 2) {
            Hcontrol = ++Hcontrol;
          } else {
            Hcontrol = 0;
          }
          IEHdt = 0;
          write_byte(HC_ADDR, Hcontrol);
        }
        lcd.print("Hs=");
        lcd.print(Hs);
        lcd.print("% ");
        lcd.print(Hcontrol == 1 ? "on" : (Hcontrol > 1 ? "auto" : "off"));
        break;
      case 3: // average temperatur
        lcd.print("Ta=");
        lcd.print(Tavg);
        lcd.print("C (");
        lcd.print(Tstd);
        lcd.print(")");
        break;
      case 4: // average humidity
        lcd.print("Ha=");
        lcd.print(Havg);
        lcd.print("% (");
        lcd.print(Hstd);
        lcd.print(")");
        break;
      case 5: // heater duty cycle
        lcd.print("Hd=");
        lcd.print(Hduty);
        lcd.print(" Hp=");
        lcd.print(Hpower);
        break;
      case 6: // air vent
        lcd.print("V=");
//        lcd.print(vent.read() / 180.0);
        lcd.print(" F=");
        lcd.print(fanrpm);
        break;
      case 7: // average humidity
        uptime = t1 * 1e-3;
        unit = 's';
        if (uptime > 60) {
          uptime /= 60;
          unit = 'm';
          if (uptime > 60) {
            uptime /= 60;
            unit = 'h';
            if (uptime > 24) {
              uptime /= 24;
              unit = 'd';
            }
          }
        }
        lcd.print("Up=");
        lcd.print(uptime, 1);
        lcd.print(unit);
        break;
      default:;
    }

    Serial.println();

    if (alarm & 7) {
      if (!talarm) {
        talarm = millis();
      }
      // sound on persistent alarm and fan failure
      if (millis() - talarm > 300000L || alarm & 4) {
        alarm &= ~8;
      }
//      analogWrite(BRIGHTNESS, bri = 255);
//      lcd.setCursor(0, 0);
      if (alarm & 1)
        lcd.print("T ");
      if (alarm & 2)
        lcd.print("H ");
      if (alarm & 4)
        lcd.print("F ");
      lcd.print("ALARM!          ");
      if (!(alarm & 8) && key) {
        alarm |= 8; // alarm acknowledged
        talarm = millis();
      }
      if (!(alarm & 8)) {
//        lcd.setCursor(0, 1);
        Serial.println();

        lcd.print("T=");
        lcd.print(T);
        lcd.print("C H=");
        lcd.print(H, 1);
        lcd.print("%");
      }
    } else {
      alarm = 0;
      talarm = 0;
    }

    if (key) {
      delay((key & SELECT) ? 500 : 200);
    }

    if (bri) {
//      analogWrite(BRIGHTNESS, --bri);
    }
    key = 0;
    t0 = t1;
  }

#if defined(WDT_TIMEOUT)
  wdt_reset();
#endif
}

```

@Lefteristhebuilder, you have selected that sketch, but the sketch might not handle problems very well.

Anyone can write code for Arduino and put it online.
At least at Github it is possible that others can write an issue (as you did). The project at Github has 9 stars and the creator showed the project at the Arduino "Project Hub". That is all good, but I'm not very happy with the code itself.
> 1 votes

---
Tags: sensors, temperature, error
---


title: How to connect multiple I2C devices?

text:
# Question
Title: How to connect multiple I2C devices?
I am trying connecting I2C OLED SSD1306 and I2C INA219 on ESP32 but without success.

**First try:**

```
#include <WiFi.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_INA219.h>
Adafruit_INA219 ina219;

#define SDA1 21  //OLED SSD1306
#define SCL1 22  //OLED SSD1306
#define SDA2 5  //INA219
#define SCL2 4  //INA219

float shuntvoltage = 0;
float busvoltage = 0;
float current_mA = 0;
float current_A = 0;
float loadvoltage = 0;
float power_W = 0;

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET   0
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

const char* ssid     = "SSID";
const char* password = "PASSWORD";

IPAddress local_IP(192, 168, 0, 241);
IPAddress gateway(192, 168, 0, 230);
IPAddress subnet(255, 255, 255, 0);
IPAddress primaryDNS(8, 8, 8, 8);
IPAddress secondaryDNS(8, 8, 4, 4);

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

  Wire.begin(SDA1, SCL1);

  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }

   display.fillScreen(BLACK);
   display.setTextColor(WHITE);
   display.setTextWrap(false);

   startWiFi();

  Wire.begin(SDA2, SCL2);
  ina219.begin();

  display.ssd1306_command(SSD1306_DISPLAYOFF);
  delay(5000);
  display.ssd1306_command(SSD1306_DISPLAYON);
  display.println("Awake!");
  display.display();

}

void loop()
{
      shuntvoltage = ina219.getShuntVoltage_mV();
      busvoltage = ina219.getBusVoltage_V();
      current_mA = ina219.getCurrent_mA();
      loadvoltage = busvoltage + (shuntvoltage / 1000);
      current_A = current_mA / 1000;
      power_W = current_A * loadvoltage;

      Serial.println("");
      Serial.print("Bus Voltage:   "); Serial.print(busvoltage); Serial.println(" V");
      Serial.print("Shunt Voltage: "); Serial.print(shuntvoltage); Serial.println(" mV");
      Serial.print("Load Voltage:  "); Serial.print(loadvoltage); Serial.println(" V");
      Serial.print("Current:       "); Serial.print(current_mA); Serial.println(" mA");
      Serial.print("Power:       "); Serial.print(power_W); Serial.println(" w");
      Serial.println("");

  delay(1000);

  display.stopscroll();
  display.fillScreen(BLACK);
  display.invertDisplay(0);

  testscrolltext("TESTING");    // Draw scrolling text

}

const char* wl_status_to_string(wl_status_t status) {
  switch (status) {
    case WL_NO_SHIELD: return "WL_NO_SHIELD";
    case WL_IDLE_STATUS: return "WL_IDLE_STATUS";
    case WL_NO_SSID_AVAIL: return "WL_NO_SSID_AVAIL";
    case WL_SCAN_COMPLETED: return "WL_SCAN_COMPLETED";
    case WL_CONNECTED: return "WL_CONNECTED";
    case WL_CONNECT_FAILED: return "WL_CONNECT_FAILED";
    case WL_CONNECTION_LOST: return "WL_CONNECTION_LOST";
    case WL_DISCONNECTED: return "WL_DISCONNECTED";
  }
}

void printWifiStatus() {
  Serial.println("");
  Serial.println("WiFi connected.");
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  Serial.print("Gateway: ");
  Serial.println(WiFi.gatewayIP());
  Serial.print("Subnet: ");
  Serial.println(WiFi.subnetMask());
  Serial.print("Primary DNS: ");
  Serial.println(primaryDNS);

  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");

  Serial.printf("BSSID: %s\n", WiFi.BSSIDstr().c_str());
  Serial.println("Connected to wifi");
}

void startWiFi() { // Start a Wi-Fi access point, and try to connect to some given access points. Then wait for either an AP or STA connection

typedef enum {
    WL_NO_SHIELD        = 255,   // for compatibility with WiFi Shield library
    WL_IDLE_STATUS      = 0,
    WL_NO_SSID_AVAIL    = 1,
    WL_SCAN_COMPLETED   = 2,
    WL_CONNECTED        = 3,
    WL_CONNECT_FAILED   = 4,
    WL_CONNECTION_LOST  = 5,
    WL_DISCONNECTED     = 6
} wl_status_t;

  WiFi.begin(ssid, password);
  Serial.print("MAC Address: ");
  Serial.println(WiFi.macAddress());
  WiFi.config(local_IP, gateway, subnet, primaryDNS, secondaryDNS);
  WiFi.mode(WIFI_STA);
  Serial.println("Connecting Wifi...");
  delay(5000);

  // Wait for connection
  while (WiFi.status() != WL_CONNECTED) {
    Serial.println("NOT Connected to wifi");
    Serial.print("Status: ");
    Serial.println(wl_status_to_string(WiFi.status()));
    WiFi.begin(ssid, password);
  WiFi.config(local_IP, gateway, subnet, primaryDNS, secondaryDNS);
    WiFi.mode(WIFI_STA);
    delay(5000);
    ESP.restart();
  }

  //If connection successful show IP address in serial monitor
  Serial.println("Connected to wifi");
  printWifiStatus();

}

void testscrolltext(char * text) {
  display.clearDisplay();

  display.setTextSize(2); // Draw 2X-scale text
  display.setTextColor(WHITE);
  display.setCursor(10, 0);
  display.println(F(text));
  display.display();      // Show initial text
  delay(100);

  // Scroll in various directions, pausing in-between:
  display.startscrollright(0x00, 0x0F);
  delay(2000);
  display.stopscroll();
  delay(1000);
  display.startscrollleft(0x00, 0x0F);
  delay(2000);
  display.stopscroll();
  delay(1000);
  display.startscrolldiagright(0x00, 0x07);
  delay(2000);
  display.startscrolldiagleft(0x00, 0x07);
  delay(2000);
  display.stopscroll();
  delay(1000);
}

```

**OLED doesn't work. But INA219 works perfectly.**

**Second try:**

```
#include <WiFi.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_INA219.h>
Adafruit_INA219 ina219;

#define SDA1 21  //OLED SSD1306
#define SCL1 22  //OLED SSD1306
#define SDA2 5  //INA219
#define SCL2 4  //INA219

TwoWire I2Cone = TwoWire(0);
TwoWire I2Ctwo = TwoWire(1);

float shuntvoltage = 0;
float busvoltage = 0;
float current_mA = 0;
float current_A = 0;
float loadvoltage = 0;
float power_W = 0;

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET   0
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

const char* ssid     = "SSID";
const char* password = "PASSWORD";

IPAddress local_IP(192, 168, 0, 241);
IPAddress gateway(192, 168, 0, 230);
IPAddress subnet(255, 255, 255, 0);
IPAddress primaryDNS(8, 8, 8, 8);
IPAddress secondaryDNS(8, 8, 4, 4);

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

  I2Cone.begin(SDA1,SCL1,400000);
  I2Ctwo.begin(SDA2,SCL2,400000);

  I2Cone.beginTransmission(0x3C);
  I2Ctwo.beginTransmission(0x40);

  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }

   display.fillScreen(BLACK);
   display.setTextColor(WHITE);
   display.setTextWrap(false);

  startWiFi();
  ina219.begin();

  display.ssd1306_command(SSD1306_DISPLAYOFF);
  delay(5000);
  display.ssd1306_command(SSD1306_DISPLAYON);
  display.println("Awake!");
  display.display();

}

void loop()
{

      shuntvoltage = ina219.getShuntVoltage_mV();
      busvoltage = ina219.getBusVoltage_V();
      current_mA = ina219.getCurrent_mA();
      loadvoltage = busvoltage + (shuntvoltage / 1000);
      current_A = current_mA / 1000;
      power_W = current_A * loadvoltage;

      Serial.println("");
      Serial.print("Bus Voltage:   "); Serial.print(busvoltage); Serial.println(" V");
      Serial.print("Shunt Voltage: "); Serial.print(shuntvoltage); Serial.println(" mV");
      Serial.print("Load Voltage:  "); Serial.print(loadvoltage); Serial.println(" V");
      Serial.print("Current:       "); Serial.print(current_mA); Serial.println(" mA");
      Serial.print("Power:       "); Serial.print(power_W); Serial.println(" w");
      Serial.println("");

  delay(1000);

  display.stopscroll();
  display.fillScreen(BLACK);
  display.invertDisplay(0);

  testscrolltext("TESTING");    // Draw scrolling text

}

```

**OLED works perfectly. But INA219 doesn't work.**

How to make both OLED SSD1306 and INA219 works simultaneously?

Please help...

# Answer
I have used a 128\*64 oled display with a ina219. Both of them were working fine. Check the below code. Hope it helps.

```
#include <Adafruit_INA219.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_GFX.h>

#define I2C_OLED_ADDRESS    0x3C
#define I2C_INA219_ADDRESS  0x40

#define OLED_RESET  4

 Adafruit_SSD1306 oled(OLED_RESET);
 Adafruit_INA219 ina219;

 void initialize_device () {

  oled.begin (SSD1306_SWITCHCAPVCC, I2C_OLED_ADDRESS);
  oled.setTextColor (WHITE);
  oled.clearDisplay ();

  ina219.begin ();
}

 void refresh_oled (float current_ma, float load_voltage) {
  oled.clearDisplay ();

  oled.setTextSize (2);
  oled.setCursor (0, 0);
  oled.print ("V:"); oled.print (load_voltage); oled.print ('V');
  oled.setCursor(0, 20);
  oled.print ("I:"); oled.print (current_ma); oled.print ("mA");

  oled.display();
}

 void setup () {
  initialize_device ();
}

 void loop () {

  float current_ma = ina219.getCurrent_mA ();
  float load_voltage = ina219.getBusVoltage_V () + (ina219.getShuntVoltage_mV() / 1000);

  refresh_oled (current_ma, load_voltage);

  delay(100);
}

```
> 0 votes

# Answer
I think that the issue is during INA219 initialization.

According with the **begin** function of class Adafruit\_INA219.

Use:

> ina219.begin(&I2CTwo);

instead of

> ina219.begin();
> 0 votes

# Answer
Here is the code for connecting I2C OLED SSD1306 and I2C INA219 on ESP32 which will works simultaneously

```
#include <WiFi.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_INA219.h>
Adafruit_INA219 ina219;

#define SDA 21  //OLED SSD1306 & INA219 pin
#define SCL 22  //OLED SSD1306 & INA219 pin

float shuntvoltage = 0;
float busvoltage = 0;
float current_mA = 0;
float current_A = 0;
float loadvoltage = 0;
float power_W = 0;

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET   0
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

const char* ssid     = "SSID";
const char* password = "PASSWORD";

IPAddress local_IP(192, 168, 0, 241);
IPAddress gateway(192, 168, 0, 230);
IPAddress subnet(255, 255, 255, 0);
IPAddress primaryDNS(8, 8, 8, 8);
IPAddress secondaryDNS(8, 8, 4, 4);

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

  Wire.begin(SDA, SCL);

  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }

   display.fillScreen(BLACK);
   display.setTextColor(WHITE);
   display.setTextWrap(false);

  startWiFi();
  ina219.begin();

  display.ssd1306_command(SSD1306_DISPLAYOFF);
  delay(5000);
  display.ssd1306_command(SSD1306_DISPLAYON);
  display.println("Awake!");
  display.display();

}

void loop()
{

      shuntvoltage = ina219.getShuntVoltage_mV();
      busvoltage = ina219.getBusVoltage_V();
      current_mA = ina219.getCurrent_mA();
      loadvoltage = busvoltage + (shuntvoltage / 1000);
      current_A = current_mA / 1000;
      power_W = current_A * loadvoltage;

      Serial.println("");
      Serial.print("Bus Voltage:   "); Serial.print(busvoltage); Serial.println(" V");
      Serial.print("Shunt Voltage: "); Serial.print(shuntvoltage); Serial.println(" mV");
      Serial.print("Load Voltage:  "); Serial.print(loadvoltage); Serial.println(" V");
      Serial.print("Current:       "); Serial.print(current_mA); Serial.println(" mA");
      Serial.print("Power:       "); Serial.print(power_W); Serial.println(" w");
      Serial.println("");

  delay(1000);

  display.stopscroll();
  display.fillScreen(BLACK);
  display.invertDisplay(0);

  testscrolltext("TESTING");    // Draw scrolling text

}

const char* wl_status_to_string(wl_status_t status) {
  switch (status) {
    case WL_NO_SHIELD: return "WL_NO_SHIELD";
    case WL_IDLE_STATUS: return "WL_IDLE_STATUS";
    case WL_NO_SSID_AVAIL: return "WL_NO_SSID_AVAIL";
    case WL_SCAN_COMPLETED: return "WL_SCAN_COMPLETED";
    case WL_CONNECTED: return "WL_CONNECTED";
    case WL_CONNECT_FAILED: return "WL_CONNECT_FAILED";
    case WL_CONNECTION_LOST: return "WL_CONNECTION_LOST";
    case WL_DISCONNECTED: return "WL_DISCONNECTED";
  }
}

void printWifiStatus() {
  Serial.println("");
  Serial.println("WiFi connected.");
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  Serial.print("Gateway: ");
  Serial.println(WiFi.gatewayIP());
  Serial.print("Subnet: ");
  Serial.println(WiFi.subnetMask());
  Serial.print("Primary DNS: ");
  Serial.println(primaryDNS);

  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");

  Serial.printf("BSSID: %s\n", WiFi.BSSIDstr().c_str());
  Serial.println("Connected to wifi");
}

void startWiFi() { // Start a Wi-Fi access point, and try to connect to some given access points. Then wait for either an AP or STA connection

typedef enum {
    WL_NO_SHIELD        = 255,   // for compatibility with WiFi Shield library
    WL_IDLE_STATUS      = 0,
    WL_NO_SSID_AVAIL    = 1,
    WL_SCAN_COMPLETED   = 2,
    WL_CONNECTED        = 3,
    WL_CONNECT_FAILED   = 4,
    WL_CONNECTION_LOST  = 5,
    WL_DISCONNECTED     = 6
} wl_status_t;

  WiFi.begin(ssid, password);
  Serial.print("MAC Address: ");
  Serial.println(WiFi.macAddress());
  WiFi.config(local_IP, gateway, subnet, primaryDNS, secondaryDNS);
  WiFi.mode(WIFI_STA);
  Serial.println("Connecting Wifi...");
  delay(5000);

  // Wait for connection
  while (WiFi.status() != WL_CONNECTED) {
    Serial.println("NOT Connected to wifi");
    Serial.print("Status: ");
    Serial.println(wl_status_to_string(WiFi.status()));
    WiFi.begin(ssid, password);
  WiFi.config(local_IP, gateway, subnet, primaryDNS, secondaryDNS);
    WiFi.mode(WIFI_STA);
    delay(5000);
    ESP.restart();
  }

  //If connection successful show IP address in serial monitor
  Serial.println("Connected to wifi");
  printWifiStatus();

}

void testscrolltext(char * text) {
  display.clearDisplay();

  display.setTextSize(2); // Draw 2X-scale text
  display.setTextColor(WHITE);
  display.setCursor(10, 0);
  display.println(F(text));
  display.display();      // Show initial text
  delay(100);

  // Scroll in various directions, pausing in-between:
  display.startscrollright(0x00, 0x0F);
  delay(2000);
  display.stopscroll();
  delay(1000);
  display.startscrollleft(0x00, 0x0F);
  delay(2000);
  display.stopscroll();
  delay(1000);
  display.startscrolldiagright(0x00, 0x07);
  delay(2000);
  display.startscrolldiagleft(0x00, 0x07);
  delay(2000);
  display.stopscroll();
  delay(1000);
}

```

**NOTE:** Both OLED SSD1306 and INA219 must be using the same SDA & SCL pins (pin 21 & pin 22 on ESP32).

Hope this will help anyone who has same issue like me.
> 0 votes

---
Tags: arduino-ide
---


# Question
Title: USB Communication between Arduino Nano and UHF Reader module
I am working on a project that requires a UHF reader development kit that can communicate using either RS232 or by USB. Via USB and a Serial terminal, I have been able to send commands to the reader as well as analyze its response.

My goal is to send these same commands to the reader, but through an Arduino Nano. My first instinct was to use the RS232, converting the signal via a MAX232. However, this is for a school project, and my advisor preferred I try to work with USB. I am familiar with UART communication, and I've been under the assumption that USB operates using UART.

I had purchased a USB converter that gives me access to the pins, but it had two additional pins than I was not expecting: CTS and DTR. I attempted to communicate despite these pins (just leaving them open, and connecting Rx, Tx, Vcc and GND as I normally would). When plugged into the UHF reader, the device did power on (as it draws power from the USB connection), however, it did not receive the output signal from the Arduino Nano.

I know that my baud rate and other settings are correct, because, as I have said, communicating via USB and a Serial terminal gives me no problems. My initial thought is that I need to properly connect the CTS and DTR pins, but immediately I could not find a good reference on how to do this, and I am not entirely convinced this is the issue. My other thought was that perhaps I am writing out my HEX values wrong from the Arduino, using a line similar to the following, where "UHF\_Reader" is defined by SoftwareSerial:

```
UHF_Reader.write(0xAA);

```

However, it appears to me from research that this is indeed the correct way to output HEX values via serial.

My final attempt to resolve this was to connect the micro-USB from the Nano to the USB of the reader, and then use Software Serial in conjunction with the USB converter to analyze the output on a Serial terminal, while powering the Nano via a 5V power supply. However, since the reader draws power from the USB port, it did not even turn on when I attempted this (I am assuming that the Vcc can only be supplied *from* the USB end?). Regardless, this attempt proved useless as well.

If anyone can offer any advice, or point me towards any references for something similar, I would much appreciate it! I have spent a while on this, and I just can't figure out what the problem is.

For reference, the reader I am using is found here: UHF Reader

And the USB converter I am using is here: USB Converter

# Answer
> I've been under the assumption that USB operates using UART.

No. You have it backwards. Devices can emulate a UART (known as CDC/ACM) over a USB connection as one of the many possible device profiles, but it is about as far from being a UART as an F1 car is from a Penny Farthing.

USB operates on a strict Master / Slave principle. That is, it has a single master device, called the *Host*, which coordinates all the devices on the bus and makes requests to them. Everything you plug into a USB system is a *Device* and requires a *Host* to tell it what to do.

Neither the Nano, nor this adaptor you bought, are *Hosts*. They are just *Devices*. And Devices cannot talk to Devices. Only Hosts can talk to Devices.

Which means you need a Host in there somewhere. If you want it controlled by Arduino then you need a USB Host Shield (or something similar) which normally communicates over SPI.

If the device you are trying to talk to uses the CDC/ACM profile then you can use the USB Host Shield with it. If it uses a proprietary profile, like the CH340G or FT232, then getting it to work with the USB Host Shield will be much harder (maybe even impossible) unless you are intimate with the underlying protocol used.
> 0 votes

---
Tags: usb
---


# Question
Title: Arduino based fully controlled aquaculture
I am doing a project on aquaculture,so I am using temperature sensor, water level sensor, dissolved oxygen sensor, pH sensor and also 4 motor's and water heater is it possible for a single Arduino to run all these at the same time??

# Answer
I would suggest finding sensors that work on an I2C bus. This way all the sensors are only using two pins for data. That will free up other outputs for motors, heaters that will probably be on relays or other drivers that need a single or multiple pins for each devices. As you start to plan it out, if you do run out of pins on a arduino uno, look at the Mega, as it has many more GPIO pins as well as multiple dedicated UART ports.

Bottom line, find your sensors, drivers, see what type of communication they require, and start to make a list of how many separate io pins you need. Then that will tell you which board is suitable for your project.
> 2 votes

---
Tags: arduino-uno, sensors, motor, temperature-sensor, stepper-motor
---


# Question
Title: Digispark Attiny85 ultrasonic sensor input problem
I was trying to use ultrasonic with digispark Attiny85 board and used separate pins for trigger and echo, and used MM5451 led controller as a display, I uploaded the code successfully the problem is if the echo pin is connected to it at startup board stops/freezes I don't know but code doesn't work, and if I connect the echo pin few seconds after the board starts everything works fine.

Below is the code I wrote

```
#define clock 0
#define data 1
#define trig 2
#define echo 3
byte c[5]={10,11,11,0,12};
long dist=0;
const uint8_t digits[15]={
    B1110111,
    B1000100,
    B1101011,
    B1101110,
    B1011100,
    B0111110,
    B0111111,
    B1100100,
    B1111111,
    B1111110,
    B0111011,
    B0010011,
    B1011101,
    B0111001,
    B0000000
};
void setup()
{
    pinMode(clock,OUTPUT);
    pinMode(data,OUTPUT);
    pinMode(trig,OUTPUT);
    pinMode(echo,INPUT);
    digitalWrite(clock,LOW);
    digitalWrite(data,LOW);
    digitalWrite(trig,LOW);
}
void pulse()
{
    delayMicroseconds(5);
    digitalWrite(clock,HIGH);
    delayMicroseconds(10);
    digitalWrite(clock,LOW);
    delayMicroseconds(5);
}
long ultrasonic(boolean ci)
{
    long distance;
    unsigned long pulsetime;
    digitalWrite(trig,LOW);
    delayMicroseconds(5);
    digitalWrite(trig,HIGH);
    delayMicroseconds(10);
    digitalWrite(trig,LOW);
    pulsetime=pulseIn(echo,HIGH);
    if(ci)
    {
        distance=pulsetime/58;
    }
    else
    {
        distance=pulsetime/148;
    }
    delay(50);
    if((distance<450)&&ci)
    {
        return distance;
    }
    else if((distance<180)&&(!ci))
    {
        return distance;
    }
    else
    {
        return 0;
    }
}
void show(byte a[5])
{
    delayMicroseconds(5);
    digitalWrite(data,HIGH);
    pulse();
    for(byte x=0;x<5;++x)
    {
        byte data1=digits[a[x]];
        for(byte y=0;y<7;++y)
        {
            if(data1&(1<<y))
            {
              digitalWrite(data,HIGH);
                pulse();
            }
            else
            {
                digitalWrite(data,LOW);
                pulse();
            }
        }
    }
    digitalWrite(data,LOW);
    pulse();
}
void loop()
{
    show(c);
    delay(2000);
    while(1)
    {
        dist=ultrasonic(true);
        if(dist>0)
        {
            byte i=3;
            c[4]=14;
            c[0]=14;
            c[1]=14;
            c[2]=14;
            c[3]=14;
            while(dist>0)
            {
                c[i]=(dist%10);
                if(i==0)
                {
                    i=4;
                }
                dist/=10;
                --i;
            }
            show(c);
        }
        delay(200);
    }
}

```

# Answer
Pins 3 and 4 are used for USB (during programming). Try using pin 5 instead.

Or swap it with one of the clock, data, or trig outputs (i.e. 0,1,2)
> 1 votes

---
Tags: programming, sensors
---


# Question
Title: Why my serial message won't show on another when I try use 2 Arduino communication
I am trying to make a simple chatting program with my 2 arduino uno and 2 PC. But when I tried write a message using PC1 serial monitor the message won't show up on PC2 serial monitor. I can't see the problem or maybe I miss something on the program.

Here is my code: PC1:

```
#include <SoftwareSerial.h>

SoftwareSerial Serial1(10,11);

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

void loop()
{
    if ( Serial.available()) // Check to see if at least one character is available
    {
        char ch1 = Serial.read();
        Serial1.print(ch1);
    }

    delay(200);
}

```

PC2:

```
#include <SoftwareSerial.h>

SoftwareSerial Serial1(10,11);

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

void loop()
{
    if (Serial1.available())
    {
        char ch = Serial1.read();
        Serial.print(ch);
    }
}

```

# Answer
> 1 votes
I haven't tested this in a while but it has been my experience that even though you can have multiple IDE windows open, you can only have one Serial Monitor at a time. The way I got around this is to use a Terminal Emulator program for the second Arduino.

---
Tags: arduino-uno, serial, softwareserial
---


# Question
Title: Getting error ets jan 8 2013,rst cause:4,boot mode(1,6) wdt reset
I'm working on a project to send ultrasonic sensor data to my webserver. For that I'm using ESP8266 WiFi module, 3.3V regulator IC by giving input volt of 5v from aduino uno.

I successfully uploaded a code but in serial monitor I got an error

```
ets jan 8 2013,rst cause:4,boot mode(1,6) wdt reset.

```

Please, tell what does it mean?

Here is my code. Guide me if I made something wrong. Thanks in advance.

**Note:** Before sending sensor values I successfully send a raw data manually to webserver, i.e string data, but when I try to send sensor values, I got an error.

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

const char* ssid = "VENTURE 11";
const char* pass = "12345678";

WiFiClient clientx;
const int trigPin = 8;  //Digital port D5
const int echoPin = 9;  //Digital port D6

long duration;
float distance;
float Mdistance;
float MAX_HEIGHT = 0;

void setup() {

  Serial.begin(115200);                                  //Serial connection
  pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
  pinMode(echoPin, INPUT);

  WiFi.begin("VENTURE 11", "12345678");   //WiFi connection
  Serial.println("Setup iniated");
  while (WiFi.status() != 3) {  //Wait for the WiFI connection completion
    delay(500);
    Serial.println("Waiting for connection");
    Serial.print("WIFI STATUS : ");
    Serial.println(String(WiFi.status()));
  }
  Serial.println(String(WiFi.status()));
}

void loop() {
  Serial.println(String(WiFi.status()));
  if (WiFi.status() != 3)
  {
    WiFi.begin("VENTURE", "12345678");   //WiFi connection
    while (WiFi.status() != 3)
    {
      Serial.println("Waiting for connection");
    }
  }
  else
  {
    digitalWrite(trigPin, LOW);
    delayMicroseconds(2);

    // Sets the trigPin on HIGH state for 10 micro seconds
    digitalWrite(trigPin, HIGH);
    delayMicroseconds(10);
    digitalWrite(trigPin, LOW);

    // Reads the echoPin, returns the sound wave travel time in microseconds
    duration = pulseIn(echoPin, HIGH);

    // Calculating the distance
    distance = (duration * 0.034) / 2;

    if (MAX_HEIGHT == 0) {
      //MAX_HEIGHT = distance;
      Serial.print("Max height has been set to ");
      //Serial.print(distance);
      Serial.println(" cm");
      Serial.println("Waiting for 5 seconds...");
      delay(5000);
    } else {
      Serial.print("Distance:\n");
      Serial.print(distance);
      Serial.print("cm\n");
      Serial.print("Distance:\n");
      Serial.print(distance / 100);
      Serial.print("m\n");
      delay(1000);

    }

    HTTPClient http;
    String Data = "x=" + (String)distance + "&y=" + (String)MAX_HEIGHT + "&z=0";
    //String Data = "x=Finally&y=Did&z=it;)";
    http.begin("http://testingblahblah.000webhostapp.com/IOTCON.php");
    http.addHeader("Content-Type", "application/x-www-form-urlencoded");
    int sent = http.POST(Data);
    Serial.println(sent);
    String httpPayload = http.getString();
    Serial.println(httpPayload);
    if (sent > 0)
    {
      Serial.println("Message has been sent");
    } else {
      Serial.println("unable to send data");
    }
    delay(20000);

  }
}`

```

# Answer
> 3 votes
Found a possible solution. I was facing with the same problem. Apparently this is a hardware stack overflow watch dog preventing malfunction. This may not apply to every possible scenario but I discovered that the allocated pin number on the board itself is incorrect. What is numbered 03 is in fact D15 for example. So assigning the pin to D15 worked but 3 created this error. I hope this helps others.

# Answer
> 2 votes
Your `loop()`:

```
void loop() {
  Serial.println(String(WiFi.status()));
  if (WiFi.status() != 3)
  {
    WiFi.begin("VENTURE", "12345678");   //WiFi connection
    while (WiFi.status() != 3)
    {
      Serial.println("Waiting for connection");
    }
  }
  else
  {
    // Other code...
  }
}

```

While waiting for the connection, you are creating `String` objects at a very high rate, since your `delay(20000)` is in the `else` clause.

This means you are possibly running out of memory, as you are creating the `String` objects with every iteration, which is in the Megahertz range.

You likely don't need the `String(...)` wrappers, as the `Serial.println()` function can work with C-style strings returned by the `WiFi` library. Then, your program won't be allocating memory to hold the result of `WiFi.status()` millions of times per second, which you don't use later on in your program.

---
Tags: esp8266, code-review
---


# Question
Title: ESP8266 Supply Voltage dropping below 3.3V
I am trying to power an ESP8266 with a 3.3V regulator (this one, can supply ~ 1A). I've been struggling for days to get the ESP to work – it will occasionally boot, occasionally connect, but then not work again for hours. What I mean by "not working" is that it will often have trouble communicating over UART; or, upload my code, but not run it; or, run my code and crash on an Exception 0.

Now I have noticed that my voltage rail is dipping severely, sometimes below 3V. If I press my reset button, the level returns to 3.3V, but then when the ESP "boots" (but often not running any code, or crashing), it dips back to 2.9V. It is also fine while programming.

Does this suggest my ESP is simply fried? It's possible I briefly misconnected a wire when I first got the unit.

# Answer
> 2 votes
The ESP8266 will do an analog calibration when it is running the user code. This will typically be the worst case power requirement. The peak current requirement can be as much as 1/2 an amp. While your regulator probably can supply that I would bet your interconnecting wiring, and maybe the power source, are causing too much voltage drop.

The fact that you can see the voltage go down to 2.9 volts makes me thin that you have serious problems.

Early on when I started with the ESP8266 I was getting flaky operation. I put it down to bad code. But eventually I ruled that out. I took my setup to work (where I design electronic products) and looked at the power connections with a digital scope **at the module**. Right at the last point before the traces run under the shield. (I use the ESP-12 modules) It dipped just under 3.0 volts for two microseconds, and that was enough to cause a reset.

These things are **not tolerant** to any power dips. And this is why I recommend anyone starting with the ESP8266 to buy a Nodemcu or a Wemos type module. Something that has the regulator right at the processor.

# Answer
> 1 votes
It was a power issue. Everyone tells you the ESP8266 needs a lot of current, and I didn't believe them.

In case anyone else runs in to this issue, I was powering the ESP via a 3.3V regulator (fine), being fed from and Arduino's 5V (fine). **However:** I was plugging my Arduino directly into my MacBook. It seems that my Mac was limiting USB power. Using a powered USB hub (max current ~2A) worked fine, but you could probably also get away with directly powering VIN on the Arduino (or a standalone 3.3V supply).

---
Tags: esp8266, power
---


# Question
Title: Code getting stuck waiting for GPS Output
I'm basically trying to make a device that pulls the GPS information from a SIM808 and pushes it to a server online via GPRS.

I am sorry as I am not good at programming so ive spent days trying to debug this but i have not been able to figure out whats wrong.

Ill get the basics out of the way.

Board: Mega2560 (I know its overkill but its what i had in hand) SIM+GPS sensor: SIM808 Module TinyGPS v13 RTC: DS1307 Arduino IDE v1.8.8

Down to the specifics, I started with SoftwareSerial Library but i heard it was inefficient so i switched to AltSoftSerial. The serial library is working as I do get output using AT commands. The problem is that when i load up the stock TinyGPS example sketch sometimes it works sometimes it gives me error saying the GPS module wasn't detected.

i tried using AT commands directly or a different GPS library but i cant figure out how to pass on data to a database over GPRS.

but basically I am sure the wiring isn't faulty nor is the GPS module (i hope) as it gives an output at ATCommands, even the RTC module is confirmed working. I know the URL in the ATCommand is fake but that is for demonstration purposes.

Coming to the code below. If i change the bool newData = false; to bool newData = true; the the code works just once with wrong GPS information.

any help would be greatly appreciated. Thank You

Edit 1: The problem has been solved, it wasn't working when i used both GPS and GPRS on SIM808 i switched to NeoGPS 6m module and GPRS from SIM800/808 it worked. Thank You.

```
#include <AltSoftSerial.h>
#include <TinyGPS.h>

#include <Wire.h>
#include <DS1307new.h>

TinyGPS gps;

SoftwareSerial sGPS (46,48);

uint16_t startAddr = 0x0000;  //Start address to store in NVRam
uint16_t lastAddr;        //New address to store in NVRam
uint16_t TimeIsSet = 0xaa55;  //Helper that time must not be set again

int currentDay = 0;
int currentMonth = 0;
int currentYear = 0;
int currentHour = 0;
int currentMinute = 0;

float flat, flon;
float previousFLat = 0.0;
float previousFLon = 0.0;

void setup()
{

  Serial.begin(9600);
  sGPS.begin(9600);

  /*
  Control the clock.
  Clock will only be set if NV-RAM Address does not contain 0xaa.
  DS1307 should have a battery backup.
  */

  RTC.getRAM(54, (uint8_t *)&TimeIsSet, sizeof(uint16_t));
  if (TimeIsSet != 0xaa55)
  {
    RTC.stopClock();

    RTC.fillByYMD(2011,4,8);
    RTC.fillByHMS(22,7,0);

    RTC.setTime();
    TimeIsSet = 0xaa55;
    RTC.setRAM(54, (uint8_t *)&TimeIsSet, sizeof(uint16_t));
    RTC.startClock();
  }
  else
  {
    RTC.getTime();
  }

  /*
   Control Register for SQW pin which can be used as an interrupt.
*/
  RTC.ctrl = 0x00;                      // 0x00=disable SQW pin, 0x10=1Hz,
                                        // 0x11=4096Hz, 0x12=8192Hz, 0x13=32768Hz
  RTC.setCTRL();
  delay(5000);
  }

  void loop()
{
    RTC.getTime();

    currentDay = RTC.day;
    currentMonth = RTC.month;
    currentYear = RTC.year;
    currentHour = RTC.hour;
    currentMinute = RTC.minute;

  bool newData = false;

  //For one second we parse GPS data and report some key values

  for (unsigned long start = millis(); millis() - start < 1000;)

  {
  while (sGPS.available())
    {
      char c = sGPS.read();
      Serial.write(c); // uncomment this line if you want to see the GPS data flowing
      if (gps.encode(c)) // Did a new valid sentence come in?
      newData = true;
    }

  }

  if (newData)
  {
    unsigned long age;
    gps.f_get_position(&flat, &flon, &age);

    if ((flat !=previousFLat)||(flon !=previousFLon))
    {
      previousFLat = flat;
      previousFLon = flon;
      Serial.print (previousFLat,6);
      Serial.println(previousFLon,6);
      SendSQL();
    }
  }

}

  void SendSQL()
  {

    //Serial.println("Start Send");
    Serial.println("AT+SAPBR=3,1,\"Contype\",\"GPRS\"");
    delay(500);
    Serial.println("AT+SAPBR=3,1,\"APN\",\"airtelgprs.com\"");
    delay(500);
    Serial.println("AT+SAPBR=1,1");
    delay(500);
    Serial.println("AT+SAPBR=2,1");
    delay(3000);
    Serial.println("AT+HTTPINIT");
    delay(500);
    Serial.println("AT+HTTPARA=\"CID\",1");
    delay(500);
    Serial.print("AT+HTTPARA=\"URL\",\"www.google.com/add_data.php?");
    Serial.print("addDay=");

      if (currentDay <10)
        {
        Serial.print("0");
        Serial.print(currentDay);
        }

      else
        {
        Serial.print(currentDay);
        }

      Serial.print("/");

      if (currentMonth < 10)
        {
          Serial.print("0");
          Serial.print(currentMonth);
        }

      else
        {
          Serial.print(currentMonth);
        }

      Serial.print("/");
      Serial.print(currentYear);
      Serial.print("&addHour=");

      if (currentHour <10)
        {
          Serial.print("0");
          Serial.print(currentHour);
        }

        else

        {
          Serial.print(currentHour);
        }

        Serial.print(":");

        if (currentMinute <10)

        {
          Serial.print("0");
          Serial.print(currentMinute);
        }

        else

        {
          Serial.print (currentMinute);
        }

          Serial.print ("&addLati=");
          Serial.print(previousFLat, 6);
          Serial.print("&addLongti=");
          Serial.print(previousFLon, 6);
          Serial.println("\"");
          delay(3000);
          Serial.println("AT+HTTPACTION=0");
          delay(15000);
          Serial.println("AT+HTTPTERM");
          delay(500);
          Serial.println("AT+SAPBR=0,1");
          delay(500);
          Serial.println("Finish");
        }

```

# Answer
I agree with above answer use the Serial ports available and do something in your setup to probe the sim808 until you get some feedback I am using SIM868 in one of my projects and had the same problem of not getting any feedback until i set a while loop up in the setup that was probing by only sending 'AT' to the module (I did not use tinyGPS i only used Serial and sent it AT commands)

Here the application notes with the AT commands for the GPS side of SIM808

This approach will give you a better idea of what is happening and where you are going wrong
> 1 votes

# Answer
You have a Mega with 4 hardware serial ports. Use of those - Serial1, Serial2, Serial 3 - to talk to the GPS.

I did a project with a SIM808 module from DF Robotics. I spent some time just powering the GPS part of it up and watching what came out. Do the same with some simple serial print statements.

```
if (Serial1.available() >0){
Serial.print(Serial1.read());
}

```

Then when you understand what comes out, you can watch in setup() for the end of messages that indicate you have good GPS data, or just send AT commands until you get a good reply back. My module took I think 7-8 seconds before it would talk, so I just waited in setup() until I started getting messages. I knew what to expect from the above testing, it was always a fixed amount, so I grabbed all that, looked at the last few to make sure it was as expected, then started the GPS commands to see if it had good data from the satellites before continuing. I suspect the TinyGPS library does similar, but the SIM808 module added some extra characters, or you had to add extra characters, to identify GPS commands from the text message commands the SIM808 expected.
> 0 votes

# Answer
The problem has been solved, it wasn't working when i used both GPS and GPRS on SIM808 i switched to NeoGPS 6m module and GPRS from SIM800/808 it worked. Thank You.
> 0 votes

---
Tags: arduino-mega, programming, gsm, tinygps
---


# Question
Title: Can i send sensor data from arduino to cloud without sending it via PC
I am trying to build a GPS tracker. I need to send the data from GPS sensor on the arduino uno board to cloud directly i.e. without sending it via PC or mobile. Is it possible and if yes, HOW?

# Answer
> 1 votes
To connect to the cloud directly while the tracker is on the move, you'll need to use GSM & GPRS technology, ie. a SIM card to make a 3G/4G connection to the Internet. GSM gets you connected, GPRS does the Internet traffic. Using WiFi to connect to a router won't work since you'll soon get too far from the router.

I suggest initially investigating the SIM908 and SIM800L (there are others).

Here are 2 projects which both use the SIM908 (GSM, GPRS **AND** GPS):

Geolocation Tracker (GPRS + GPS) with SIM908 over Arduino and Raspberry Pi

Where is my car? Realtime GPS+GPRS Tracking of Vehicles Using Arduino

The cheaper SIM800 is also popular GPRS/GSM module (no GPS capability, but you already have that?):

QUICKSTART SIM800 (SIM800L) WITH ARDUINO

This technology is moving quickly, so you may find better options, for instance see:

Difference between SIM908 vs SIM808 modules

Hope this helps, Regards, Geoff

# Answer
> 1 votes
Arduino UNO is a micro controller without any internet communication. In order to send data to the cloud, you need to have an internet connection (meaning TCP/IP stack).

In regards with your project, there are 2 major solutions:

1. Store all data locally on EEPROM (if not too much data because there is only 1KB on the Arduino Uno) or an external flash memory (there are some modules and libraries for this). When the Arduino is connected, you send over all the data to the cloud.
2. Send the data while data are collected.

In both case, you need an internet connection that could be managed by a wifi module or a GPRS module depending on your needs.

For the wifi module, the ESP8266 is a popular and cheap choice. You will find a lot of documentation on Google.

For the GSM/GPRS module, I suggest the SIM800L which is cheap and easy to use (there is a HTTP/S stack embedded on the module).

# Answer
> 0 votes
Not with a UNO alone, the UNO obviously needs internet connection either via a LAN shield, a Wi-Fi unit (ESP8266) or a GSM unit. Since you are GPS tracking then a GSM unit is most suited.

Particle Electron GPS receiver (Location plotted on Google Map) https://www.brianmoreau.com/projects/particle-electron-gps-receiver/particle-electron-gps-receiver.php

---
Tags: arduino-uno
---