# Question
Title: Using RFID and fingerprint sensor together
I am using both an RFID and a fingerprint sensor in my project. When running the program, the RFID is detected but the fingerprint sensor is not detected and hence my code is not going forward.

Here is my code

```
#include <Adafruit_Fingerprint.h>
#include <SoftwareSerial.h>
#include <MFRC522.h>
#include <SPI.h>

#define SAD 10
#define RST 5

MFRC522 nfc(SAD, RST);

uint8_t id;
uint8_t getFingerprintEnroll();
int getFingerprintIDez();

// pin #2 is IN from sensor (GREEN wire)
// pin #3 is OUT from arduino (WHITE wire)
SoftwareSerial mySerial(2, 3);
Adafruit_Fingerprint finger = Adafruit_Fingerprint(&mySerial);

void setup() {
  SPI.begin();
  Serial.begin(115200);
  Serial.println("Looking for MFRC522.");
  nfc.begin();
  byte version = nfc.getFirmwareVersion();
  if (! version) {
    Serial.print("Didn't find MFRC522 board.");
    while (1); //halt
  }

  Serial.print("Found chip MFRC522 ");
  Serial.print("Firmware ver. 0x");
  Serial.print(version, HEX);
  Serial.println(".");
  Serial.begin(9600);

  Serial.println("Fingerprint and RFID Test");

  finger.begin(57600);
  if (finger.verifyPassword()) {
    Serial.println("Found fingerprint sensor!");
  } else {
    Serial.println("Did not find fingerprint sensor :(");
    while (1);
  }
}

char abc;

void loop() {
  abc = Serial.read();
  switch (abc) {
    case '1': {
      // enroll method
    }
    break ;
    case '2': {
      // verify method
    }
    break;
    case '3': {
      // rfid method
    }
  }
}

```

# Answer
Get rid of the `Serial.begin(9600)`. You're accidentally changing the `Serial` baud rate without doing the same in the serial monitor so you'll probably see gibberish, if anything.
> 2 votes

---
Tags: arduino-uno, adafruit, rfid
---


title: FastLED: "Invalid pin specified"

text:
# Question
Title: FastLED: "Invalid pin specified"
I have an **Adafruit Trinket (5v, 16mhz, based off of the AtTiny85 chip)**, and am wishing to use it with a strip with 24 **3 pin, individually addressable LEDs (WS2812B)**. When I try to compile my code, I get this error: `static_assert(validpin(), "Invalid pin specified");` I've tried using different pins, but of them are seeming to work. What can I do to fix this issue? Here's my current code:

```
#include <FastLED.h>
#define LEDCOUNT 24
#define DATAPIN 0

CRGB leds[LEDCOUNT];

void setup() {
  FastLED.addLeds<WS2812B, LEDCOUNT>(leds, LEDCOUNT);
}

void loop() {
  leds[0] = CRGB::Red;
  FastLED.show();
  delay(30);
}

```

# Answer
> 1 votes
I think what @IgnacioVazquez-Abrams is getting at is:

```
void setup() {
  FastLED.addLeds<WS2812B, LEDCOUNT>(leds, LEDCOUNT);
}

```

Has `LEDCOUNT` showing up for both the number of LEDs and the data pin identifier.

Try:

```
void setup() {
  FastLED.addLeds<WS2812B, DATAPIN, GRB>(leds, LEDCOUNT);
}

```

This puts `DATAPIN` in the right place, and also adds the color order typical for WS2812B, `GRB`

---
Tags: rgb-led, attiny85, compilation-errors
---


# Question
Title: 'DynamicJsonBuffer' was not declared in this scope
I have this code:

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

const char* ssid = "xxxx";
const char* password = "xxxx";

bool a = false;
bool b = true;
int heldVal = 0;

WiFiServer server(80);

void setup () {

  Serial.begin(115200);
  delay(10);

  pinMode(2, INPUT);

  // Connect to WiFi network
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");

  // Start the server
  server.begin();
  Serial.println("Server started");

  // Print the IP address
  Serial.println(WiFi.localIP());
}

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

    // Check if a client has connected
    WiFiClient client = server.available();
    if (!client) {

      HTTPClient http;  //Declare an object of class HTTPClient

      int readVal;
      if (!a) {
        if(b) {
          readVal = digitalRead(2);
        }
      }
      else {
        a = false;
        readVal = heldVal;
      }

      if (readVal == 0)
        http.begin("http://192.168.1.100/gpio/0");  //Specify request destination
      else
        http.begin("http://192.168.1.100/gpio/1");

      int httpCode = http.GET();                                                                  //Send the request

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

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

      }

      http.end();   //Close connection
      return;
    }

    // Wait until the client sends some data
    Serial.println("new client");
    while (!client.available()) {
      delay(1);
    }

    // Read the first line of the request
    String req = client.readStringUntil('\r');
    Serial.println(req);

    // Match the request
    bool toWrite = true;
    if (req.indexOf("/gpio/0") != -1) {
      heldVal = 0;
      b = false;
    }
    else if (req.indexOf("/gpio/1") != -1) {
      heldVal = 1;
      b = true;
    }
    else if (req.indexOf("/mode") != -1) {
      toWrite = false;

      client.flush();

      Serial.println(String(heldVal));
      Serial.println("---in mode request---");

      String input = "{\"mode\":"+String(heldVal)+"}";
      DynamicJsonBuffer jsonBuffer; //----- PROBLEM LINE -----//
      JsonObject& root = jsonBuffer.parseObject(input);

      // Generate the JSON string
      root.printTo(Serial);

      client.println("HTTP/1.1 200 OK");
      client.println("Content-Type: application/json");
      client.println("Connection: close");
      client.println();
      root.printTo(client);
      delay(1);
    }
    else {
      Serial.println("invalid request");
      client.stop();
      return;
    }

    // Set GPIO2 according to the request
    if(toWrite) {
      a = true;

      client.flush();

      // Prepare the response
      String s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\nGPIO is now ";
      s += (heldVal) ? "high" : "low";
      s += "</html>\n";

      // Send the response to the client
      client.print(s);
      delay(1);
      Serial.println("Client disonnected");

      // The client will actually be disconnected
      // when the function returns and 'client' object is detroyed
    }
  }
  else {
    ESP.restart();
  }

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

}

```

I put a comment, `//----- PROBLEM LINE -----//`, next to the problem line above. The error is:

```
/Users/eamonwhite/Documents/Arduino/tempcontrolesp/tempcontrolesp.ino: In function 'void loop()':
tempcontrolesp:110: error: 'DynamicJsonBuffer' was not declared in this scope
       DynamicJsonBuffer jsonBuffer;
       ^
tempcontrolesp:110: error: expected ';' before 'jsonBuffer'
       DynamicJsonBuffer jsonBuffer;
                         ^
tempcontrolesp:111: error: 'JsonObject' was not declared in this scope
       JsonObject& root = jsonBuffer.parseObject(input);
       ^
tempcontrolesp:111: error: 'root' was not declared in this scope
       JsonObject& root = jsonBuffer.parseObject(input);
                   ^
tempcontrolesp:111: error: 'jsonBuffer' was not declared in this scope
       JsonObject& root = jsonBuffer.parseObject(input);
                          ^
exit status 1
'DynamicJsonBuffer' was not declared in this scope

```

I put it just inside the `loop` function and it is still giving the same error:

```
void loop() {
  DynamicJsonBuffer jsonBuffer; //still throws error

```

How is it not being used correctly? Its just a declaration...

# Answer
Did you forget to include the ArduinoJSON header file:

```
#include <ArduinoJson.h>

```
> 4 votes

---
Tags: programming, esp8266, json, compilation-errors
---


# Question
Title: Why does an Arduino Uno have 2 microcontrollers
I was looking at this schematic:

And I noticed that there are 2 microcontrollers (an Atmega328p and a ATmega16U2). I was wondering why there need to be 2 microcontrollers. Do they do different things that only 1 of them can do and the other can't ?

# Answer
Atmega328P is a microcontroller which are the heart of Arduino Uno, where the Atmega8U2 is the USB to serial convertor for arduino communicated with computer.

You can refer to this link for more information about this.
> 4 votes

---
Tags: arduino-uno
---


# Question
Title: Why does the Leonardo take 8 seconds to restart?
My problem is, that my system takes 8 seconds to start the programm after I push the Reset button on my Leonardo. During that period the L-LED is pulsating.

What could be the problem?

# Answer
That's the firmware waiting for a programming connection. If you want alternate behavior them burn SparkFun's ATmega32U4 firmware to it. One press of Reset will reset the device, and two presses will put it into programming mode.
> 4 votes

---
Tags: reset
---


title: Select from Custom Array without Repeat

text:
# Question
Title: Select from Custom Array without Repeat
I found this great code to pick a random number from a "hat" without repeat:

```
/* RandomHat
  Paul Badger 2007 - updated for Teensy compile 2017
  choose one from a hat of n consecutive choices each time through loop
  Choose each number exactly once before reseting and choosing again
*/

#define randomHatStartNum 0  // starting number in hat
#define randomHatEndNum 25    // ending number in hat - end has to be larger than start
#define numberInHat (randomHatEndNum - randomHatStartNum) + 1

void setup()
{
  Serial.begin(9600);
  Serial.println("start ");
}

void loop()
{ // randomHat test
  for (int i = 1; i <= numberInHat; i++) {
    int x = randomHat();
    Serial.print(x);
    Serial.print(", ");
    delay(50);
  }
  Serial.println(" ");
}

int randomHat() {
  int thePick;    //this is the return variable with the random number from the pool
  int theIndex;
  static int currentNumInHat = 0;
  static int randArray[numberInHat];

  if  (currentNumInHat == 0) {                  // hat is emply - all have been choosen - fill up array again
    for (int i = 0 ; i < numberInHat; i++) {    // Put 1 TO numberInHat in array - starting at address 0.
      if (randomHatStartNum < randomHatEndNum) {
        randArray[i] = randomHatStartNum + i;
      }
    }
    currentNumInHat = abs(randomHatEndNum - randomHatStartNum) + 1;   // reset current Number in Hat
    Serial.print(" hat is empty ");
    // if something should happen when the hat is empty do it here
  }

  theIndex = random(currentNumInHat);                  //choose a random index from number in hat
  thePick = randArray[theIndex];
  randArray[theIndex] =  randArray[currentNumInHat - 1]; // copy the last element in the array into the the empty slot
  //                                                     // as the the draw is random this works fine, and is faster
  //                                                     // the previous version. - from a reader suggestion on this page
  currentNumInHat--;    // decrement number in hat
  return thePick;
}

```

I would like to use a custom array to choose from like so:

```
char *things[]={
"Thing 1",
"Thing 2",
"Thing 3",
"Thing 4",
"Thing 5",
"Thing 6",
};

```

Which is quite possible as I use the numbers from to first piece of code to select items from my custom array.

So I have two questions about this:

The first being the code first returns "hat is empty" before the numbers.

```
start
  hat is empty 11, 24, 17, .......
  hat is empty 4, 19, 23, .......

```

Is there a way to reverse this?

And secondly, I would like define the `randomHatEndNum` automatic by the lenght of my custom array, but I have trouble implementing that code. What is the right way to approach this?

# Answer
> 1 votes
> The first being the code first returns "hat is empty" before the numbers.

Well, you have to comment out the line

```
Serial.print(" hat is empty ");

```

> I would like define the randomHatEndNum automatic by the lenght of my custom array,

To get the size of an array, the standard idiom is

```
const int numberInHat = sizeof(things) / sizeof(things[0]);

```

I rewrote your sketch.

The idea is use randArray to store all the remaining values to return. Then, randomly pick one value (to return) and replace randArray with -1, which signal that the value has been returned, so don't return it again.

The best for functions returning random values is always work in the range 0..n, and adjust that value in the calling code if you need some other range (like 1..n+1). It's simplier and simplify debugging.

```
/* RandomHat
  Paul Badger 2007 - updated for Teensy compile 2017
  choose one from a hat of n consecutive choices each time through loop
  Choose each number exactly once before reseting and choosing again
*/

char *things[]={
"Thing 0",
"Thing 1",
"Thing 2",
"Thing 3",
"Thing 4",
"Thing 5",
"Thing 6",
};

const int numberInHat = sizeof(things) / sizeof(things[0]);

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

void loop()
{ // randomHat test
  for (int i = 0; i < numberInHat; i++) {
    int x = randomHat();
    Serial.print(x); Serial.print(" ");
    Serial.println(things[x]);
    delay(50);
  }
  Serial.println("----");
}

int randomHat() {
  int thePick = -1;    //this is the return variable with the random number from the pool
  int theIndex;
  static int left = 0;
  static int randArray[numberInHat];

  if  (left == 0) {                                // hat is emply - all have been choosen - fill up array again
    for (int i = 0 ; i < numberInHat; i++) {    // Put {0, ..., n} into randArray.
        randArray[i] = i;
      }
    left = numberInHat;
  }

  // bEmpty always false at this point.
  while (thePick == -1) {
    theIndex = random(numberInHat);                  //choose a random index from number in hat
    thePick = randArray[theIndex];
   }

  left--;
  randArray[theIndex] =  -1;        // value theIndex is not longer available.
  return thePick;
}

```

---
Tags: programming, string, array, code-review
---


# Question
Title: error using String class to convert a double to a string
i wanted to convert a double to a string i tested several examples online i allawys get the same error.

the code :

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

}
void loop()
{
  double val =3.2222;
  String stringOne =  String(val, 3);
  Serial.print(stringOne);
}

```

the errors :

```
sketch_jun02c.ino: In function ‘void loop()’:
sketch_jun02c.ino:10:36: error: call of overloaded ‘String(double&, int)’ is ambiguous
sketch_jun02c.ino:10:36: note: candidates are:
In file included from /usr/share/arduino/hardware/arduino/cores/arduino/Arduino.h:192:0,
                 from sketch_jun02c.ino:2:
/usr/share/arduino/hardware/arduino/cores/arduino/WString.h:70:11: note: String::String(long unsigned int, unsigned char)
  explicit String(unsigned long, unsigned char base=10);
           ^
/usr/share/arduino/hardware/arduino/cores/arduino/WString.h:69:11: note: String::String(long int, unsigned char)
  explicit String(long, unsigned char base=10);
           ^
/usr/share/arduino/hardware/arduino/cores/arduino/WString.h:68:11: note: String::String(unsigned int, unsigned char)
  explicit String(unsigned int, unsigned char base=10);
           ^
/usr/share/arduino/hardware/arduino/cores/arduino/WString.h:67:11: note: String::String(int, unsigned char)
  explicit String(int, unsigned char base=10);
           ^
/usr/share/arduino/hardware/arduino/cores/arduino/WString.h:66:11: note: String::String(unsigned char, unsigned char)
  explicit String(unsigned char, unsigned char base=10);
           ^

```

# Answer
> 0 votes
I had installed arduino using apt-get and I didnt notice that I had an old version. I upgraded my arduino and it worked fine.

---
Tags: string, code-review, compilation-errors
---


title: Arduino Micro Interrupt

text:
# Question
Title: Arduino Micro Interrupt
I have built a custom Arduino Micro PCB, but I have made a mistake, I accidentally attached an interrupt pin for a Gyro sensor to pin 12 of the Micro, not realizing it wasn't an external interrupt pin.

I tried using the interrupt pin change command found on the Arduino website, but I am having some trouble getting it working. If there is a way to make pin 12 on the Arduino Micro an Interrupt pin, how would I go about doing that in the simplest way.

# Answer
> If there is a way to make pin 12 on the Arduino Micro an Interrupt pin

you should take a look at the device datasheet and see what other functionalities pin 12 has.

if it is a pcint pin, you are golden; if it is a timer input pin or an input capture pin, they can be programmed to act like an interrupt pin as well.

all begins with reading the datasheet.
> 1 votes

# Answer
this library will let you attach a function to a pin using pin-change-interrupt, api is quite simple

https://github.com/neu-rah/PCINT#api

Arduino pin change interrupt library compatible with AVR and SAM with consistent interface.

Allows handlers to be called with a predefined cargo (void\*) for user data or just regular void returning functions with no params.

This library use meta-programing to achieve consistency.

**Example**

```
#include <pcint.h>

#define led 13
#define btn 12

void setled() {
  digitalWrite(led,digitalRead(btn));
}

void setup() {
  pinMode(led,OUTPUT);
  pinMode(btn,INPUT_PULLUP);
  PCattachInterrupt<btn>(setled,CHANGE);
  setled();//initial led status
}

void loop() {}

```

**API**

Just two methods:

```
void PCattachInterrupt<pin>(userFunc,mode);
void PCdetachInterrupt<pin>();

```
> 0 votes

---
Tags: interrupt, mpu6050
---


# Question
Title: Voice recognition without module, is it possible?
I'm trying to figure out how to process a voice signal for simple purposes. Wherever I look people using or suggesting recognition modules for Arduino.

What I'm wondering: is this possible to make a simple command recognition with Arduino, without modules?

I just simply want to attach a microphone to my Arduino and after I convert it I want to handle signal and program it in MATLAB or in an Arduino itself. How can I achieve that?

As you can see I'm newbie in this. Any help is appreciated. Thanks!

# Answer
No, it's not possible. The Arduino is not powerful enough to run the algorithms needed.

You need something with far more processing power, memory and storage. Something like a Raspberry Pi, maybe, or a desktop PC.

Or just use one of the many commonly available VR modules you can buy on the internet for next to nothing.
> 0 votes

# Answer
Sadly, that's never an easy thing to do as it seems like. I have tried with microphone , amplifier, ADC , and an EEPROM to store patterns of voltage produced by a human voice for different people. But it looked unreliable in the end. EasyVR is a popular voice recognition module usually used with UNO.
> 0 votes

---
Tags: arduino-uno, arduino-nano, sound, signal-processing
---


# Question
Title: On/off button for Arduino Mega for 5V input pin- hardware based auto on/off arduino(PUSHBUTTON NOT AS INTERRUPT)
I am working on Arduino Mega project where I want to add a PUSHBUTTON (Any other can be suggested) that will be programmed in my arduino code, such that if I would press the button arduino code should stop working and when I will press the button back the code should resume from the moment where it stopped. Button will be attached to 5v pin so that will turn off/on the arduino.

# Answer
Your question is very badly written, and a lot of infos are missing. In any case, from what I understood from your comments, you want a button that works this way:

* The arduino is not powered up
* You press the button; the arduino turns on, and starts the operations.
* You press the button; the arduino shuts down.
* You press the button; the arduino turns on, and resumes the operations from where it was.

I'm not sure about the last point, so first of all I'll give you some hints about the first three points.

You can modify the circuit in a way similar to this:

simulate this circuit – Schematic created using CircuitLab

(I named the two arduino pins as A and B because it is not important which pins you use, just two separate pins).

The diodes can be any diode (e.g. 1N4148). The PMOS and NMOS are not critical, provided that they can fully turn on with a 4-5V gate voltage and that the PMOS can bear the current you need.

When the arduino is shut down, the NMOS is off, and so is the PMOS. When you press the button, the voltage on the NMOS gate becomes about 4.5V, so it turns on. the PMOS turns on too, and so the arduino sees some power. At the very first moment, it has to pull pin B to 5V. This way even when the button is not pressed anymore, the board will be powered. When the user presses the button, the arduino can sense it through pin A. This way it can go into shutdown mode. Here is a sort of base for handling this behavior. Please note that I'm using the Bounce2 library, since I particularly like it when dealing with buttons (it automagically handles bounces and also give more info about the edges).

```
#include <Bounce2.h>

const byte pinA = the pin A number;
const byte pinB = the pin B number;

Bounce pinA_debounced = Bounce();

void shutdown() {
    // Turn off the board
    digitalWrite(pinB, LOW);
    // Farewell, cruel world!
    while(1); // wait for a power off
}

void setup() {
    // Turn on the board
    pinMode(pinB,OUTPUT);
    digitalWrite(pinB, HIGH);

    // Initializate the debounced pin
    pinA_debounced.attach(pinA, INPUT_PULLUP);

    // Other setup instructions
}

void loop() {
    // Update the Bounce instance :
    pinA_debounced.update();

    if (pinA_debounced.rose())
        shutdown();

    // Other loop instructions
}

```

If you want to save your data in order to resume it, well, this highly depends on your actual code. You will have to identify what is your "current status", then save it to EEPROM.

Here is, for instance, a program which outputs on serial one sequential number (from 0 to 254, then restart from 0) every second. When you shut it down, it will start again from the last one:

```
#include <Bounce2.h>

const byte pinA = the pin A number;
const byte pinB = the pin B number;

const byte valueAddress = 0x10; // Any value is fine for this
// as long as it is in the available EEPROM

Bounce pinA_debounced = Bounce();
byte value;
unsigned long lastMillis;

void shutdown() {
    // Save status BEFORE turning down the power
    EEPROM.update(valueAddress, value);

    // Turn off the board
    digitalWrite(pinB, LOW);
    // Farewell, cruel world!
    while(1); // wait for a power off
}

void setup() {
    // Turn on the board
    pinMode(pinB,OUTPUT);
    digitalWrite(pinB, HIGH);

    // Initializate the debounced pin
    pinA_debounced.attach(pinA, INPUT_PULLUP);

    // Restore the current value from EEPROM
    value = EEPROM.read(valueAddress);
    Serial.begin(9600);
    lastMillis = millis() - 1000;
}

void loop() {
    // Update the Bounce instance :
    pinA_debounced.update();

    if (pinA_debounced.rose())
        shutdown();

    if ((millis() - lastMillis) >= 1000)
    {
        lastMillis += 1000;
        Serial.println(value);
        value++;
    }
}

```
> 3 votes

# Answer
If you rewrite the code to be a state machine so that `loop()` never blocks it's pretty easy to add:

```
bool paused = false;
void loop(){
    //read button
    if(buttonPressed){
        paused = !paused;
    }
    if(paused){
        return;
    }
    //rest of code written so it never blocks and returns as fast as possible
}

```

Then the resume part is handled by the extra already required by needing to be able resume on next call of loop.

If you go for full power off then you need to write out your state to non-volatile memory and read it back in on init.
> 1 votes

# Answer
> if I would press the button arduino code should stop working and when I will press the button back the code should resume from the moment where it stopped.

the simplest would be use an interrupt trigger by the button to set a flag and the execution would either loop around the flag or go straight through, depending on the state of the flag.
> -1 votes

---
Tags: arduino-mega
---


# Question
Title: I2C Packet ocasionally send a garbage data
I have a project with Arduino working as I2C slave. The master request data each 300ms.

The code of Arduino is:

```
/*
  Name:     SimpleClass_Applcation.ino
  Created:  5/26/2017 4:18:28 PM
  Author:   Felipe Fonseca
  Description: Versão de Código para o Trocador de Calor de forma a simplificar
  a operçãoo para tornar possível a utilização em aulas
*/

//includes

//Libs dos sensores
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Ultrasonic.h>

//display lcd
#include <LiquidCrystal.h>

//timed action
//#include <Utility.h>
//#include <TimedAction.h>

//lib i2c
#include <Wire.h>

//gerar sinais
#include <waveforms.h>

//Pinos de entrada e sa�da

#define but1 A1  //no programa de testes 42; no original, trocar por A1  //
#define but2 A2  //no programa de testes 44; no original trocar por A2
#define pot A0 //no programa de testes A7; no original trocar por A0

#define mode_switch 42  //no programa de testes 43; no original trocar por 42
#define emergency_button 43 //no programa de testes 51; no original  trocar por 43

#define ultrassonico_echo   50      //no original trocar para 50
#define ultrassonico_trigger 48     //no original trocar para 48
#define ONE_WIRE_BUS 52             //no original trocar para 52  - terminal do conjunto de sensores
#define hf_sensor 9                //no original trocar para 9 -> pino de interrup��o para calculo da vaz�o agua fria
#define TEMPERATURE_PRECISION 12

#define led1 44                  // utilizado para sinalização geral
#define led2 45                  // utilizado para sinalização geral
#define led_heater 47            // no programa de testes 37; no original trocar para 47

#define inversor_rele 49        //no programa de teste 47;no original trocar para 49
#define heater_rele 10          //no programa de testes 49;no original trocar para 10

#define MAX_MENU_ITENS 2         //numero de telas no menu

//testes em prototipo
#define LDR_PIN A3
#define LM35_PIN A4
#define RXLED 3
#define oneHzSample 1000000/maxSamplesNum //gerador de sinais
#define SIMULATORSAMPLETIME 500

float LM35_value;
float LDR_value;

//vari�veis internas

//armazenar valores de entrada
bool switch_state;
int pot_value;
bool emergency_status;

volatile int pump_onoff;
volatile int heater_onoff;
volatile float remote_pumpspeed;

float temp[4];
double vazao_quente;
float vazao_fria;
volatile int flow_frequency;

//estrutura de dados para envio i2c
typedef struct processData {
  float temp1;
  float temp2;
  float temp3;
  float temp4;
  float hotflow;
  float coldflow;
  float pump_speed;
  byte bstatus;
  byte chksum;
};

typedef union I2C_Send { //compartilha a mesma área de memória
  processData data;
  byte I2C_packet[sizeof(processData)];
};

I2C_Send send_info;
int command; //processar o indice de comando enviado pelo Rpi

//array de bytes auxilar para receber a velocidade da bomba
byte data[4];

//estrutura para receber um float para alterar velocidade
typedef union PumpDataSpeed {
  float fspeed;
  byte bspeed[4];
};

//variáveis utilizadas no calculo de vazao de agua fria/quente
unsigned long currentTime;
unsigned long cloopTime;
long microsec;
float cmMsec;
float nivel;
//float vazao1_sf;   //se for necessário para a função de vazao quente, descomentar

//variáveis auxiliares para operação local
char flag_button1 = 0x00;
char flag_button2 = 0x00;
char flag_emergency = 0x00;
String mode = "";

//variáveis auxiliares para comando
float pot_value_mapped;

//variáveis para o simulador
unsigned long current_sim_time;
unsigned long simulator_time_elapsed;
int indexwave;

//inicialização de objetos
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
DeviceAddress deviceID[] =
{
  { 0x28, 0xFF, 0x46, 0x02, 0x54, 0x16, 0x04, 0xF8 },
  { 0x28, 0xFF, 0xD3, 0xE6, 0x53, 0x16, 0x04, 0xA0 },
  { 0x28, 0xFF, 0xE8, 0xF0, 0x53, 0x16, 0x04, 0x65 },
  { 0x28, 0x1D, 0x9D, 0x27, 0x00, 0x00, 0x80, 0x2E }
};
//delay necessário para leitura dos sensores. Depende da resolução
int delayTempRead = 0;
int lastTempRequest = millis();

Ultrasonic ultrasonic(ultrassonico_trigger, ultrassonico_echo);

LiquidCrystal lcd(41, 11, 12, 40, 13, 38);  //no original deve-se utilizar  LiquidCrystal lcd(41, 11, 12, 40, 13, 38);

//funções
void ReadPotentiometer();
float mapfloat(float x, float in_min, float in_max, float out_min, float out_max);

//funções de navegação  - Display LCD
void Menu(int op);
void EmergencyStatus();

//funções de leitura de grandezes
void flow();                //função de interrupção para o calculo de vazao de água fria
void PumpSpeed(float ref);  //função para alterar a velocidade da bomba
void VazaoAguaFria();       //função para calcular a vazão de água fria
void VazaoAguaQuente();     //função para calcular a vazão de água quente
void Temperaturas();        //função para calcular as temperaturas dos sensores
void new_Temperaturas();

//funções do estado do arduino
void LocalState();
void RemoteState();
void emergencia();

//funções para fazerem a leitura periodica dos valores analógicos
void runReads();
void refresh_I2C_Packet();

//função para receber o valor em bytes via i2c e retornar a velocidade em float
void parseSpeed(byte data[]);

//testes em prototipo
void Temperaturas2();
void Simulator();

// the setup function runs once when you press reset or power the board
void setup() {
  //painel
  pinMode(but1, INPUT_PULLUP);
  pinMode(but2, INPUT_PULLUP);
  pinMode(pot, INPUT);
  pinMode(mode_switch, INPUT);
  pinMode(emergency_button, INPUT);
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led_heater, OUTPUT);

  //sensores
  pinMode(ultrassonico_echo, INPUT);
  pinMode(ultrassonico_trigger, OUTPUT);
  pinMode(hf_sensor, INPUT_PULLUP);
  pinMode(ONE_WIRE_BUS, INPUT_PULLUP);

  //reles
  pinMode(heater_rele, OUTPUT);
  pinMode(inversor_rele, OUTPUT);

  //começar inversor desligado
  digitalWrite(inversor_rele, HIGH);

  //habilitar a interrupção para medição de vazão fria
  //attachInterrupt(hf_sensor, flow, RISING);

  //iniciar sensores de temperatura
  sensors.begin();
  for (byte i = 0; i <= 4; i++) {
    sensors.setResolution(deviceID[i], TEMPERATURE_PRECISION);
  }
  //modo de leitura assincrona
  //sensors.setWaitForConversion(false);
  delayTempRead = 750 / (1 << (12 - TEMPERATURE_PRECISION));

  //iniciar lcd
  lcd.begin(20, 4); //no original utilizar 20,4

  //resolução de escrita do DAC
  analogWriteResolution(10);

  //variáveis que guarda o status da bomba e do aquecedor
  pump_onoff = 0;
  heater_onoff = 0;

  //inicialização da serial
  Serial.begin(115200);

  //inicialização de variáveis
  vazao_fria = 0;
  vazao_quente = 0;

  //inicialização da estrutura i2c
  send_info.data.chksum = 27;
  Wire.begin(12); //arduino iniciado no endereço 12
  Wire.onReceive(receiveEvent); //callback para recebimento de comandos
  Wire.onRequest(requestEvent); //callback para responder à requisições

  //semente para o simulador
  randomSeed(analogRead(LM35_PIN));
  indexwave = 0;
}

// the loop function runs over and over again until power down or reset
void loop() {

  // le o estado da chave
  switch_state = digitalRead(mode_switch);

  /* lê se o botão de emergencia está acionado ou não
      cobre os casos de pressionar o botão e despressionar o botão
  */
  if (digitalRead(emergency_button) == LOW) { //presisonado botão
    emergencia();
  }
  else if (!digitalRead(emergency_button) == LOW && flag_emergency) { //despressionado o botão
    flag_emergency = 0x00;
    emergency_status = 0;
    lcd.clear();
    if (switch_state) {
      RemoteState();
    }
    else {
      LocalState();
    }
  }
  else { //tudo normal
    if (switch_state) {
      RemoteState();
    }
    else {
      LocalState();
    }
  }
}

//função de interrupção para calcular a vazão
/*void flow() {
  flow_frequency++;
}*/

//funções que gerenciam o estado do arduino

void LocalState() {

  //efetua a leitura das grandezas
  runReads();

  //atualiza o lcd com os novos valores
  Menu(0);

  if (!digitalRead(but1)) flag_button1 = 0x01;
  if (!digitalRead(but2)) flag_button2 = 0x01;

  if (digitalRead(but1) && flag_button1) {
    flag_button1 = 0x00;
    //troca o estado da bomba
    digitalWrite(inversor_rele, pump_onoff);  //o estado da bomba � invertido
    //digitalWrite(led_pump, !pump_onoff);  -> N�o � para utilizar o led
    pump_onoff = !pump_onoff;
  }

  if (digitalRead(but2) && flag_button2) {
    flag_button2 = 0x00;
    //troca o estado do aquecedor
    digitalWrite(heater_rele, !heater_onoff);
    digitalWrite(led_heater, !heater_onoff);
    heater_onoff = !heater_onoff;
  }

  //controlar a velocidade da bomba
  ReadPotentiometer();
  PumpSpeed(pot_value_mapped);

  //enquanto modo local, a variável remote_pumpspeed deve ser atualizada para quando
  //ocorrer a mudança para o modo remoto, por exemplo, as informações sejam corretas
  remote_pumpspeed = pot_value_mapped;

  //atualiza a estrutura de envio de dados via i2c
  refresh_I2C_Packet();
}

void RemoteState() {
  //faz a leitura das variáveis
  runReads();

  //atualiza o lcd com os novos valores
  Menu(1);

  //atualiza a estrutura de envio de dados via i2c
  refresh_I2C_Packet();
}

void emergencia() {
  //digitalWrite(led_flow_mode, LOW);//Apaga LED 1
  digitalWrite(led_heater, LOW);//Apaga LED 2
  digitalWrite(inversor_rele, HIGH);//Desliga a bomba
  digitalWrite(heater_rele, LOW);//Desliga o aquecedor

  //atualiza variável de emergência
  emergency_status = 1;

  //vari�veis auxiliares
  pump_onoff = 0x00;
  heater_onoff = 0x00;
  remote_pumpspeed = 0.0;

  //para evitar blinkar o lcd
  if (!flag_emergency) {
    lcd.clear();
    EmergencyStatus();
  }
  flag_emergency = 0x01;
}

//funções para gerenciar a exibição do lcd

void EmergencyStatus() {
  lcd.setCursor(0, 0);
  lcd.print("Emergencia");
  lcd.setCursor(0, 1);
  lcd.print("Comandos");
  lcd.setCursor(0, 2);
  lcd.print("Bloqueados");
}

void Menu(int op) {

  mode = (op == 1) ? "Remote Mode" : "Local  Mode";

  lcd.setCursor(0, 0);
  lcd.print(mode);

  lcd.setCursor(0, 1);
  lcd.print("TA: ");
  lcd.print(temp[0]);
  lcd.print("  ");
  lcd.print("TB: ");
  lcd.print(temp[1]);

  lcd.setCursor(0, 2);
  lcd.print("TC: ");
  lcd.print(temp[2]);
  lcd.print("  ");
  lcd.print("TD: ");
  lcd.print(temp[3]);

  lcd.setCursor(0, 3);
  lcd.print("V1: ");
  lcd.print(vazao_quente);
  lcd.print("  ");
  lcd.print("V2: ");
  lcd.print(vazao_fria);

}

//funções de leitura (e escrita) das grandezas

void Temperaturas() {

  // call sensors.requestTemperatures() to issue a global temperature
  // request to all devices on the bus

  sensors.requestTemperatures();

  // print the device information
  for (byte i = 0; i <= 4; i++)
  {
    temp[i] = sensors.getTempC(deviceID[i]);
  }
}

void new_Temperaturas(){
  if(millis() - lastTempRequest > delayTempRead){
    for (byte i = 0; i <= 4; i++)
    {
      temp[i] = sensors.getTempC(deviceID[i]);
    }
  }
  lastTempRequest = millis();
  sensors.requestTemperatures();
}

void VazaoAguaFria() {
  currentTime = millis();
  // Every second, calculate litres/hour
  if (currentTime >= (cloopTime + 1000))
  {
    cloopTime = currentTime; // Updates cloopTime
    // Pulse frequency (Hz) = 7.5Q, Q is flow rate in L/min.
    vazao_fria = (flow_frequency / 7.5); // (Pulse frequency) / 7.5Q = flowrate in L/min
    flow_frequency = 0; // Reset Counter
  }
}

void VazaoAguaQuente() {

  float vazao1_sf; //descobrir o porquê do nome da variavel

  microsec = ultrasonic.timing();
  cmMsec = ultrasonic.convert(microsec, Ultrasonic::CM);
  nivel = 11.46 - cmMsec;
  vazao1_sf = (0.0537) * pow((nivel * 10), 1.4727);
  if (vazao1_sf > 1) {
    vazao_quente = 0.75 * vazao_quente + 0.25 * vazao1_sf;
  }
}

void Temperaturas2() {
  LM35_value = analogRead(LM35_PIN) * 0.48875855;
  LDR_value = analogRead(LDR_PIN) / 10.0;
  temp[0] = LM35_value;
  temp[1] = LDR_value;
}

void Simulator() {
  current_sim_time = millis();
  if (current_sim_time >= simulator_time_elapsed + SIMULATORSAMPLETIME) {

    simulator_time_elapsed = current_sim_time;

    for (int i = 0; i < 3; ++i) {
      temp[i] = mapfloat(random(1024), 0, 1023, 10, 50);
    }

    //ultima temperatura com valor senoidal
    temp[3] = mapfloat(waveformsTable[0][indexwave], 0, 4095, 0, 100);
    indexwave++;
    if (indexwave == maxSamplesNum) {
      indexwave = 0;// Reset the counter to repeat the wave
    }

    vazao_quente = mapfloat(random(1024), 0, 1023, 0, 30);
    vazao_fria = mapfloat(random(1024), 0, 1023, 0, 30);
  }
}

void PumpSpeed(float ref) {
  if (ref > 100)
    ref = 100;
  else if (ref < 0)
    ref = 0;
  analogWrite(DAC0, ref * 9.43 + 80);
}

void ReadPotentiometer() {
  pot_value = analogRead(pot);
  pot_value_mapped = mapfloat(pot_value, 0, 1023, 0, 100);
}

void runReads() {

    //Temperaturas();
    //VazaoAguaFria();
    //VazaoAguaQuente();
    //new_Temperaturas();

  //Temperaturas2();
  Simulator();
}

//funções callback do i2c
void receiveEvent(int Nbytes) {
  command = Wire.read();

  switch (command) {
    case 49: //comando de teste
      //comando liga bomba
      digitalWrite(inversor_rele, LOW); //o estado da bomba é invertido
      pump_onoff = 1;
      break;

    case 50:
      //comando desliga bomba
      digitalWrite(inversor_rele, HIGH);
      pump_onoff = 0;
      break;

    case 51:
      //comando liga aquecedor
      digitalWrite(heater_rele, HIGH);
      digitalWrite(led_heater, HIGH);
      heater_onoff = 1;
      break;

    case 52:
      //comando desliga aquecedor
      digitalWrite(heater_rele, LOW);
      digitalWrite(led_heater, LOW);
      heater_onoff = 0;
      break;

    case 53:
      //comando alterar velocidade da bomba
      int i = 0;
      while (Wire.available()) {
        data[i] = Wire.read();
        i = i + 1;
      }
      parseSpeed(data);
      break;
  }
}

void requestEvent() {
  if (command == 54) {
    Wire.write(send_info.I2C_packet, sizeof(processData));
  }
}

void parseSpeed(byte data[]) {
  //o primeiro byte é o número de bytes do envio; deve-se ignorar
  PumpDataSpeed speed;
  speed.bspeed[0] = data[1];
  speed.bspeed[1] = data[2];
  speed.bspeed[2] = data[3];
  speed.bspeed[3] = data[4];
  //Serial.println(speed.fspeed);
  remote_pumpspeed = speed.fspeed;
  PumpSpeed(remote_pumpspeed); //envia o comando de velocidade para a bomba fisicamente
}

void refresh_I2C_Packet() {
  send_info.data.temp1 = temp[0];
  send_info.data.temp2 = temp[1];
  send_info.data.temp3 = temp[2];
  send_info.data.temp4 = temp[3];

  //se a bomba estiver desligada, ignorar o valor do potenciometro
  if (pump_onoff) {
    if (switch_state) {
      send_info.data.pump_speed = remote_pumpspeed;
    }
    else {
      send_info.data.pump_speed = pot_value_mapped;
    }
  }
  else {
    send_info.data.pump_speed = 0.0;
  }

  send_info.data.hotflow = vazao_quente;
  send_info.data.coldflow = vazao_fria;
  bitWrite(send_info.data.bstatus, 0, pump_onoff);
  bitWrite(send_info.data.bstatus, 1, heater_onoff);
  bitWrite(send_info.data.bstatus, 2, switch_state);
  bitWrite(send_info.data.bstatus, 3, emergency_status);
}

float mapfloat(float x, float in_min, float in_max, float out_min, float out_max) {
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

```

https://github.com/felipefonsecabh/ArduinoCode/blob/ArduinoNoNavigation/ArduinoCode.ino

My problem is ocasionally i'm receiving in master a crazy data. For example:

```
Normal block data
[0, 0, 9, 66, 0, 192, 6, 66, 0, 128, 207, 65, 0, 0, 208, 65, 52, 171, 33, 64, 102, 102, 166, 64, 0, 0, 0, 0, 4, 27]

Crazy data
[120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120]

```

Any ideas?

Thanks a lot!

# Answer
I have seen this exact same problem, and it took me quite a while to track down the answer.

The I2C protocol is a very raw protocol that is inexpensive to implement, but is very susceptible to noise on the bus. When I put the SCL and SDA lines on my oscilloscope, I saw that occasionally there were spikes of high frequency noise on both lines. These turned out to be EMF noise. Most of the spikes were rejected by glitch filters on the master and slave chips, but occasionally the spikes lasted too long for the glitch filters, and were then read as data or as clock pulses.

When this happens, the master and the slave get out of sync, often resulting in the slave holding SDA low while awaiting a clock pulse, while the master is waiting for the slave to release SDA so it can send a final NAK.

I2C has no concept of a timeout, so this state will last forever unless you detect it and force a resolution.

In the meantime, your sensor library does not check for Wire errors (it has no way of doing so) so it is returning invalid data.

When you see the invalid data, you can try to recover by temporarily taking control of the SCL and SDA pins yourself and toggling them as follows:

* Pulse the clock 9 times to force any slave that was sending data to finish sending the current byte, at which point it will release the SDA line. When SDA goes high, the slave will see the next clock pulse as a NAK, so it will stop sending any more bytes. Any leftover clock pulses won't have any START marker, so will be ignored by the slaves.
* Then send a STOP condition (take CLK low, then take SDA low, then take CLK high, and finally allow SDA to transition low-\> high while CLK is high. All masters and slaves on the bus should now be OK again.

Another failure mode can occur in which the slave believes it has received a WRITE command, and it may write to addresses that can put it into an unknown state. To recover from that state, first do the pulsing as above, and then just stop and restart that sensor using library calls.

Finally, there is a failure mode in which the master thinks another master has control of the bus. To recover from that state, first issue the pulses as above, then stop and restart Wire, and then stop and restart any frozen sensors.

It would be nice if all this functionality were in the Wire library, but as of today that's not the case so you'll have to do it yourself. Fortunately that's not too difficult -- it's only a dozen lines of code.

Good luck!
> 1 votes

---
Tags: i2c, arduino-due, code-review, serial-data
---


# Question
Title: How do I add dimming control to my following LED toggling program on Arduino? Also how do I improve my existing code?
I am attaching my code below :

```
int cwled=9;
int wwled=10;
int button=8;
int buttonpress;
long startTime=0;
long endTime;
long holdTime;
boolean previous = LOW;
boolean current;
int state=0;
int pot = A0;
boolean cwState = HIGH;
boolean wwState = LOW;
int brightness;
int counter = 1;
boolean pressB;

void setup(){
  pinMode(cwled,OUTPUT);
  pinMode(wwled,OUTPUT);
  pinMode(button,INPUT);
  Serial.begin(9600);

}

void loop() {
  if(state == 0){
    brightness= map(analogRead(pot),0,1023, 0, 255);
        analogWrite(cwled,brightness);
       // analogWrite(wwled,0);
        Serial.println("Initialized");
  }
  current= digitalRead(button);
  if(current == HIGH){
  pressDetection();
  state =1;
  }
}

void pressDetection(){
  pressB=digitalRead(button);
  if(pressB==HIGH && previous == LOW)
  {
    state =1;
    startTime = millis();
  }
  while(digitalRead(button) == HIGH){
    endTime = millis();
    Serial.println("Inside loop");
  }
  previous = LOW;
  holdTime = endTime - startTime;
  if(holdTime> 500){
    longPress();
  }
  else{
    shortPress();
  }

  }

void shortPress(){
  cwState = !cwState;
  wwState = !wwState;
  //brightness= map(analogRead(pot),0,1023, 0, 255);
  if(cwState == HIGH && wwState == LOW){
   brightness= map(analogRead(pot),0,1023, 0, 255);
   digitalWrite(cwled,HIGH);
   digitalWrite(wwled,LOW);
   Serial.println("cwState");
   return;
  }
  if(cwState == LOW && wwState == HIGH){
  // brightness= map(analogRead(pot),0,1023, 0, 255);
   digitalWrite(wwled,HIGH);
   digitalWrite(cwled,LOW);
   Serial.println("wwState");
   return;
  }
 /*else if(cwState == HIGH && wwState == HIGH){
   //brightness= map(analogRead(pot),0,1023, 0, 255);
   digitalWrite(cwled,HIGH);
   digitalWrite(wwled,LOW);
  }*/
}

void longPress(){

   cwState =wwState = HIGH;

   //if(cwState == HIGH && wwState == HIGH){
 //  brightness= map(analogRead(pot),0,1023, 0, 255);
   digitalWrite(wwled,HIGH);
   digitalWrite(cwled,HIGH);
  cwState = !cwState;

 //}

}

```

I understand there are so many variables unused, this program needs a lot of improvising. My question is:

1. How do I improve this code?
2. How do I add dimming via pwm in this code?
3. And if I have to add one more type of LED or say n number of LEDs and want to toggle between them what should be the algorithm.

My aim is to use a push button to switch between different types of LEDs (in my case between warmwhite LED and coldwhite LED, if Arduino registers long press off the push button all the LEDs light up, in my case both warmwhite and coldwhite LEDs turn on, and short press of push button toggles between warmwhite and coldwhite LED. The program by default switches on coldwhite LED first and after a long press, shortpress sets default LED to high which is coldwhite.

I am not a hardcore programmer but I have more than basic knowledge of OOPS programming. I am an ECE Engineer and I believe I have slightly more than basic understanding of OOPS and procedural programming. I am aware of C++, C and JAVA only. Any advice or help would be highly appreciated.

# Answer
**How do you improve your code?**

Firstly there is nothing disastrously wrong with you code, it could do with a polish, but who's code couldn't?

In the dim and very distant past I was told "you write code once but read it many times" so try and make your code readable and clear.

1. If the values aren't going to change then they should be constants or #defines.
2. ***ALWAYS*** initialise variables. (Doesn't matter on an Arduino because the compiler does it for you, but its good practice).
3. Boolean should be true or false.
4. You are writing C/C++ not Java. Opening braces { should be on a new line. It makes the code easier to read and match up the braces.
5. Unless your space bar is broken, put spaces after commas and either side of equals.
6. Using function parameters and less global variables will make you code more reusable. Imagine the day when you start a new project and copy and paste functions from previous projects and finish the code in 15 minutes.
7. One statement per line. `cwState = wwState = HIGH;`. In this case its not a problem, but you can get into states where side affects screw everything up. Also its easier to read.
8. Comment the code as you go, because you'll never go back.
9. Explain what each function does, because you'll have forgot by tomorrow.

I hope that helps you write better code and none of it has caused offence.
> 2 votes

# Answer
Putting aside the long press vs. short press, alternating the pwm generation is fairly simple.

1. Use an adc interrupt to periodically read the pot and update a variable that holds the duty cycle.
2. Use an interrupt to track the button input. In the isr, use a static variable to track which pwm pulse train is running. Upon button presses, update the variable and then use it to steer pwm output.

With this structure, your loop() is entirely empty and the functionalities (reading the pot, pwm generation and output steering) is done entirely in the background.

As to the long pushes, you can use a timer to track the button hold time and it returns not just the state of the button but also long vs. short presses.
> 0 votes

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


title: SIM800 gsm Module returns 0 on AT+COPS?

text:
# Question
Title: SIM800 gsm Module returns 0 on AT+COPS?
I am using SIM800 Module with Arduino Micro. It reponds well to basic AT commands. But i am unable to send SMS from this module as:

AT+CMGF=1 ERROR

Now while further debugging i saw AT+COPS? Returns 0, means not connected to any operator. That may be causing the CMGF failure. But my AT+COPS=? returns multiple operator. I have an Airtel working sim. Intialyy it was showing AIRTEL too in AT+COPS=? but not now.. anything to do with signal??

AT+COPS?

+COPS: 0

OK AT+COPS=?

+COPS: (2,"405800","405800","405800"),(1," IDEA CELLULAR Ltd","IDEA","40404"),(1,"40505","40505","40505"),,(0-4),(0-2)

What is going wrong here. any inputs?

# Answer
It can take a while for a modem to register on the network - sometimes several minutes.

Turning on CREG URCs can help you monitor what is happening:

```
AT+CREG=1

```

You should now start getting `+CREG` notifications as the network status changes.

Before using `AT+COPS?` you should really select a reporting mode so you know what you are looking at. I prefer numeric, since it's easier to parse:

```
AT+COPS=0,2

```

That will switch to automatic registration and reporting as numbers.

```
AT+COPS?
+COPS: 0
OK

```

That is not registered.

```
AT+COPS?
+COPS: 0,2,"40404"
OK

```

That is registered on a network with ID 40404.

The +CREG reports tell you what is going on:

```
+CREG: 1

```

That tells you that you have just connected to your home network.

If you are roaming, you would see:

```
+CREG: 5

```

Of course, if your home network is not available (say you have an AT&T SIM and only Verizon is visible at the moment), and your SIM doesn't have roaming enabled, then registration will never work. You'd expect to see +CREG reports of:

```
+CREG: 2
+CREG: 3
+CREG: 0

```

That is "trying to register" (2), "registration denied" (3) and "doing nothing much now" (0).

The best document for learning about these commands is the 3GPP Command Set which is the standard that all modern GPRS modems should adhere to.
> 4 votes

# Answer
If you are using linear voltage regulator such as LM7805 or LM317, then definitely you need to replace with buck converter. Since the dropout at max current 1.5A is 1.8V.

Pls check the module voltage level using AT+CBC. If the voltage dropped less than 3.3V then module would keep restarts. Hence recommended voltage level for sim800 series is 3.7 - 4.4v. In that case you need a proper power supply. Try buck converter which has 3A rating and less dropout voltage too.

You can refer my study on my blog.. http://vimtron.blogspot.in/2017/10/gsm-sim800l-and-arduino-mega-2560.html
> 3 votes

# Answer
1- Do you even a proprely working SIM card? Test it with your phone by calling or texting someone with it.

2- Try putting your SIM card into your phone and unlock the SIM card. This function is usualy in the setting area of your smartphone. It will make it easier later on.

3- As always, reboot your PC and try again.
> 0 votes

---
Tags: gsm
---


title: Fan control circuit with Arduino

text:
# Question
Title: Fan control circuit with Arduino
I have a fan control circuit with Arduino (PWM). I did all things and it worked. My question is why we did not directly connect the fan to Arduino. Why should we have a driver circuit?

# Answer
This is an electronics question, and it should be forwarded to the electronics stackexchange.

The fan needs to have a proper amount of current to spin, and because the microcontroller that controls the fan draw very little current on its output pins (check the datasheet for the exact value, but it should be a few milliamps), unless you have a miniature fan, wiring it directly on the microcontroller will not be able to move the fan.

And this is by design that microcontrollers cannot provide much current. Because to provide larger amount of current than what they do, they'd need to have bigger copper tracks between the transistor to avoid having they internal circuits building too much heat, and they would be much much bigger.

So as a work around, we use an transistor, which receives on the "Base" pin a voltage, drawing almost no current, which will "connect" the collector and emitter pins where you can have a much bigger current flowing (though be careful to respect the datasheet's nominal values for current! Or use either a MOSFET, a Triac or a Relay for bigger currents).
> 2 votes

# Answer
Arduino is a low voltage and low current device. Arduino max current output delivery capecity is 200ma, you can read about diffrent arduino's limitations here, http://playground.arduino.cc/Main/ArduinoPinCurrentLimitations

**Fan or anything that** has a coil inside it, needs a huge amount of current during their start up. The current draw decreases as it gains its motion to some limit. The initial huge current is called **surge current**. There is a high chance that it will blow you pins dead.

Let's say we are using really small fan. And it managed to start and rotating, that dosen't meant there is no problem at all. When a coil is rotated inside a magnetic field an opposite voltage is induced called **Back Emf** . This is **another** huge **potential concern**. This is why we are always suggested to use a **diode** which will **block** the opposite flow of **current**.

**Transistor**, being a low voltage device and as it can deliver tremendous large amount of output current, It is very widely used to drive high current devices
> 1 votes

# Answer
The

```
Vin pin = 5V or 3.3V

```

You cannot use the 5V from the USB to power up the FAN and the LOAD because the USB port usually delivers only 100mA, and this is not enough to switch the relay and the LOAD. That is why you must use an external power supply (Vcc) that is between 7 to 12 volts to power up the Arduino board and the transistor + relay. The load uses its own power supply, for instance if you use a light bulb then you might connect it to the 110/220V mains or any other power source.

**or**

you can also use a fan that has one of the pins of the fan is a PWM input. The fan has an internal transistor to switch the 12V power when given a 0-5V input. That is the pin you want to connect to the actuator pin.

**please get back to me if it was helpful**
> 1 votes

# Answer
Actually the Arduino Uno dc current per I/O pin is 40mA. When fan is connected directly to Arduino Uno, it cannot withstand, because the fan draws more-than `20mA` current.

The driver circuit provides sufficient current to rotate the fan. The `TIP 121` can withstand up to `3A` current.
> 1 votes

# Answer
I know this is an old link but MAXIM has a tutorial on using PWM to drive "normal" DC fans. The link is here: https://www.maximintegrated.com/en/app-notes/index.mvp/id/1784

It was helpful.

Personally, I am designing a simple 5-step temperature-driven device that uses an ATtiny13A to drive a 5 volt fan and a thermistor mounted to a heatsink. I was originally trying to use a PWM frequency of 4687Hz (CPUclk / 256) but it was way to high. The MAXIM article states that frequencies in the range of 20Hz to 160Hz are useful. Obviously, the 4687Hz was TOO HIGH. I dropped it down to 18Hz and everything works now. The problem was that the pulse width at 4687Hz was too short to give the DC fan enough electrical "momentum" to spin the fan. Using a lower PWM frequency gives more electrical energy to the fan to get it to spin. An analogy would be trying to push a toy car with short and rapid "pushes" as opposed to using longer and slower "pushes".

Hope this helps.

Peace and blessings.
> 1 votes

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


# Question
Title: Please help explain the meaning of '\n' and '0';
Please help explain the meaning of `'\n'` and `'0'` in the lines

```
if (isdigit(readValue) && readValue != '\n')
{
  cellValue = cellValue * 10 + readValue - '0';
}

```

# Answer
The '\n' in interpreted as a line-feed character. It is one of many printable and non printable ASCII characters computers use. Usually, character strings are terminated using a line-feed. So this line of code is likely testing for the end of a string of characters.

The '0' is interpreted as the ASCII value for the character which looks like the number zero. Strange enough, when printing characters, the ASCII value for the charter which looks like the number zero actually has a value of 48. And one has a value of 49. Two a value of 50. Three a value of 51. And so on. So, to convert a number found in a character string into numbers like 0, 1, 2 & 3, programmers subtract 48 from the character. Using '0' instead of 48 works as both represent the same value. And, by subtracting '0', it is clearer to the seasoned programmer that a conversion from ASCII numbers to normal numbers is underway.
> 1 votes

# Answer
\n stands for new line feed. It is one of the many "escape sequences" in C. Escape sequences start with "\\" and it imply a predefined meaning to compiler.

Refer: https://en.m.wikipedia.org/wiki/Escape\_sequences\_in\_C

In ASCII, decimal numbers from 0-9 are represented in 7-bits, in the range 48-57. So if a and b are integers, then: b = a - '0' means b = a - 48

Refer: https://ascii.cl/index.htm?content=mobile
> 0 votes

---
Tags: arduino-uno
---


title: Stray\342 inprogram

text:
# Question
Title: Stray\342 inprogram
What does this mean?? Stray\342 inprogram

```
// Basic sketch for EmonWRT
// Version 1.2

#define FILTERSETTLETIME 15000 // Time (ms) to allow the filters to settle before sending data

const int CT1 = 1;
const int CT2 = 1; // Set to 0 to disable CT channel 2
const int CT3 = 1; // Set to 0 to disable CT channel 3
const int VOLT = 1; // Set to 0 to disable

const int UNO = 1; // Set to 0 if your not using the UNO bootloader (i.e using Duemilanove) – All Atmega’s shipped from OpenEnergyMonitor come with Arduino Uno bootloader
#include <avr/wdt.h>
#include <JeeLib.h> // Download JeeLib: http://github.com/jcw/jeelib
ISR(WDT_vect) { Sleepy::watchdogEvent(); } // Attached JeeLib sleep function to Atmega328 watchdog -enables MCU to be put into sleep mode inbetween readings to reduce power consumption
#include <EmonLib.h>
EnergyMonitor ct1,ct2,ct3; // Create instances for each CT channel
float power1, power2, power3;
float voltage;
const int LEDpin = 9; // On-board emonTx LED

boolean settled = false;
boolean firstsensor = true; // Just to know if a , must be added in the CSV output

void setup()
{
delay(10000);

Serial.begin(9600);
Serial.println(“emonWRT CT123 and Voltage v1.2”);
pinMode(LEDpin, OUTPUT); // Setup indicator LED
digitalWrite(LEDpin, HIGH);

if (UNO) wdt_enable(WDTO_8S); // Enable anti crash (restart) watchdog if UNO bootloader is selected. Watchdog does not work with duemilanove bootloader // Restarts emonTx if sketch hangs for more than 8s
ct1.voltage(3, 225, 1); // Voltage: input pin, calibration, phase_shift

}

void loop()
{

power1 = ct1.Irms; //ct.calcIrms(number of wavelengths sample)*AC RMS voltage
power2 = ct2.Irms;
power3 = ct3.Irms;
voltage = ct1.Vrms; // AC Mains rms voltage

// because millis() returns to zero after 50 days !
if (!settled && millis() > FILTERSETTLETIME) settled = true;

if (settled) // send data only after filters have settled
{
digitalWrite(LEDpin, HIGH); delay(2); digitalWrite(LEDpin, LOW); // flash LED
**Serial.println(“EMONWRT “);**

if (CT1) {
if (!firstsensor) Serial.println(" ");
firstsensor = false;
Serial.print(power1);
}

if (CT2) {
if (!firstsensor) Serial.println(" ,");
firstsensor = false;
Serial.print(power2);
}

if (CT3) {
if (!firstsensor) Serial.println(",");
firstsensor = false;
Serial.print(power3);
}

if (VOLT) {
if (!firstsensor) Serial.println(" ");
firstsensor = false;
Serial.print(voltage);
}

firstsensor = true;

//Serial.println(” “);
Serial.println(" ");

delay(100);

Sleepy::loseSomeTime(5000); // sleep or delay in seconds – see emontx_lib
}
}

```

# Answer
Typographic quotes ( and ) are not part of C/C++ language for defining string literals.

For that you must use straight quotes (i.e. **"**).

Hence replace:

```
Serial.println(“EMONWRT “);

```

with:

```
Serial.println("EMONWRT ");

```

Typographical quotes might get automatically created when using a word processor (e.g. MS Word) to type your source code, or when copying code from a Word document into the Arduino IDE.

The best is to keep away from word processors when typing source code.
> 2 votes

---
Tags: arduino-uno
---


# Question
Title: How to get a character from a serial Parsed http response?
I am a web developer and I am struggling with C code on Arduino. So this is What I have:

I have a backend written on PHP that returns a 0 or 1 depending of wether a pin should be high or low. I have an Arduino UNO with a W5100 Ethernet shield mounted, and I'm currently connecting correctly to my server, this is my Arduino code:

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

// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
// if you don't want to use DNS (and reduce your sketch size)
// use the numeric IP instead of the name for the server:
//IPAddress server(74,125,232,128);  // numeric IP for Google (no DNS)
char server[] = "www.api-qa1.enerzoo.com";    // name address for Google (using DNS)

// Set the static IP address to use if the DHCP fails to assign
IPAddress ip(192, 168, 0, 177);

// Initialize the Ethernet client library
// with the IP address and port of the server
// that you want to connect to (port 80 is default for HTTP):
EthernetClient client;

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  // start the Ethernet connection:
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // try to congifure using IP address instead of DHCP:
    Ethernet.begin(mac, ip);
  }
  // give the Ethernet shield a second to initialize:
  delay(1000);
  Serial.println("connecting...");

  // if you get a connection, report back via serial:
  if (client.connect(server, 80)) {
    Serial.println("connected");
    // Make a HTTP request:
    client.println("GET /api/DeviceState/1 HTTP/1.1");
    client.println("Host: www.api-qa1.enerzoo.com");
    client.println("Connection: close");
    client.println();
  } else {
    // if you didn't get a connection to the server:
    Serial.println("connection failed");
  }
}

void loop() {
  // if there are incoming bytes available
  // from the server, read them and print them:
  if (client.available()) {
    char c = client.read();
    Serial.print(c);
  }

  // if the server's disconnected, stop the client:
  if (!client.connected()) {
    Serial.println();
    Serial.println("disconnecting.");
    client.stop();

    // do nothing forevermore:
    while (true);
  }
}

```

And this is the response it outputs:

```
connecting...
connected
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Content-Type: application/json
Transfer-Encoding: chunked
Connection: close
Vary: Accept-Encoding
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS
Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With
Cache-Control: no-cache
Date: Fri, 17 Nov 2017 23:36:14 GMT
Set-Cookie: laravel_session=eyJpdiI6ImIzTDJzQk1BUm1qY1BuZ1BJXC83Mk5BPT0iLCJ2YWx1ZSI6IlwvNjlmXC9FZWxDSW9vbGNcL1JZUU5tbTFvOVVXVjcxV0hHaDRKUzVGVVZCSmFCM1BcLzlSR2x5MmN4cnZ1ZHRvZmlcLzNSUWMrZEFDMTQzR05ORTk5R3dBUGc9PSIsIm1hYyI6IjM4ZjVhY2IxOWVmZTMzMGY2OGE1MTNmZWY0NzczNGVhNWJhZjVkYzlkYzY4ODg3ZGI0OWVhNDYwOTkwYjgxYTAifQ%3D%3D; expires=Sat, 18-Nov-2017 01:36:14 GMT; Max-Age=7200; path=/; HttpOnly

1a
||0||
0

disconnecting.

```

I need to get that zero that is enclosed between the double pipes

> ||0||

Any help would be really appreciated

# Answer
This is how I solved it. I avoided using regex expressions and "complex" functions such as substring in order to save memory. I just detected two consecutive pipes and get the next character (in this case 0 or 1) using a counter. Since I need to continuously be checking the status of the device, I reset the counter to 0 once I get the current state.

```
  if (client.available()) {
    char c = client.read();
    if(c == '|' || counter == 2){
      counter++;
      if(counter == 3){
        counter = 0;
      }
      if(c == '1' || c == '0'){
        Serial.print(c);
      }
    }
  }

```
> 0 votes

# Answer
You can send json format instead of pipes enclosed and parse the value. Else use regex expression to match ||0|| or ||1|| .
> 0 votes

---
Tags: arduino-uno, serial, ethernet
---


# Question
Title: Using RTC DS3231 + Arduino UNO to calculate time lapsed
I am a beginner with no coding background. I am trying to figure out an alarm that tells people how long they have been sitting on their chair. The concept is very simple when the person would sit in his chair it will trigger an event ( maybe a button press) which should trigger the counting of time. if the time exceeds a limit (let's say an hour) a buzzer will go off. The only way to stop the buzzer is to stay away from the chair for let's say a minute. I don't know how to start writing this code, especially how do I make this time counter start with this sitting action ( which might press a button). Its for my class project so any help is highly appriciated.

# Answer
> 0 votes
> The concept is very simple when the person would sit in his chair it will trigger an event ( maybe a button press) which should trigger the counting of time. if the time exceeds a limit (let's say an hour) a buzzer will go off.

multiple ways, all conceptually identical to yours ask:

1) when a person sits in the chair, it triggers a piece of code that sets an alarm in the dtc. once the dtc alarm goes off, it triggers a state change on a pin linking the dtc to the mcu, which triggers the buzzer;

2) the 2nd approach is similar except that the mcu pulls the dtc constantly for new time. once the new time passes the trigger time sufficiently, a buzzer sounds.

...

this whole thing can be done without the dtc, btw.

# Answer
> 1 votes
One idea would be to use force/pressure sensor on chair. You have to find what the sensor outputs when an average person sits on it and calibrate the values accordingly in code. Finally you have to a set threshold value for it. Now if somebody sits on it and if that threshold is exceeded, it means somebody sat on it. So you can now trigger your rtc module or maybe you can use special peripherals called timers , which are inside arduino itself. Both can be used to keep track of time. Tutorials are available for both timers, and ds3231- arduino interfacing. You can easily code. Good luck :-)

---
Tags: arduino-uno, timers, rtc, ds3231-alarms
---


# Question
Title: How to enable interrupt again after disabling it?
I am not quite experienced with Arduino and Interrupts. Below I am trying to disable interrupt once it got detected and enable it again when I start loop again. But in below code I am not able to enable it.

```
int L = 2;
volatile int done0=0;
volatile unsigned long leftT=0;

void recordL()
{
  if(done0 == 0)
  {
      leftT=micros();
  }
  done0 = 1;
  detachInterrupt(0);
}

void setup() {
  // put your setup code here, to run once:
  pinMode(L,INPUT);
  Serial.begin(9600);
  Serial.println("Start..");
}

void loop() {
  // put your main code here, to run repeatedly:

  attachInterrupt(0,recordL,RISING);
  done0 = 0;

  while(!done0)
  {

  }

  Serial.println("Sound..");
  Serial.println(leftT);
  delay(1000);
  Serial.println("After Delay");
}

```

but I made small change in code. I shifted 'done0=0' above attachInterrupt() then it is working. Why is that happening? One more issue that I am facing here is when I enable it again one more saved value is coming. Does it store value when I have disabled it?

```
int L = 2;
volatile int done0=0;
volatile unsigned long leftT=0;

void recordL()
{
    if(done0 == 0)
    {
        leftT=micros();
    }
  done0 = 1;
  detachInterrupt(0);
}

void setup() {
  // put your setup code here, to run once:
  pinMode(L,INPUT);
  Serial.begin(9600);
  Serial.println("Start..");
}

void loop() {
  // put your main code here, to run repeatedly:
  done0 = 0;
  attachInterrupt(0,recordL,RISING);

  while(!done0)
  {

  }

  Serial.println("Sound..");
  Serial.println(leftT);
  delay(1000);
  Serial.println("After Delay");
}

```

Output for 2nd case (Sound is coming only once but I am getting sound after delay also):

```
   Start..
   Sound..
   2873000
   After Delay
   Sound..
   3873528
   After Delay

```

# Answer
> 1 votes
The code needs modifications. I presume you are using digital pin 2 as your interrupt pin here. But the first argument to your attachinterrupt () is simply 0. That's not a recommended way of passing argument. Check the below link.

Check -https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/

I think this is what happened -

In the first case, the code is stuck in the infinite while loop as interrupt routine might have called just after attachinterrupt() and done became 1. After that done becomes 0 and got stuck in while (!done) loop forever as interrupts are now disabled.

In the second case, after making done = 0, the code entered into the interrupt routine and made done = 1, comes out, skips while loop and prints output. Again in loop(), done is made 0 and interrupts are attached back. And again interrupt routine is executed again , possibly because it detected another rising edge. This issue is there with push buttons, due to bouncing. Here, sound sensor may not be outputting clean digital signal.

Note: Disabling interrupt inside interrupt routine is meaningless cz arduino by default disables all interrupts and queues further interrupts during the execution of an interrupt routine. So I really doubt its behavior. You better rectify it by removing that statement from there and put it in the main code after while().

# Answer
> 0 votes
Normally, an Arduino interrupt attachment is made in the setup() method and is never removed. Consider moving your call to attach the interrupt accordingly and removing your call to detach the interrupt.

Your approach is understandable when considering normal embedded processor programming. In such cases all aspects of the hardware must be considered. This may include resetting the interrupt hardware for the next interrupt event.

When programming in the Arduino paradigm, many details are abstracted from the coder to make the coding experience simple and straight forward. In the example found at the bottom of the interrupt attachment Arduino Reference page, it is evident that no code needs to be added to manage the interrupt within the interrupt method.

To address your question specifically (why does the 2nd code listing work while the 1st does not) consider the actual (possible) sequence of events. The setup() method is 1st run followed by the loop() method. In the 1st code listing you attached the interrupt then set your "done" flag allowing the code in the interrupt to run. You cause the interrupt by raising the input on interrupt pin 0. This will likely work and you will then disconnect the interrupt. If you try to cause the interrupt again before 1 seconds elapses it will appear that the interrupt did not work because the loop() method is still waiting for the 1 second delay you have added and has not re-attached the interrupt. After the 1 second delay has ended, the loop() method will be called again. It is likely this time the processor's hardware remembers you tried to cause an interrupt. So when the interrupt is attached, the interrupt routine is called. But the "done" flag has not yet been set to zero so the interrupt does not execute code controlled by the "done" flag. In the 2nd code listing you have remedied this problem by setting the "done" flag before reattaching the interrupt.

# Answer
> 0 votes
> Below I am trying to disable interrupt once it got detected and enable it again when I start loop again.

not sure why you want to do that but interrupts are DISABLED in isr by hardware (unless you explicitly enable it in isr) so what you are trying to do is done for you automagically.

> But in below code I am not able to enable it.

mostly it involves enabling the respective interrupt mask, unless you want to enable / disable all interrupts.

---
Tags: arduino-uno, interrupt
---


title: motor hard stop vs coasting

text:
# Question
Title: motor hard stop vs coasting
I'm using this motor driver with 2 of these motors to control a skid steer robot. To get the robot to coast to a stop, I use this code:

```
  analogWrite(MotLPWM, 0);  //coast to stop
  analogWrite(MotRPWM, 0);
  digitalWrite(MotL1, HIGH);
  digitalWrite(MotL2, HIGH);
  digitalWrite(MotR1, HIGH);
  digitalWrite(MotR2, HIGH);

```

to get the robot to hard stop, I use this code:

```
analogWrite(M1PWM, 0);
analogWrite(M2PWM, 0);
digitalWrite(M1INA, LOW);
digitalWrite(M2INA, LOW);
digitalWrite(M1INB, LOW);
digitalWrite(M2INB, LOW);

```

I would like for the robot to stop and/or brake with something in between so it isn't so hard on the gears. The following snippet of the whole sketch is supposed to let the motors coast for 1/4 second then hard stop. Unfortunately, it doesn't coast and goes straight to the hard stop. Any ideas how to fix it?

```
    void allStop () {
//COAST
  analogWrite(MotLPWM, 0);  //coast for 1/4 second before fast stop
  analogWrite(MotRPWM, 0);
  digitalWrite(MotL1, HIGH);
  digitalWrite(MotL2, HIGH);
  digitalWrite(MotR1, HIGH);
  digitalWrite(MotR2, HIGH);
//HARD STOP
  if ((millis() - previousCoastMillis) > 250) {
  analogWrite(MotLPWM, 0);
  analogWrite(MotRPWM, 0);
  digitalWrite(MotL1, LOW);
  digitalWrite(MotL2, LOW);
  digitalWrite(MotR1, LOW);
  digitalWrite(MotR2, LOW);
    previousCoastMillis = millis();
  }
}

```

The full sketch is here:

```
int ledB = 5;

int MotL1 = 8;
int MotL2 = 7;
int MotLPWM = 9;

int MotR1 = 11;
int MotR2 = 12;
int MotRPWM = 10;

unsigned long previousCoastMillis = 0;
const int coastInterval = 500;

void setup() {
  pinMode(MotL1, OUTPUT);
  pinMode(MotL2, OUTPUT);
  pinMode(MotLPWM, OUTPUT);
  pinMode(MotR1, OUTPUT);
  pinMode(MotR2, OUTPUT);
  pinMode(MotRPWM, OUTPUT);
  pinMode(ledB, OUTPUT);
}

void loop() {
  go();
  allStop();
}

void allStop () {
//COAST
  analogWrite(MotLPWM, 0);  //coast for 1/4 second before fast stop
  analogWrite(MotRPWM, 0);
  digitalWrite(MotL1, HIGH);
  digitalWrite(MotL2, HIGH);
  digitalWrite(MotR1, HIGH);
  digitalWrite(MotR2, HIGH);
//HARD STOP
  if ((millis() - previousCoastMillis) > 250) {
  analogWrite(MotLPWM, 0);
  analogWrite(MotRPWM, 0);
  digitalWrite(MotL1, LOW);
  digitalWrite(MotL2, LOW);
  digitalWrite(MotR1, LOW);
  digitalWrite(MotR2, LOW);
    previousCoastMillis = millis();
  }
}

void go () {
  analogWrite(MotLPWM, 150);
  analogWrite(MotRPWM, 150);
  digitalWrite(MotL1, HIGH);
  digitalWrite(MotL2, LOW);
  digitalWrite(MotR1, HIGH);
  digitalWrite(MotR2, LOW);
  digitalWrite(ledB, HIGH);
  delay(1000);

}

```

# Answer
You are trying to use a mix of `delay` and `millis`

Instead you will want a proper state machine:

```
void loop(){

    switch (state){
    case GOING: go();
       state = WAIT_FOR_COAST;
       transition = millis();break;

    case WAIT_FOR_COAST: if(millis()-transition > 1000){
            allStop(false);
            state = WAIT_FOR_STOP; transition = millis();
        }
        break;
    case WAIT_FOR_STOP: if(millis()-transition > 250){
            allStop(true);
            state = WAIT_FOR_GO; transition = millis();
        }
        break;
    case WAIT_FOR_GO: if(millis()-transition > 1000){
            allStop(true);
            state = WAIT_FOR_GO; transition = millis();
        }
        break;

    }

}

```

Remove the delay in go and use a simple if-else in the allStop where parameter == true means hard stop and false means coast.

Another option is to use a extra mosfet to put a resistor across the motor instead of shorting it out (which is what the hard stop will do). That will reduce the breaking torque but defeats the isolation of the board.
> 1 votes

# Answer
This works. When allStop gets called, previousCoastMillis is reset. Then the motor coasts while it's stuck in the while loop for 150ms. Then it hard stops.

```
void allStop () {
  previousCoastMillis = millis();
  while (millis() - previousCoastMillis < 150) {
    analogWrite(enA, 0);
    analogWrite(enB, 0);
    digitalWrite(in1, HIGH);
    digitalWrite(in2, HIGH);
    digitalWrite(in3, HIGH);
    digitalWrite(in4, HIGH);
  }

  analogWrite(enA, 0);
  analogWrite(enB, 0);
  digitalWrite(in1, LOW);
  digitalWrite(in2, LOW);
  digitalWrite(in3, LOW);
  digitalWrite(in4, LOW);
}

```
> 0 votes

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


# Question
Title: Simulation of Arduino Mega 2560 with GSM Module using Proteus
I have really been suffering with my simulation! Tried connecting my arduino mega 2560 to COMPIM (used as GSM Module) in my circuit and also loaded sample code but damn! In vain! I wanted to view the data sent in virtual terminal but am getting nothing! and its also complaining of excessive CPU usage.

This is the circuit as seen below in Proteus.

And thereafter, the log messages are displayed as shown below.

Someone please help me out. Am I making a mistake oh? Infact the arduino code for displaying in the simulation is also giving me hard time. The one am using is as shown below.

```
#include <SoftwareSerial.h>

SoftwareSerial mySerial(10, 11); // RX, TX

void setup()
{
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }

  Serial.println("Goodnight moon!");

  // set the data rate for the SoftwareSerial port
  mySerial.begin(9600);
  mySerial.println("Hello, world?");
}

void loop() // run over and over
{
  if (mySerial.available())
    mySerial.println("Hello, world?");
  if (Serial.available())
    mySerial.println("Hello, world?");
}

```

Will b every grateful for any help offered.

# Answer
> 2 votes
You should download this GSM Library for Proteus . You can use this library to simulate your GSM module in Proteus software. You should also check this example where they have discussed Hoe to Send SMS with GSM module in Proteus ISIS. I hope it will help you out.

Thanks.

# Answer
> 1 votes
Hello I had the same problem as you, but I managed to solve it.
Use the TinyGSM library. Open the library folder, locate the Tinygsmcommon file. Open the file, line 75 changes the value from Baud 9600 to 2400. That is the minimum speed of my module.

In proteus work with the same speed 2400.
It worked here. Proteus can not handle so much speed.
And do not forget to also change the speed of GSM, place 2400.

---
Tags: arduino-mega, gsm, simulator
---


title: ESP8266-07 no work after reboot

text:
# Question
Title: ESP8266-07 no work after reboot
I try move my projects from atmega to ESP8266-07 modules. I connect ESP8266-07 to FT232:

```
(ESP) RX -------- TX (FT232)
(ESP) TX -------- RX (FT232)
(ESP) GND ------- GND (FT232)
(ESP) VCC ------- VCC 3.3V (FT232)
(ESP) EN -------- VCC 3.3V (FT232)
(ESP) GPIO0 ----- GND (FT232)
(ESP) GPIO15 ---- GND (FT232)

```

I can upload sketch and it's work. BUT...

... WHEN I restart ESP (software reset or hardware reset - unplug power) program no starting. I try change connections after upload like:

```
Try 1:
(ESP) RX -------- TX (FT232)
(ESP) TX -------- RX (FT232)
(ESP) GND ------- GND (FT232)
(ESP) VCC ------- VCC 3.3V (FT232)
(ESP) EN -------- VCC 3.3V (FT232)

Try 2:
(ESP) RX -------- TX (FT232)
(ESP) TX -------- RX (FT232)
(ESP) GND ------- GND (FT232)
(ESP) VCC ------- VCC 3.3V (FT232)
(ESP) EN -------- VCC 3.3V (FT232)
(ESP) GPIO0 ----- VCC 3.3V (FT232)

Try 3:
(ESP) RX -------- TX (FT232)
(ESP) TX -------- RX (FT232)
(ESP) GND ------- GND (FT232)
(ESP) VCC ------- VCC 3.3V (FT232)
(ESP) GPIO0 ----- VCC 3.3V (FT232)

```

But everytime sketch does not start after upload. This is not a code problem, because I try start "blink" sketch or other. Everytime ESP work once, after upload.

# Answer
> 1 votes
Thank you gre\_gor. You were right about correct pins. If you want start ESP on "normal mode" you must plug pins like:

```
(ESP) GND ------- GND
(ESP) GPIO15 ---- GND
(ESP) VCC ------- VCC 3.3V
(ESP) EN -------- VCC 3.3V
(ESP) GPIO0 ----- VCC 3.3V
(ESP) GPIO2 ----- VCC 3.3V

```

But if we must use GPIO0, GPIO2 and GPIO15 how we have 9 GPIO, 2 UART and 1 ADC?

# Answer
> 0 votes
For me the same issue happened once ,i tries flashing the AT commands firmware (can download from espressif website)and then burned my test firmware to it ...worked.Try it..!

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


# Question
Title: Using an ESP8266 with an Arduino Uno - can't get AT command to work
I am trying to connect an ESP8266 to my Arduino Uno.

Connections:

```
RX -> RX
TX -> TX
CH_PD -> 3.3v (Arduino 5v using voltage regulator)
VCC -> 3.3v
GND -> GND

```

I am running the RX and TX pins through a logic converter, dropping those down to 3.3v. Also, I have read that normally RX goes to TX and vice versa, but since I am trying to communicate with the chip using my computer (not the arduino) it needs to be the other way around.

I can't get the `AT` command to work on any baud rate. I was paying attention mostly to 9600, 115200, and 57600...I checked some others but it seemed like from reading these are the most common.

I used a multimeter to check the voltage of the RX/TX pins and after the logic converter my meter says it is outputting 3.2 volts (is this two low for serial to work?) Is their some +/- in the reading and it is actually 3.3v?

How do I go about troubleshooting this? Is it possible the AT firmware isn't loaded onto my chip? (I purchased it new, and recently).

**UPDATE:**

I'm reading about my logic level converter here, and I'm wondering if I have it setup right. My converter is labeled with HV -\> HV4 and LV -\> LV4 (you can see in the below picture). I'm wondering about where it says:

`The middle section of the board is where the reference supply for your high and low voltages should go. Supplying voltage to all four of these pins is required. If you’re converting 3.3V to 5V (and vice-versa), for example, you’d run 5V into the “HV” side, and 3.3V into the “LV” input. Make sure each is grounded too!`

So I need to provide power ("reference" power)? Some diagrams I have seen do this but I wasn't sure why:

**UPDATE**

I provided the reference supply and it up'd my voltage reading from 3.2 to 3.27 (I can assume it has enough voltage now?). I still can't connect with `AT` \- on one of the baud rates I was getting stuff like `!?` as output.

**UPDATE**

I changed what pins were being used by RX/TX on my logic level converter, and now when I type `AT` on baud 115200, it outputs `AT`. Below is what it looks like for this configuration:

Do the soldered connections look good on the logic level converter?

# Answer
Try loading the ESP8266-01/12F firmware once more from the Espressif and see if it's working correctly. Hope you know how to change to firmware/programing mode?

(GPIO 0-\>ground)-\>rest-\>burn program-\>GPIO0-\>high-\>power reset)
> 1 votes

# Answer
After writing such a long question, hopefully this is useful to someone else: After changing the logic converter channels (not sure why the first two weren't working) I was receiving `AT` as output - the only thing I needed to do after that was change `No line ending` to `Both NL & CR` and I am receiving `AT OK` now.
> 0 votes

---
Tags: arduino-uno, serial, esp8266, arduino-ide, firmware
---


# Question
Title: Arduino Sketch: NodeMCU compilation error
Every time I try to compile a program written in Arduino IDE 1.8.5 for NodeMCU (LoLIN version v3), I get the following error:

```
Arduino: 1.8.5 (Windows 10), Board: "NodeMCU 1.0 (ESP-12E Module), 80 MHz, 115200, 4M (3M SPIFFS)"

C:\Users\sumeetpatil\AppData\Local\Arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\1.20.0-26-gb404fb9-2/bin/xtensa-lx106-elf-ar: unable to rename 'C:\Users\SUMEET~1\AppData\Local\Temp\arduino_build_831529/arduino.ar'; reason: File exists

exit status 1
Error compiling for board NodeMCU 1.0 (ESP-12E Module).

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

```

I have tried reinstalling several times, but I just can't get ahead of this step.

# Answer
> 1 votes
> Do a full uninstall of Arduino, then delete the Arduino folder and Arduino15 (back them up first if you have any sketches in there!!!!), as well as **any Arduino folders under Temp**. Make sure the folders and all contents are really gone, reboot and try again if not. Then, do a clean install of the IDE.

Cited from here.

---
Tags: arduino-ide, sketch, nodemcu, compilation-errors
---


# Question
Title: Auto acknowledge failed with nRF 24L01+ and Arduino
My transceivers are running fine. I've written a few code and got them running. Then I decided to check the auto acknowledgement feature wherein we can return data back to the sender WITHOUT manually changing the radio modes on both units. But I find that the serial monitor always shows "failed to transmit". Why is this happening, because otherwise they work fine?

I am using maniacbug's RF24master library.

The Tx code is:

```
#include<SPI.h>
#include<nRF24L01.h>
#include<RF24.h>

int msg[1] = {1};
int rec[1] = {0};
bool stat = true;
RF24 radio(9,10);
const uint64_t pipe[1] = {0xF0F0F0F0E1LL};

void setup()
{
  Serial.begin(57600);
  radio.begin();
  delay(1000);
  radio.setAutoAck(true);
  radio.enableAckPayload();
  radio.openWritingPipe(pipe[0]);
  radio.setRetries(15,15);
 }
void loop()
{
  if(stat)
  {
    radio.stopListening();
    bool ok = radio.write(msg,sizeof(msg));
    delay(100);
    if(ok)
    {Serial.println("transmitted successfully !!");}
    else
    {Serial.println("faileed to transmit");}
    msg[1]++;
    if(msg[1]>=200)
    {msg[1]=1;}
    stat = false;
    //delay(20);
  }
  if(!stat)
  {
    if(radio.isAckPayloadAvailable())
    {
      radio.read(rec,sizeof(rec));
      Serial.print("received ack payload is : ");
      Serial.println(rec[1]);
      stat = true;
    }
  }

}

```

and the Rx part is:

```
#include<SPI.h>
#include<nRF24L01.h>
#include<RF24.h>
const uint64_t pipe = 0xF0F0F0F0E1LL;
RF24 radio(9,10);
int rec[1] = {0};
int ack[1] = {1};
void setup()
{
  Serial.begin(57600);
  radio.begin();
  delay(100);
  radio.setAutoAck(true);
  radio.enableAckPayload();
  radio.openReadingPipe(1,pipe);
  radio.startListening();
  radio.setRetries(15,15);
}
void loop()
{
  if(radio.available())
  {
    Serial.println("payload available....");
    bool ok = radio.read(rec,sizeof(rec));
    if(ok)
    {
        Serial.println("message received !!");
        Serial.print("integer got is : ");
        Serial.println(rec[1]);
        radio.writeAckPayload(1,ack,sizeof(ack));
    }
    else
    {Serial.println("failed to receive the message");}
  }
}

```

# Answer
> 1 votes
To achieve that you have to do the following -

```
if ( radio.available() ) { // make sure the read will succeed
radio.writeAckPayload( 1, buf, len ); // prep the ack payload
radio.read( &got_time, sizeof(unsigned long) ); // also shunts out ack payload
}

```

So your program finally becomes -

```
#include<SPI.h>
#include<nRF24L01.h>
#include<RF24.h>
int msg[1] = {1};
int rec[1] = {5};
bool stat = true;
RF24 radio(9,10);
const uint64_t pipe[1] = {0xF0F0F0F0E1LL};

void setup()
{
  Serial.begin(57600);
  radio.begin();
  delay(100);
  radio.setAutoAck(true);
  radio.enableAckPayload();
  radio.enableDynamicPayloads();
  radio.stopListening();
  radio.openWritingPipe(pipe[0]);
  radio.setRetries(15,15);
 }
void loop()
{
if(stat)
{
    if(radio.write(msg,sizeof(msg)))
    {
      Serial.print( msg[0] );
      Serial.println("...tx success");
      if(radio.isAckPayloadAvailable())
      {
        radio.read(rec,sizeof(int));
        Serial.print("received ack payload is : ");
        Serial.println(rec[0]);
      }
      else
      {
        stat = false; //doing this completely shuts down the transmitter if an ack payload is not received !!
        Serial.println("status has become false so stop here....");
      }
      msg[0]+=3;;
    if(msg[0]>=100)
    {msg[0]=1;}
    }
 }
}

```

And the RX part becomes -

```
#include<SPI.h>
#include<nRF24L01.h>
#include<RF24.h>
const uint64_t pipe[1]= {0xF0F0F0F0E1LL};
RF24 radio(9,10);
int rec[1] = {2};
int red;
void setup()
{
  Serial.begin(57600);
  radio.begin();
  delay(100);
  radio.setAutoAck(true);
  radio.enableAckPayload();
  radio.enableDynamicPayloads();
  radio.openReadingPipe(1,pipe[0]);
  radio.startListening();
  radio.setRetries(15,15);
}
void loop()
{
  if ( radio.available() ) {
    radio.writeAckPayload( 1, rec, sizeof(int) );
    radio.read( &red,sizeof(red) );rec[0]+=2;
    Serial.print("integer got is : ");
    Serial.println(red);
}
}

```

Know more about it at the following pages - https://shantamraj.wordpress.com/2014/07/19/exploring-the-auto-ack-feature-of-the-transceiver/ https://shantamraj.wordpress.com/2014/11/30/auto-ack-completely-fixed/

---
Tags: remote-control, rf
---