# Question
Title: Requesting help with CNC Project using Arduino
I have made a setup with Arduino Uno, Nema 17, T8 lead screw, IR Sensor and a DC motor. I am trying to establish a code which:

1. Resets Home position of the Machining Head on the lead screw
2. Has an action button, which operates only when the position of the Head is on the lead screw, goes down the specified depth
3. Takes input from user to run the DC Motor (to rotate the tool on the machine head)
4. Takes second input to stop rotating and return to the reset position.

I am facing one major problem and two minor problems:

Major Problem: To remove an error which was later resolved, I added the line: action\_permit=0 Now due to some reason (I have pulled a lot of hairs trying to understand this), when I remove this action\_permit line, the DC Motor rotation is stopped. I have to include this line to rotate my DC Motor.

Minor Problem: To get input from the user as to control when the DC motor starts and stops, I included the code which accepts 'y' for yes (start rotating the DC motor) and 'n' as no (stop rotation and return to home position)

Minor Problem: I am not sure how to control the PWM, I have copied the code from a video, but do not know how to reach maximum and minimum rpm; also I understand the variation between PWM value and RPM is not linear. Any feedback on how to precisely control the rpm of the motor would be great

```
int IR_signal=2;
int DC_ENB=11;
int DC_IN3=4;
int DC_IN4=5;
int STE_dir=6;
int STE_step=7;
int STE_ena=10;
int button_reset=8;
int button_action=9;
//define arduino pin
int action_permit;//0-action part is not allowed to run. 1-action part is allowed to run
int IRon;
int COUNT;//the amount of steps that the machine head should go
int HEIGHT;//total height that the machine head should go
int i;
int reset_on;
int action_on;
String Switch_DC;

//parameter
void setup() {
  // put your setup code here, to run once:
  pinMode(IR_signal,INPUT);
  pinMode(button_reset,INPUT);
  pinMode(button_action,INPUT);
  //input part
  pinMode(DC_ENB,OUTPUT);
  pinMode(DC_IN3,OUTPUT);
  pinMode(DC_IN4,OUTPUT);
  pinMode(STE_dir,OUTPUT);
  pinMode(STE_step,OUTPUT);
  pinMode(STE_ena,OUTPUT);
  //output part
  action_permit=0;// ban the action part at the beginning
  COUNT=0;
  HEIGHT=0;

  //original value of parameters
  //digitalWrite(DC_ENB,HIGH);
  analogWrite(DC_ENB,200);
  digitalWrite(STE_ena,LOW);
  digitalWrite(DC_IN3,HIGH);
  digitalWrite(DC_IN4,HIGH);
  //original pin output
  Serial.begin(9600);
  // start the monitor
}

void loop() {
  // put your main code here, to run repeatedly:
  reset_on=digitalRead(button_reset);
  action_on=digitalRead(button_action);
  //read the signal from the button
  if(reset_on==0)//reset button is pressed
  {
    delay(10);
    // preventing manual error
    if(reset_on==0)
    {
      RES();
    }
  }
  if(action_on==0)//action button is pressed
  {
    delay(10);
    // preventing manual error
    if(action_on==0)
    {
      ACT();
    }
  }
}
void RES()//reset part
{
  while(action_permit==0)//when 0, this "while" loop will keep running
  {
    IRon=digitalRead(IR_signal);// read the signal from IR sensor
    if(IRon==1)// machine head is not in original position
    {
      delay(1);
      //ensure the signal is not happened by a BUG
      IRon=digitalRead(IR_signal);
      if(IRon==1)
      {
        digitalWrite(STE_dir,LOW);
        digitalWrite(STE_step,HIGH);
        delay(1);
        digitalWrite(STE_step,LOW);
        delay(1);
        //if machine head is not in original position, it will go up for one step
      }
    }//if HIGH, go up
    else if(IRon==0)
    {
      action_permit=1;
      COUNT=0;

    }//once machine head reaches the original position, controller will get out this loop and allow action part to run
  }
}
void ACT()//action part
{
  if(action_permit==1)
  {

   for(i=0;i<3523;i+=1)
   {
     digitalWrite(STE_dir,HIGH);
     digitalWrite(STE_step,HIGH);
     delay(1);
     digitalWrite(STE_step,LOW);
     delay(1);
   }
   delay(100);
   for(i=0;i<100;i+=1)
   {
     digitalWrite(STE_step,HIGH);
     delay(10);
     digitalWrite(STE_step,LOW);
     delay(10);
   }
   action_permit=0;

   Serial.println("Please press y to start tool rotation");
   while((Serial.available()==0))
   {
    //waiting for input
   }
   Switch_DC=Serial.readString();
   if (Switch_DC == "y")
   action_permit=0;
   {
    analogWrite(DC_ENB,200);
    digitalWrite(DC_IN3,HIGH);
    digitalWrite(DC_IN4,LOW);
    delay(2000);
   }

   Serial.println("Please press n to stop tool rotation");
   while((Serial.available()==0))
   {
    //waiting for input
   }
   Switch_DC=Serial.readString();
   if(Switch_DC == "n")
   action_permit=0;
   {
    analogWrite(DC_ENB,200);
    digitalWrite(DC_IN3,LOW);
    digitalWrite(DC_IN4,LOW);
   }
   digitalWrite(STE_dir,LOW);
   for(i=0;i<4523;i+=1)
   {
     digitalWrite(STE_step,HIGH);
     delay(1);
     digitalWrite(STE_step,LOW);
     delay(1);
   }
   action_permit=0;
  }
}

```

# Answer
> 0 votes
You have some obvious problems in your code, though I don't know, if the logic will be correct (doing what you want it to do) if you fix them. But either way it is a good start.

* You check for `action_on` and `reset_on` to be LOW, so I guess the button will pull the pin to LOW, if you press it. You didn't activate the internal pullup resistors, so I guess you already have them externally (if not: You definitely need them). So `action_on==0` actually is the case for action is permitted to run, not forbidden. You seem to think, that it is the other way round.
* Then you are doing this (and the same with `reset_on`):

```
if(action_on==0)//action button is pressed
  {
  delay(10);
  // preventing manual error
  if(action_on==0)

```

You check, if `action_on` is zero. If yes, you wait a bit and check the same again. The value of `action_on` cannot change during the delay, so this will always be true and thus is superfluous. If you meant to read the button again, to check if the button was really pressed (for debouncing), you have to actually read the button state again with `digitalRead()` and save it to `action_on`, like you have done before. This is not done automatically for you.
* `for(i=0;i<3523;i+=1)` Using a global variable to count in a for loop is not a good idea. Instead you should always use a local variable to do this: `for(int i=0;i<3523;i+=1)`
* `Switch_DC=Serial.readString();` Using `readString()` is not good coding, because this function just reads all data, that comes until the timeout hits (default 1s). This is not a reliable way to read data from Serial. Instead you should read each character individually from the Serial interface, put it into a buffer, and only stop and process the output, if a delimiting character was send. Often a newline character `\n` is used for this. So one message/command, that should be processed as a whole should be ended with a newline character. That will prevent, that the input from serial is processed incorrectly, only because the timing was different. If you only have commands, that consist of only 1 character, you can instead use a single `Serial.read()`, which reads exactly one character from the Serial interface (or returns -1 if there is no character to read).
* Then you wrote this:

```
if (Switch_DC == "y")
action_permit=0;
{

```

I guess, here you have inserted the `action_permit=0`. This cannot be, want you meant. As you wrote it, the `action_permit=0` line will only be executed, if `Switch_DC` is equal to "y", since this statement is inside the if statement. The `;` at the end of the statement also closes the if statement. So the code inside the following brackets will always be executed and the brackets are superflous. I don't know, where you intended to insert the `action_permit=0`, but since it is never used in the rest of the function, it is sufficient to just use it at the end of the function, like you already did. Remove all other of these lines from that function.

---

If you want to control the RPM of the motor, not just some relative PWM value, you first need to measure the RPM. PWM just controls the electrical energy going into the motor in a relative way (relative to fully powered on). To set a RPM value for the motor, you need to measure the current RPM (for example with a light barrier or a rotary encoder) and use that as input for a PID controller (Proportional Integral Differential). The output of the PID controller then must be fed into the `analogWrite()` function. The PID controller will raise or lower the PWM value, until the RPM setpoint is reached. There is a PID library for Arduino, that will help you with the calculation.

---
Tags: arduino-uno, stepper-motor, project
---


title: Expected unqualified-id before 'public'

text:
# Question
Title: Expected unqualified-id before 'public'
I'm making an arduino program for a buzzer that you can record notes and song for and then play them back. I have 2 arrays that hold both pitch and if a note is being played. I continue to get errors that say `expected unqualified-id before 'public'`.

Does anybody know how to fix this?

```
void setup()
{
 Serial.begin(9600);
 pinMode(5, INPUT_PULLUP);
 pinMode(14, INPUT_PULLUP);
 pinMode(12, INPUT_PULLUP);
}

void freePlayMode()
{
    int readP = analogRead(0);
  int readB = digitalRead(5);
  readP = map(readP, 0, 1023, 300, 2000);
  Serial.println(readP);
  if (readB == LOW)
  {
  tone(4, readP);
  }
  else
  {
    noTone(4);
  }
}

void recordMode()
{
 int readS2 = digitalRead(12);
 if (readS2 == LOW)
 {
  rec();
 }
 else
 {
  if (readS2 == HIGH)
  {
    playBack();
  }
 }
}

void rec()
{

static public int recordings[99999999] = {NULL};
static public int notes[99999999] = {NULL};
int state;
static unsigned long i = 0;
int readP = analogRead(0);
  int readB = digitalRead(5);
  readP = map(readP, 0, 1023, 300, 2000);
  Serial.println(readP);
  if (readB == LOW)
  {
  tone(4, readP);
  }
  else
  {
    noTone(4);
  }

  if (i < 99999999)
 {
  if (readB == HIGH)
  {
    state == 0;
  }
  else
  {
    state == 1;
  }
  recordings[i] = state;
  notes[i] = readP;
  i++;

 }
}

void playBack()
{

}

void loop()
{
int readS1 = digitalRead(14);
if (readS1 == LOW)
{
  freePlayMode();
}
else
{
  if (readS1 == HIGH)
  {
    recordMode();
  }
}

}

```

# Answer
```
static public int recordings[99999999] = {NULL}

```

This is not valid C code. Remove the word `public`.
Also you cannot create such a big array. The Arduino has only 2 KB (SRAM) memory and also since it is static you have to fill it with values directly, like:

```
static int recordings[5] = { 0, 1, 2, 3, 4 };

```

How many values you want to store?

In case you need quite a lot (like hundreds), I would use a different solution for the `state` array as it only stores values 0 or 1. For example, you can use arrays of uint8\_t which cost only 1 byte per element, but even better would be to store 8 0 or 1 (boolean) values in one byte each, but that means you have to get/set the values in the correct indices yourself.
> 2 votes

---
Tags: esp8266, programming, array
---


title: MKR GPS Shield Sampling Frequency

text:
# Question
Title: MKR GPS Shield Sampling Frequency
I have the MKR 1010 and am working on a circuit that needs realtime GPS positioning. I bought the MKR GPS Shield, and am using it on the I2C bus (attached via cable to the 1010 board), and am using the Arduino\_MKRGPS library in my sketch.

I am attempting VERY basic interaction with the board at the moment, and basically just want to print out the GPS coordinates to the serial.

I am using the GPSLocation sample from the Arduino\_MKRGPS library (see here):

```
  /*
  GPS Location

  This sketch uses the GPS to determine the location of the board
  and prints it to the Serial monitor.

  Circuit:
   - MKR board
   - MKR GPS attached via I2C cable

  This example code is in the public domain.
*/

#include <Arduino_MKRGPS.h>

void setup() {
  // initialize 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
  }

  // If you are using the MKR GPS as shield, change the next line to pass
  // the GPS_MODE_SHIELD parameter to the GPS.begin(...)
  if (!GPS.begin()) {
    Serial.println("Failed to initialize GPS!");
    while (1);
  }
}

void loop() {
  // check if there is new GPS data available
  if (GPS.available()) {
    // read GPS values
    float latitude   = GPS.latitude();
    float longitude  = GPS.longitude();
    float altitude   = GPS.altitude();
    float speed      = GPS.speed();
    int   satellites = GPS.satellites();

    // print GPS values
    Serial.print("Location: ");
    Serial.print(latitude, 7);
    Serial.print(", ");
    Serial.println(longitude, 7);

    Serial.print("Altitude: ");
    Serial.print(altitude);
    Serial.println("m");

    Serial.print("Ground speed: ");
    Serial.print(speed);
    Serial.println(" km/h");

    Serial.print("Number of satellites: ");
    Serial.println(satellites);

    Serial.println();
  }

  delay(100);
}

```

What I'm seeing is that the GPS takes on the order of 30-90 secs to initialize, and then only provides new updated coords every 20-30 secs. This is all with a clear view of the sky.

Is that really what to expect from this module? I was under the impression that it could provide several samples per second. Documentation seems to be very lacking for the Arduino\_MKRGPS library. Anyone else have insights or experience with this module?

Thanks!

# Answer
> 1 votes
It seems that the problem with the GPS was caused by my usage of the arduino delay(...) method in my loop.

I'm assuming that by using delay, the connection to the GPS module was being severed, and in effect, every loop was forcing a reconnect and a new download of satellite details.

In summary, when needing high sample frequency interaction with the GPS, using delay in the sketch won't work.

EDIT:

I've done a lot of digging since originally posting this question/answer and wanted to add my findings for others that are struggling to make the MKR GPS module work for higher than 1Hz sample rate use cases.

I had to make the following two changes to the Arduino\_MKRGPS library:

1. increase baud rate of the GPS connection. In the very last line of GPS.cpp...

```
GPSClass GPS(Serial1, 460800, serialDDC, 400000, 7);

```
2. In GPS.h, make the sendUbx method a public member of the GPS class. This allows me to send low-level commands to the SAM-M8Q from my sketch.

After this, I can construct low-level messages in my sketch and configure the GPS to my liking. Here's what I did to increase the sample rate to 3Hz in my sketch's setup method:

```
  Serial.println("Configuring GPS refresh rate...");

  //  UBX-CFG-RATE (0x06 0x08) Navigation/Measurement Rate Settings
  //  See UBX-13003221 section 32.10.23.1
  byte payload[6];

  memset(payload, 0x00, sizeof(payload));

  uint16_t measRate = 333;    // ms between gps data publish  (min of 100)
  uint16_t navRate  =   1;    // ratio between measurements and nav solution calculations
  uint16_t timeRef  =   1;    // The time system to which measurements are aligned (0: UTC, 1:GPS, ...)

  // write out the unsigned shorts in little-endian form
  payload[0] = measRate & 0xff;
  payload[1] = (measRate >> 8) & 0xff;
  payload[2] = navRate & 0xff;
  payload[3] = (navRate >> 8) & 0xff;
  payload[4] = timeRef & 0xff;
  payload[5] = (timeRef >>8) && 0xff;

  GPS.sendUbx(0x06, 0x08, payload, sizeof(payload));

  Serial.println("  > done");

```

Hope this helps someone else struggling with higher data rate use cases. There's still room for improvement, I think, in particular by reducing the number of sentences returned by the GPS. I haven't been able to get the sample rate higher than 5Hz, while technically the GPS is supposed to be capable of doing 10Hz. I'm not sure where the bottleneck is.

---
Tags: sensors, gps, mkr1010
---


# Question
Title: Blew my Arduino. Did I wire this correctly?
Hi,

I am currently doing a project and it seems that I may have blown my Arduino Nano (or maybe not). The power LED of the Nano was still on and I believe the L pin blinks once every time I press the reset button.

I wanted to use 4AA alkaline batteries to power my project. The servo is a continuous servo rated for 4-6V and 15-200mA from Parallax. Given that the Nano runs optimally when powered at 7-12V, I decided to buy a step-up converter (adjustable output voltage). It looks like this although I bought it elsewhere:

https://www.ebay.com.au/i/283603471149?chn=ps&norover=1&mkevt=1&mkrid=705-139619-5960-0&mkcid=2&itemid=283603471149&targetid=752505019384&device=c&mktype=pla&googleloc=9071392&poi=&campaignid=1979582348&mkgroupid=72745766764&rlsatarget=pla-752505019384&abcId=1139426&merchantid=7364522&gclid=Cj0KCQjwt5zsBRD8ARIsAJfI4Bh8cSOKugFrugHz-gA-s8nXclnO7H8iQ-WX46FRdhDLchwbl6UyWLgaAr4oEALw\_wcB

When I tried to test it with the servo running, my Nano stopped working after several seconds later. Did I wire them up wrongly? I also measured the output of the step-up converter when it was running with a voltmeter between the two terminals of the step-up's output. Would it be possible to short it that way?

Appreciate any help I can get. Thanks

# Answer
It would be best if everything ran at the same voltage. (And it is necessary that everything uses the same ground.) Which is possible as there are 5V Arduino boards. Interestingly, the Arduino nano, according to this schematic, runs at 5V.

In order to use the Arduino Nano at 5V, instead of using VIN / Pin 1, you should be able to skip the Arduino's 5V regulator and use +5V / Pin 4. But this must be a regulated 5V power source.

Now, why are you having problems controlling the servo?

It is difficult to tell, but your boost switching power supply negative input may not be directly connected to the negative output. With out a common ground, it may be difficult to create the proper signal to control the servo.

To be specific, if the ground or negative side of the servo power supply is not at the same potential as the ground or negative side of the Arduino power supply, controlling the servo may be difficult at best and at worst you could burn something out on the servo or Arduino.

To check, measure with a volt meter to see if there is any difference between the boost switcher negative input and negative output.

To solve this problem consider using a USB power supply plugged into the Arduino Nano and powering the servo off the 5V at pin 4 of the Nano. Or, keep using your 6V battery and 6V to 9V boost switching power supply. Connect this as you are to VIN Pin 1. The Arduino Nano's 5V power regulator should kick in and provide 5V at pin 4.
> 0 votes

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


# Question
Title: NodeMCU MQTT getting topic but not calling IF loop
I am very new to Arduino/ESP and I am writing a code to activate 2 relays using MQTT. My connection is successful and I am able to receive message/topic printed out on serial console. Here is my code:

```
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <DNSServer.h>
#include <WiFiManager.h>
#include <PubSubClient.h>
#include <Wire.h>
#include "SSD1306Wire.h"
#define wifi_ssid "SSID"
#define wifi_password "PASSWORD"
#define mqtt_server "192.168.1.1"
#define mqtt_user "mqtt_username"
#define mqtt_password "mqtt_password"

SSD1306Wire  display(0x3c, D2, D1);
const int relay1 = 5;
const int relay2 = 4;
String header;
String output5State = "off";
String output4State = "off";
const int output5 = 5;
const int output4 = 4;
WiFiClient wificlient;
WiFiClient espClient;
PubSubClient client(espClient);
ESP8266WebServer server(80);

//------------------- MAIN WEB PAGE ------------------------
const char MAIN_page[] PROGMEM = R"=====(
<head><meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<title>HOME IOT</title>
<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}
.button { background-color: #195B6A; border: none; color: white; padding: 16px 40px
text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer
body{margin-top: 50px;} h1 {color: #444444;margin: 50px auto 30px;
.button2 {background-color: #77878A;
p {font-size: 24px;color: #444444;margin-bottom: 10px;}
</style>
</head>
<body>
<div id="webpage">
<h1>Security Door</h1>
<p><a href="/show/SecurityDoor/Open"><button class="button">Open</button></a></p>
<p><a href="/show/SecurityDoor/Close"><button class="button">Close</button></a></p>
</div>
</body>
</html>
)=====";
//------------------- MAIN WEB PAGE ------------------------

void setup() {
  Serial.begin(9600);
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
  //-----------------------------------------
  WiFiManager wifiManager;
  //wifiManager.resetSettings();
  wifiManager.autoConnect("IOT-LivinRoom");
  //-----------------------------------------
  server.on("/", handle_OnConnect);
  server.onNotFound(handle_NotFound);
  server.begin();
  Serial.println("Initializing OLED Display");
  display.init();

  display.flipScreenVertically();
  display.setFont(ArialMT_Plain_10);
  Serial.println("HTTP server started");
}

void setup_wifi() {
  delay(10);
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(wifi_ssid);
  WiFi.begin(wifi_ssid, wifi_password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

}

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  String messageTemp;
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
    messageTemp += (char)payload[i];
  }
  Serial.println();
  Serial.print(messageTemp);

 if(topic=="livingroom/securitydoor"){
     Serial.print("Changing esp01 relay1 to ");
     if(messageTemp == "on"){
       digitalWrite(relay1, LOW);
       Serial.print("On");
       Serial.print("On from opening");

     }
     else if(messageTemp == "off"){
       digitalWrite(relay1, HIGH);
       Serial.print("Off");
       Serial.print("On from Closing");
     }
 }
 Serial.println();

 if(topic=="livingroom/ac"){
     Serial.print("Changing esp01 relay2 to ");
     if(messageTemp == "on"){
       digitalWrite(relay2, LOW);
       Serial.print("On");
       Serial.print("On from opening");

     }
     else if(messageTemp == "off"){
       digitalWrite(relay2, HIGH);
       doorClosing();
       Serial.print("Off");
       Serial.print("On from Closing");
     }
 }
 Serial.println();
}

void reconnect() {
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    if (client.connect("ESP8266Client", mqtt_user, mqtt_password)) {
      Serial.println("connected");
      client.subscribe("livingroom/securitydoor");
      client.subscribe("livingroom/ac");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

//--------------------------- void loop-----------------------
void loop() {

  server.handleClient();
  if (!client.connected()) {
    reconnect();
  }
  client.loop();

}

//----------------------------- Web Calls Function -----------
void handle_OnConnect() {
String s = MAIN_page; //Read HTML contents
server.send(200, "text/html", s);
}

void handle_NotFound(){
  server.send(404, "text/plain", "Not found");
}

```

Issue is: message from below is not printing in serial

```
       Serial.print("On");
       Serial.print("On from opening");

```

In fact code is displaying topic and message in serial console.

My actual user case is to display status on OLED display as well as control relay.

# Answer
> 0 votes
thanks for suggestions,

When i am doing it in below way, it got worked

```
if (strcmp(topic, "livingroom/securitydoor") == 0)
  {
    Serial.print(topic);
  }

```

---
Tags: esp8266, nodemcu
---


# Question
Title: How do I send Sensor Data from one Arduino to another Arduino that is a Webserver to post it?
I have been looking for over 2 hours now and just cant get it figured out. Im very confused as to how to do this. The solution I thought I found was to use HTTP POST. But I just cant get it to work. To be honest i'm guessing this should be very simple. Im using the variable

```
sensorValue = analogRead(0);

```

And then want to sent that Variable to my Webserver with the ip 172.20.10.5

Then I wish to save this variable into an array on my Webserver. I am sorry for this request I of course looked at least on 20 diffrent sites and questions and cant find a solution.

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

IPAddress server(172,20,10,5);
 if(client.connect(server, 80)) {
  client.println("POST /Raum1 HTTP/1.1");
  client.println("Host: 172.20.10.5");
  client.println("User-Agent: Arduino/1.0");
  client.println("Connection: close");
  client.print("Content-Length: ");
  client.println(sensorValue.length());
  client.println();
  client.println(sensorValue);
}
void setup(){
Serial.begin(9600);                            // sets the serial port to 9600
  WiFi.begin("iPad von Tobias", "12345678");  //Connect to the WiFi network

  while (WiFi.status() != WL_CONNECTED) {  //Wait for connection

    delay(500);
    Serial.println("Waiting to connect…");

  }

  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());  //Print the local IP
 }

//byte server[] = {172, 20, 10, 5}; //IP
void loop(){
sensorValue = analogRead(0);       // read analog input pin 0
Serial.print("AirQuality=");
Serial.print(sensorValue, DEC);               // prints the value read
Serial.println(" PPM");
delay(1000);

```

This is my current code on the ESP8266 I have the sensor on. The error im getting the most is: "client" has not been definied in this context. I had the HTTP POST in the loop, out of the loop, in the setup, it just doesn't work. I tried diffrent methods to write the IPAddress which didnt help either. I also do not know how to then save that Data on the Webserver. They are connected over WIFI. Maybe the http way is completly wrong?. I can't find anything for this.

I would most likely have it look like this but this doenst work either.

```
#include <SPI.h>
#include <Ethernet.h>
#include "ESP8266WiFi.h"
int sensorValue;

void setup(){
Serial.begin(9600);                            // sets the serial port to 9600#
WiFi.begin("iPad von Tobias", "12345678");  //Connect to the WiFi network

  while (WiFi.status() != WL_CONNECTED) {  //Wait for connection

    delay(500);
    Serial.println("Waiting to connect…");

  }

  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());  //Print the local IP
 }

 IPAddress server(172,20,10,5);
 client.connect(server, 80)
void loop(){sensorValue = analogRead(0);       // read analog input pin 0
Serial.print("AirQuality=");
Serial.print(sensorValue, DEC);               // prints the value read
Serial.println(" PPM");
delay(1000);
  client.println("POST /Api/AddParking/3 HTTP/1.1");
  client.println("Host: 172.20.10.5");
  client.println("User-Agent: Arduino/1.0");
  client.println("Connection: close");
  client.print("Content-Length: ");
  client.println(sensorValue.length());
  client.println();
  client.println(sensorValue);
}

```

Thank you for your help, I dont need a direct solution if you can point me to literatur that will help me solve this problem.

# Answer
> -1 votes
If found that you can also use UDP to do what I want.

---
Tags: esp8266, sensors, web-server, http
---


# Question
Title: How to Sort a String with Number by Ascending
I have trouble figuring out how to sort a String that has a Number in it.

The String im sending looks like 112:AAAA and 111:EEEE, how would I sort it so that the 111 will be the first in an array but (and here is what I cant figure out) the sorted array should contain the letters again so it would be a String Array that is sorted by the numbers and look like 111:EEEE, 112:AAAA.

I wanted to use what I have seen on C#, having a key and value, but that does not seem to exist in arduino code. So I improvised by writing everything in 1 char array.

edit: I see I'm mixing up char array and string, im very flexible and its no trouble to change to 1 or the other, currently I use char arrays.

I guess it would also be enough to just sort the strings, but i cant find a function for that also.

# Answer
> 2 votes
As Michel Keijzers points out, `qsort` is the standard sorting function from the libc. Now, since your numbers can start with either two or three digits, you can not sort them lexicographically, because if you did so 111 would sort before 82. Instead I suggest to:

* parse the start of the strings as integers
* compare the integers
* if the integers are equal, then sort the strings lexicographically.

The simplest way to parse the strings into integers is `atoi()`. Unlike functions like `strtol()`, `atoi()` does no error checking, but it is good enough if you know for sure that the strings have the right format.

Here is the comparison function:

```
int compare(const void *a, const void *b)
{
    // Get the strings.
    const char *sa = *(const char * const *) a;
    const char *sb = *(const char * const *) b;

    // First, compare the numeric prefixes.
    int ia = atoi(sa);
    int ib = atoi(sb);
    if (ia < ib) return -1;
    if (ia > ib) return +1;

    // If equal, compare the strings lexicographically.
    return strcmp(sa, sb);
}

```

And here is an example on how to use it:

```
#define STR_COUNT 3
const char *strings[STR_COUNT] = { "112:AAAA", "82:FFFF", "111:EEEE" };
qsort(strings, STR_COUNT, sizeof strings[0], compare);

```

Now the array of strings is sorted as ("82:FFFF", "111:EEEE", "112:AAAA").

# Answer
> 0 votes
You can use the `qsort` function (see c-library-function-to-do-sort).

With the user definable `comp` function you can get the first two or three characters, convert it to in integer and compare it against the converted integer from another element.

I would not advise to use strings, because of the limited SRAM storage of an Arduino, you might run out of memory too fast.

---
Tags: esp8266, string, array
---


title: How to get current Date

text:
# Question
Title: How to get current Date
How to get Current date, month and year. I have used RTC, NTPClient, but it didn't work. This gives default output of 1970. What can I do for fixing it.

```
time_t now = time(nullptr);
struct tm* newtime = localtime(&now);
String tmpNow = "";
tmpNow += String(newtime->tm_year + 1900);
tmpNow += "-";
tmpNow += String(newtime->tm_mon + 1);
tmpNow += "-";
tmpNow += String(newtime->tm_mday);
tmpNow += " ";

```

# Answer
An example how to use NTPClient is available at the projects github

```
#include <NTPClient.h>
// change next line to use with another board/shield
#include <ESP8266WiFi.h>
//#include <WiFi.h> // for WiFi shield
//#include <WiFi101.h> // for WiFi 101 shield or MKR1000
#include <WiFiUdp.h>

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

WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP);

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

  WiFi.begin(ssid, password);

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

  timeClient.begin();
}

void loop() {
  timeClient.update();

  Serial.println(timeClient.getFormattedTime());

  delay(1000);
}

```

Form what I found TimeRTC requires an external device called DS1307RTC to keep track of the time as shown in video here and with it we should be able to get the real time as seen in github example

```
#include <TimeLib.h>
#include <Wire.h>
#include <DS1307RTC.h>  // a basic DS1307 library that returns time as a time_t

void setup()  {
  Serial.begin(9600);
  while (!Serial) ; // wait until Arduino Serial Monitor opens
  setSyncProvider(RTC.get);   // the function to get the time from the RTC
  if(timeStatus()!= timeSet)
     Serial.println("Unable to sync with the RTC");
  else
     Serial.println("RTC has set the system time");
}

void loop()
{
  if (timeStatus() == timeSet) {
    digitalClockDisplay();
  } else {
    Serial.println("The time has not been set.  Please run the Time");
    Serial.println("TimeRTCSet example, or DS1307RTC SetTime example.");
    Serial.println();
    delay(4000);
  }
  delay(1000);
}

void digitalClockDisplay(){
  // digital clock display of the time
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.print(" ");
  Serial.print(day());
  Serial.print(" ");
  Serial.print(month());
  Serial.print(" ");
  Serial.print(year());
  Serial.println();
}

void printDigits(int digits){
  // utility function for digital clock display: prints preceding colon and leading 0
  Serial.print(":");
  if(digits < 10)
    Serial.print('0');
  Serial.print(digits);
}

```

If what I understand from your code you are actually not using any RTP or NTP. You are only creating a Time object with no values and you read it default values.

Check some more examples here
> 4 votes

---
Tags: esp8266, arduino-ide, nodemcu, rtc
---


# Question
Title: Can Chirp Waves be sent using JSN-SR04T?
So i have project for underwater rangefinding using JSN-SR04T. I've read on the datasheet that the module sends square waves. Is it possible to program it so that it sends Chirp waves instead ? (Help with the coding is very appreciated) Thanks in advance

# Answer
As I googled the sensor, I found various sites stating, that a JSN-SR04T behaves exactly like the HC-SR04. The difference is mainly the water prooving.

So the answer is: No, you can't do this. The square wave, which drives the ultrasonic transducers, is generated by a hardware circuit and is not meant to be changed. To output a chirp wave you would need to rebuild the signal generation and measurement hardware (leaving only the transducers unchanged). At that point you may just buy the pure ultrasonic transducers and build the rest yourself.
> 2 votes

---
Tags: arduino-uno, sensors
---


# Question
Title: What is the difference between a Hall effect sensor and an inductive one?
From what I have read, when placed within a magnetic field, a current will flow in both sensors.

My goal is to use this kind of sensors to guide a robot thanks to an existing automower loop wire, such as suggested in DIY Perimeter Wire Generator and Sensor.

I am thus wondering what is the difference between a Hall effect sensor and an inductive one such as the one described in the link above?

# Answer
> 2 votes
First they physically work differently. In the Hall effect sensor the electrons flowing through a plate will be deflected. Thus there will be a voltage perpendicular to the current, which can be measured. The voltage will be proportional to the magnetic field strengh. So you can sense a magnet, that is near the sensor, even if it doesn't move.

For the inductive sensor you have a guiding wire, that has an AC current flowing through it. This also means, that a magnetic field ist constantly building up and collapsing again around the wire. This change of magnetic field will induce an induction voltage in a nearby wire loop (the actual sensor). The frequency of that voltage is the same as of the guidance wire and the strength depends on the distance between the wires. So you are not measuring the magnetic field strength directly, but you measure how much it is changing (mathematically you differentiate).

Two different measurement methods which can be used to do the same thing. To guide a robot over a predefined course I would use the induction method (as long as the situation allows laying out wires), since it can be made less susceptible to noise. For that you can filter out all frequencies except of the used guiding frequency with a LC circuit. Or even better (though maybe not important) a lock-in amplifier. The hall sensor is an analog device, which can be very noisy.

---
Tags: arduino-nano, electronics, inductive, hall-effect
---


# Question
Title: MQTT with OLED realy :- display not coming properly
I am very new to Arduino/ESP and I am writing a code to activate 2 relays using MQTT. Also like to display status on OLED

here is my code

```
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <DNSServer.h>
#include <WiFiManager.h>
#include <PubSubClient.h>
#include <Wire.h>
#include "SSD1306Wire.h"
#define wifi_ssid "ssid"
#define wifi_password "wifipassword"
#define mqtt_server "192.168.1.1"
#define mqtt_user "username"
#define mqtt_password "password"

SSD1306Wire  display(0x3c, D2, D1);
const int relay1 = 5;
const int relay2 = 4;
String header;
String display_line2;
String output5State = "off";
String output4State = "off";
const int output5 = 5;
const int output4 = 4;

WiFiClient wificlient;
WiFiClient espClient;
PubSubClient client(espClient);
ESP8266WebServer server(80);

//------------------- MAIN WEB PAGE ------------------------
const char MAIN_page[] PROGMEM = R"=====(
<head><meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<title>HOME IOT</title>
<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}
.button { background-color: #195B6A; border: none; color: white; padding: 16px 40px
text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer
body{margin-top: 50px;} h1 {color: #444444;margin: 50px auto 30px;
.button2 {background-color: #77878A;
p {font-size: 24px;color: #444444;margin-bottom: 10px;}
</style>
</head>
<body>
<div id="webpage">
<h1>Security Door</h1>
<p><a href="/show/SecurityDoor/Open"><button class="button">Open</button></a></p>
<p><a href="/show/SecurityDoor/Close"><button class="button">Close</button></a></p>
</div>
</body>
</html>
)=====";
//------------------- MAIN WEB PAGE ------------------------

void setup() {
  Serial.begin(9600);
  //dht.begin();
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
  //-----------------------------------------
  WiFiManager wifiManager;
  //wifiManager.resetSettings();
  wifiManager.autoConnect("IOT-LivinRoom");
  //-----------------------------------------
  server.on("/", handle_OnConnect);
  server.onNotFound(handle_NotFound);
  server.begin();
  Serial.println("Initializing OLED Display");
  display.init();

  display.flipScreenVertically();
  display.setFont(ArialMT_Plain_10);
  Serial.println("HTTP server started");
}

void setup_wifi() {
  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(wifi_ssid);
  WiFi.begin(wifi_ssid, wifi_password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  String messageTemp;
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
    messageTemp += (char)payload[i];
  }
  Serial.println();

 if(strcmp(topic, "livingroom/securitydoor") == 0){
     Serial.print("Changing esp01 relay1 to ");
     if(messageTemp == "on"){
       digitalWrite(relay1, LOW);
       Serial.print("On");
       doorOpening();

     }
     else if(messageTemp == "off"){
       digitalWrite(relay1, HIGH);
       Serial.print("Off");
       doorClosing();
     }
 }
 Serial.println();

 if(topic=="livingroom/ac"){
     Serial.print("Changing esp01 relay2 to ");
     if(messageTemp == "on"){
       digitalWrite(relay2, LOW);
       Serial.print("On");
       doorOpening();

     }
     else if(messageTemp == "off"){
       digitalWrite(relay2, HIGH);
       Serial.print("Off");
       doorClosing();
     }
 }
 Serial.println();
}

void reconnect() {
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    if (client.connect("ESP8266Client", mqtt_user, mqtt_password)) {
      Serial.println("connected");
      client.subscribe("livingroom/securitydoor");
      client.subscribe("livingroom/ac");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

//--------------------------- void loop-----------------------
void loop() {

  server.handleClient();
  if (!client.connected()) {
    reconnect();
  }
  client.loop();

}

//----------------------------- Web Calls Function --------------------------------------
void handle_OnConnect() {
String s = MAIN_page; //Read HTML contents
server.send(200, "text/html", s);
}

void handle_NotFound(){
  server.send(404, "text/plain", "Not found");
}

//----------------------- LED display--------------------------------------

void doorOpening() {
  display.clear();
    display.setTextAlignment(TEXT_ALIGN_LEFT);
    display.setFont(ArialMT_Plain_24);
    display.drawString(0, 0, "Door");
    display.setFont(ArialMT_Plain_24);
    display.drawString(0, 28, "Opening");
  display.display();
}

void doorClosing() {
  display.clear();
    display.setTextAlignment(TEXT_ALIGN_LEFT);
    display.setFont(ArialMT_Plain_24);
    display.drawString(0, 0, "Door");
    display.setFont(ArialMT_Plain_24);
    display.drawString(0, 28, "Closing");
  display.display();
}

```

actually doorOpening() function is coming and doorClosing() function is not coming on OLED

again i am not very good in programming and arduino/esp8266

# Answer
i found the issue, actually relay pin was defined on D1 & D2 by mistake i connected oled to that pins
> 0 votes

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


title: 20 m LED WS2811 Pixel Stripe 12 V

text:
# Question
Title: 20 m LED WS2811 Pixel Stripe 12 V
i need some help for my masterthesis. I plan an Light and Sound installation and for this I decided to use the shape of an Dodecahedron and I want to put LED RGB Pixel Stripes on the surfaces to light the space. Imagine it like a huge ceiling light in shape of a half Dodecahedron.

What I have:

* 1 x Arduino Starter Kit
* 4 x RGB LED Pixel Stripe: BTF-LIGHTING WS2811, 5M, 60 LEDs/m, 300LEDs RGB, DC12V
    + (0,3W/LED = 90W/5 M (1 LED Stripe) = 360 W/20 M an in total 40A (4 LED Stripes))
* 2 x LED Stripe: Minger SMD 2835, 5m, 300 LEDs, Dimmable, 6000K Kaltweiß, DC12V (?)

The half of the Dodecahedron has 6 surfaces. Each surface gets like 300 to 350 cm RGB LEDs and 150 cm of Cold White.

My plan is to program the RGB LEDs with Strobe-Light (10 Hz) and changing colours and at the End of the installation the Cold White ("Daylight") is lighten up the space. (But this is another challenge for me ;))

How to connect all of them with my Arduino Uno? Any ideas? Thank you very much!

# Answer
So, addressable RGB LED strips. You can drive each string from an Arduino output, or daisy chain the signal thru all of them and just pump out the needed data using Adafruit Neopixel library, or the FastLED library. Make multiple power connections to keep the amount of 12V current going thru any one strip to a reasonable level.
> 0 votes

# Answer
Your big challenge is going to be power. Sum up the current requirements of ALL of your LED strips. Find a power supply that puts out ≈20% more than that. Read up on the max power you can pass through each strip, You can daisy-chain the power on multiple strips up to the current handling ability of the strips. Say the docs say a strip can pass max 5A through it, and each draws 1A. So you could chain the power connections of 5 of them one to the next, but no more than that. Also make sure you use power wire that's rated for your current needs. Remember your ground wires need to be heavy enough for your current needs as well. (The signal wires can be much lighter gauge.)

The signal lines don't need to follow the same topology as the power connections, but it's simpler to wire up if they do. (You could make the control lines of ALL of the LED strips in one long "snake" but run the power wires in a star pattern so the power wires don't exceed the current carrying limits of the strips or of your power wires. You could also wire both the power and the signal lines in a star pattern, and drive each point of the star with a separate Arduino pin.) You should be able to find a **chart online that gives you the current carrying ability of different gauges of wire**. There, too, use wire that's rated a little over the current need, just to be safe. (That chart also talks about maximum length of wire to keep the voltage drop below 2%, which is a good idea.)
> 0 votes

---
Tags: arduino-uno, led, neopixel
---


title: Ultrasonic Sensor - JSN-SR04T 2.0

text:
# Question
Title: Ultrasonic Sensor - JSN-SR04T 2.0
I would like to use the JSN-SR04T 2.0 in order to find the depth of a body of water. Once I test the sensor in a body of water, the distance measurements are then constant at about 20 cm. I then changed my distance formula to account for the speed of sound in water, but the measurements are still constant despite change in the body of water. Does anyone have any recommendations on how to obtain better measurements underwater?

```
#define trigPin 2
#define echoPin 3

// Define variables:
long duration;
int distance;

void setup() {
  // Define inputs and outputs
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);

  // Begin Serial communication at a baudrate of 9600:
  Serial.begin(9600);
}
void loop() {
  // Clear the trigPin by setting it LOW:
  digitalWrite(trigPin, LOW);

  delayMicroseconds(5);
 // Trigger the sensor by setting the trigPin high for 10 microseconds:
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  // Read the echoPin. pulseIn() returns the duration (length of the pulse) in microseconds:
  duration = pulseIn(echoPin, HIGH);

  // Calculate the distance:
  distance = duration*0.034/2;

  // Print the distance on the Serial Monitor (Ctrl+Shift+M):
  Serial.print("Distance = ");
  Serial.print(distance);
  Serial.println(" cm");

  delay(100);
}

```

# Answer
> 1 votes
According to the data sheet the minimum target distance is 20cm in the open air at a 343 m/s

The speed of sound in water is 1481 m/s so the minimum distance would be 20cm x 1481 / 343 = 86cm.

You cannot measure distances under 83cm in water.

---
Tags: arduino-uno, sensors
---


# Question
Title: Interrupt is activated as soon as I insert a jumper wire into the port
I have written a very simple code to test the interrupt functionality of my Arduino Uno expansion board:

```
const byte buttonPin3 = 3;

void setup() {
  pinMode(buttonPin3, INPUT);
  attachInterrupt(digitalPinToInterrupt(buttonPin3), trigger, CHANGE);

  Serial.begin(9600);
}

void loop() {
}

void trigger(){
  Serial.println("trigger");
}

```

However, the `Serial.println("trigger");` is activated as soon as I insert a jumper wire into pins 2 or 3. It seems like I have broken the microcontroller. I would appreciate if you could help me know if there is something wrong with my code or I need to change the microcontroller? if I have to replace the MCU can I just use any identical AVR and just place it on the DIP IC socket adaptor?

**P.S.** Filip Franik asked me to draw the schematics:

simulate this circuit – Schematic created using CircuitLab

**P.S.** I used the official Button's tutorial and now everything works just fine. I can't reproduce the issue anymore for no obvious reason!.

# Answer
Connect both Pin2 and Pin3 with two 1K resistors to ground.

When a pin that's set as INPUT is "floating" (it's not connected to anything) the value on it is "undetermined" and interrupt can trigger when a neighboring pin status changes, or even just magically by itself. The 1K resistors (called pulldown resistors) will make sure that pin is set to LOW when it's not connected using the jumper.

This circuit should put a stable 0V on Pin3 when switch is unpressed and 5V when it's pressed. You should be able to verify that using any voltage meter.

If the issue persists then swapping the microcontroller on the Arduino is just one of the steps you need to perform. You would also need to burn a bootloader on the chip. It's not a hard procedure but it requires a second Arduino.
> 2 votes

# Answer
CMOS inputs "float" when not connected to anything, and will give semi-random values. You can either connect the pin to ground via a medium value resistor (1kΩ-10kΩ), or set the pin to INPUT\_PULLUP mode.

You shouldn't move the interrupt pin connections around while the Arduino is running. As soon as you disconnect the wire from the input, it begins floating again, and can detect semi-random HIGH/LOW values.

If you use an external pull-down resistor, put a connector after the ground connection and move that connection, so the pull-down resistor is always connected to the pin.

If you use INPUT\_PULLUP mode, you should not use a pull down or pull up resistor. This mode connects the pin weakly to +5V, which will hold it at a HIGH value when not connected to anything. You would then ground it to trigger an interrupt. In INPUT\_PULLUP mode you can probably disconnect the wire from the interrupt pin without triggering interrupts.
> 1 votes

---
Tags: interrupt, testing
---


# Question
Title: How to decrease delay for String concatenation + Arduino Due
In my project I need to add a delimiter between integer numbers. In the following code. I add a "," between integer numbers obtained from inputsig matrix. The problem is that concatenation of these numbers with concat() command for a Matrix with 100 rows and 9 columns takes 10 ms. Is there any efficient way to decrease this delay?

```
#include <CStringBuilder.h>

int Max_pack_size = 100;

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

  while (!SerialUSB) ;

}

void loop() {

  String  datas1;
  String  inputsig[Max_pack_size][9];
  char buff[((8+1)*Max_pack_size+1)*9];
  CStringBuilder sb(buff, ((8+1)*Max_pack_size+1)*9);

  for (int i = 0; i < Max_pack_size; i++)
  {
    for (int j = 0; j < 9; j++)
    {
      inputsig[i][j] = 16777215;

    }
  }

  int t0 = micros();

  for (int i = 0; i < Max_pack_size; i++)
  {
    for (int j = 0; j < 9; j++)
    {
      //datas1.concat(inputsig[i][j]);
      //datas1.concat(",");
  sb.print(inputsig[i][j]);
  sb.print(F(","));
    }
  }

 SerialUSB.println(float(micros() - t0));
 delay(1000);

 SerialUSB.println(buff);

}

```

# Answer
I don't have Arduino Due but I have an Arduino Uno so I had to adjust the code to run with much smaller RAM and use the standard Serial.

This is the original code as you can see i can use only Max\_pack\_size of 5

```
#include <CStringBuilder.h>

int Max_pack_size = 5;

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

void loop() {

  String inputsig[Max_pack_size][9];
  char buff[((8 + 1)*Max_pack_size + 1) * 9];
  CStringBuilder sb(buff, ((8 + 1)*Max_pack_size + 1) * 9);

  for (int i = 0; i < Max_pack_size; i++)
  {
    for (int j = 0; j < 9; j++)
    {
      inputsig[i][j] = 16777215;
    }
  }

  int t0 = micros();

  for (int i = 0; i < Max_pack_size; i++)
  {
    for (int j = 0; j < 9; j++)
    {
      sb.print(inputsig[i][j]);
      sb.print(',');
    }
  }

  int t1 = micros();

  Serial.println(float(t1 - t0) / 1000.0);
  delay(1000);

  Serial.println(buff);
}

```

The timer displays values around 2.08 milliseconds for the code above.

First optimization attempts is to stop using StringBuilder. Everything that's written to be universal and easy to use is usually slow.

Note that when we generate `String` from `long` the implicit cast allocates `char buf[2 + 3 * sizeof(long)];` so the max length of such string is 14 characters. String is of course terminated by null character `'\0'`

```
#include <CStringBuilder.h>

int Max_pack_size = 5;

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

void loop() {

  String inputsig[Max_pack_size][9];
  char buff[((8 + 1)*Max_pack_size + 1) * 9];

  for (int i = 0; i < Max_pack_size; i++)
  {
    for (int j = 0; j < 9; j++)
    {
      inputsig[i][j] = 16777215;
    }
  }

  int t0 = micros();

  int p = 0;
  for (int i = 0; i < Max_pack_size; i++)
  {
    for (int j = 0; j < 9; j++)
    {
      for (int k = 0 ; k < 14; k++)
      {
        char c = inputsig[i][j][k];

        if (c == 0)
          break;
        else
          buff[p++] = c;
      }

      buff[p++] = ',';
    }
  }

  int t1 = micros();

  Serial.println(float(t1 - t0) / 1000.0);
  delay(1000);

  Serial.println(buff);
}
}

```

Now the timer displays 0.86 milliseconds. Much better, but we can improve even more!

Let's drop the String. It's just an over complicated wrapper for a char array anyway.

```
#include <CStringBuilder.h>

int Max_pack_size = 5;

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

void loop() {

  char inputsig[Max_pack_size][9][14];
  char buff[((8 + 1)*Max_pack_size + 1) * 9];

  for (int i = 0; i < Max_pack_size; i++)
  {
    for (int j = 0; j < 9; j++)
    {
      ltoa(16777215, inputsig[i][j], 10);
    }
  }

  int t0 = micros();

  int p = 0;
  for (int i = 0; i < Max_pack_size; i++)
  {
    for (int j = 0; j < 9; j++)
    {
      for (int k = 0 ; k < 14; k++)
      {
        char c = inputsig[i][j][k];

        if (c == 0)
          break;
        else
          buff[p++] = c;
      }

      buff[p++] = ',';
    }
  }

  int t1 = micros();

  Serial.println(float(t1 - t0) / 1000.0);
  delay(1000);

  Serial.println(buff);
}

```

Now the timer shows 0.50 milliseconds. So we optimized the code to the point it runs 4 times as fast.
> 1 votes

---
Tags: arduino-due, string
---


title: nodemcu GPIO6 clock

text:
# Question
Title: nodemcu GPIO6 clock
is there a way that i can declare gpio6 (CLK) as an input without getting a wdt reset? I'm somewhat new to circuitry, but my boss wants to use it(GPIO6) to talk with external devices. I have more pictures of the schematics if you think that it would help.

# Answer
No. There is no way you can use it (or not without a lot of messing around...).

According to the ESP8266 GPIO Reference Guide:

> GPIO6 to GPIO11 are usually connected to the flash chip in ESP8266 boards. So, these pins are not recommended to use.

If you mess with those pins you won't be able to access the flash chip - and that means that you can't run code. And of course that means that the watchdog then times out.

I say that you can't "without a lot of messing around", because theoretically it *could* be possible if you had a function resident in RAM which reconfigured the pins, then did whatever was needed with them (taking into account the fact that there's a flash chip connected there...), then afterwards reconfigure the pins back to working in XIP SPI Flash mode. But that's not something I would like to even contemplate doing.
> 3 votes

# Answer
No you can't. Refer to this: https://tttapa.github.io/ESP8266/Chap04%20-%20Microcontroller.html

However as that article states there is a dedicated SPI set of pins on the esp8266 so you should be able to use that?

From your circuit diagram I see this might not be an option for you as you seem to have most of the pins allocated to a different function.

Your best and most robust solution would probably be to have a separate microcontroller chip handling your I2C and SPI requirements, using the Esp8266 UART functionally to provide your wireless capabilities.

As a side note why do you have so many clock lines?
> 1 votes

---
Tags: esp8266, nodemcu, reset
---


# Question
Title: Syntax for stopping loop until the condition has made false
I am taking reading from temperature sensor and from that data. I have to control 3 LEDs. Lets consider LED1, LED2, LED3.

```
If temperature range between 0-20
   I have to HIGH LED2.
   else if temperature range between 20-30
I have to HIGH LED1; HIGH LED3; LOW LED1;

```

my sketch is something like this:-

```
while(1)
{
if(temp>=0&&temp<=20)
{
digitalWrite(2,HIGH);
}
else if (temp>=20&&temp<=30)
{
digitalWrite(1,HIGH);
digitalWrite(3,HIGH);
digitalWrite(1,LOW);
}
}

```

The problem which I am facing is LED1 is continuously ON (which should be OFF), when temperature is between 20-30 because of continuously running loop so, how can I stop loop, once the statement under second condition has executed till the second condition has made false.

# Answer
Your code doesn't make sense. You have a `while (1)` statement, which will run forever. Inside the body of that statement, you never change the value of `temp`.

An Arduino sketch's `loop()` function runs continuously. You should not have a `while (1)` loop inside your loop function. You should have a loop function something like this:

```
void loop() {
  temp = //read a temp value somehow
  if(temp>=0&&temp<=20)
  {
    digitalWrite(2,HIGH);
  }
  else if (temp>=20&&temp<=30)
  {
    digitalWrite(1,HIGH);
    digitalWrite(3,HIGH);
    digitalWrite(1,LOW);
  }
}

```

With that loop function you would fetch a new value of temp on each pass through the loop, then decide what LEDs to light.
> 2 votes

# Answer
You don't want to stop the loop! You want it to run fast and often.

Eventually you want it to not change the current state of a LED, but in your case, I rather do not see enough defined states of LEDs.

> I want to first ON LED1 then ON LED2 then OFF LED1"

if `then` means an amount of time, remember that loop runs fast and does not take time by itself. You will have to notice the starting point in time and compare that with the current time and your desired intervals. (And you do not mention what should happen to LED2 after the second *then* )

```
const unsigned int LED1_DURATION=500;
const unsigned int LED3_DURATION=1000;
bool c2 = false;  // true while condition2 is met
unsigned long start2;  // time when condition2 starts
void loop() {
  int temp = analogRead(A0); //read a temp value somehow
  if(temp<=20)
  {
    digitlaWrite(1, LOW);
    digitalWrite(2,HIGH);
    digitlaWrite(3, LOW);
    c2 = false;
  }
  else if (temp >20 && temp <= 30)
  {
     digitalWrite(2, LOW);

     if (c2 == false) { c2 = true; start2=millis(); } // detect start time

     if ((millis() - start2 < LED1_DURATION) ||
         (millis() - start2 > LED3_DURATION)   )
          digitalWrite(1,HIGH);
     else digitalWrite(1, LOW);

     if ((millis() - start2 > LED1_DURATION) &&
         (millis() - start2 < LED3_DURATION)    )
          digitalWrite(3,HIGH);
     else digitalWrite(3,LOW);
  }
  else
  {
    digitlaWrite(1, LOW);
    digitalWrite(2, LOW);
    digitlaWrite(3, LOW);
    c2 = false;
  }
}

```

This code contains a couple of guesses about states you did not mention, and a slightly different behavior (sorry), but I hope you get an idea...
> 2 votes

---
Tags: temperature-sensor, loop
---


title: Sending file from PC to Arduino

text:
# Question
Title: Sending file from PC to Arduino
How can i send a (file) from PC to Arduino Yun at running time ?

There's a way to send some commands via Serial. But how would a whole file goes ? Assuming the file can take place at RAM without any problems.

Thanks

# Answer
You can send a file, byte after byte, using Serial. On the Arduino side, you parse serial communication and put bytes inside an array. At the end, you reconstruct the file.
> 1 votes

# Answer
The first question is what do you want to do with your image : Arduino Yun has a Linux chip & an Arduino chip. And I don't think that image treatment must happen in the Arduino side... So you can send your image with scp to Linux side, then do what you want with it and perhaps, eventually, send the result for action to the Arduino part.
> 0 votes

# Answer
Back in the mists of time (late 1990s, if anyone's counting), there existed a file transfer protocol called XMODEM that was used to send a file across a link normally used for a terminal, on small, publicly available systems known as Bulletin Board Systems, or BBSes. XMODEM divided a file into packets of 129 bytes, sent and acknowledged one packet at a time. It had a simple 8-bit checksum to verify the file contents which was just "ok" over a reasonably reliable line, line and inadequate on a noisy one. But it was one of the first experimenter-built and widely used protocols.

As it was pushed harder and harder (larger file sizes, higher line speeds intolerant of the small, single-packet handshake) and its weaknesses became more problematic,a number of derivatives were developed to address the weaknesses.

ZMODEM was one of those, which allowed the sender a "sliding window" of packets, so it could keep sending packets (up to the window maximum) without stopping to wait for each acknowledgement, and could use larger packet sizes, among other improvements.

They are relatively easy to implement, XMODEM more-so, and source code or specs can be found by looking around.

If your files aren't horrendously large and the lines are fairly reliable, even XMODEM may be adequate.
> 0 votes

---
Tags: serial, arduino-yun, serial-data
---


title: WiFi connection in loop function

text:
# Question
Title: WiFi connection in loop function
What I am trying to do is while connected locally in the esp8266 and give it a ssid and password, save them in a global variable and use them to start a connection inside loop function with a flag so it happens only once and let the program run while I check when the connection is complete. Do you foresee any problems with this application?:

```
setup(){
    wifi.mode(WIFI_AP_STA);
    setup softAP
    server.on("/",handleroot)
    server.begin()
}
loop(){
    server.handleClient()
    if(credential_submited){
        Wifi.begin(credentials);
        flag_connection_started =true;
        credential_submited = false;
        flag_for_internet_server=true;
    }
    if(WiFi.status()==WL_CONNECTED && flag_for_internet_server==true){
        server.on("/",handleroot)
        server.begin()
        flag_for_internet_server=false;
    }

```

I know there is also WifiManager But I am trying to do it on my own. The thing is some wifi networks take a lot of time to connect. More precisely they connect but then the esp doesn't get an ip and disconnects. Thank you for your time

# Answer
WiFi.begin() in ESP8266WiFi library doesn't wait until the connection completes, it returns immediately.

You can check if the connection to WiFi network is established using WiFi.status() as most of the examples show. And it is not mandatory to wait for the connection in setup().

BTW: You can use a separate sketch to set the SSID and password in esp8266 and then in all other sketches not use WiFi.begin(), only wait for the connection to WiFi network to finish.
> 0 votes

# Answer
This is not a big deal...

You can do it vary easily, the most simple way is that you can use EEPROM to achieve this..

Simply pass the SSID and PASSWORD of new network to ESP8266 and save it in EEPROM and also create a new variable in eeprom that store the status that new network credentials is entered or not and check it in loop and then fetch new network credentials from the EEPROM and try to connect to it...

You can also check and connect to your desired network from the loop...

Or alternatively you can use the library that can help you in doing that \[WiFiManager\]: https://github.com/tzapu/WiFiManager
> -1 votes

---
Tags: esp8266, wifi
---


title: NodeMCU max draw

text:
# Question
Title: NodeMCU max draw
1) what is the max draw I can draw from NodeMCU V3 logic and 5v pins? 2) Also, I heard i draw with it more than 500mA, the PC USB port stops working. Is that information actual? Because USB 3 port has 900mA and USB 2 had 500mA max

# Answer
> 1 votes
for ESP8266 (which your NodeMCU is based upon) , the maximum current is about 20mA sinking and 12mA sourcing per \[single\] pin. so the maximum current of all GPIOs together is a lot lower than the 500mA USB limits.

you have to use external drivers (transistors, MOSFETs) for that purpose.

**Sink current**: the current which is provided when you pull the pin LOW. e.g. when you provide GND for the cathode of an LED. (the Anode is connected to VCC).

**Source current**: the current which is provided when you pull the pin HIGH. e.g. when you provide VCC for the anode of an LED. (the cathode is connected to GND).

*the difference is for different internal resistance for identical N-MOS/P-MOS, due to their structure. that's why many devices like 7segment drivers, or motor drivers supply GND for the Load (common anode drivers) instead of VCC.*

---
Tags: esp8266, nodemcu
---


title: Is ATMEGA328P the same as 16U2?

text:
# Question
Title: Is ATMEGA328P the same as 16U2?
I've been playing with my Arduino for a few months.

But, I just bought a shield that says it needs to be used with ATMEGA328P. My box says I have a 328P, however, reading the chip, it's inscribed with "ATMEL MEGA16U2".

Does that mean the box is wrong, or is that the same as 328P somehow?

Thanks!!

# Answer
> 4 votes
The 16u2 is related to the ATmega328p, and includes USB, but is more limited in resources. While it would be *possible* to make an Arduino-type board from alone, this is unlikely to be what you have.

Rather, it is likely that you have a board with an ATmega328p as the main processor, and *also* a 16u2 which serves as a USB interface for it.

You could know for sure from what board type you select in the dropdown menu of the Arduino IDE. If you are selecting something like "Uno" or "Duemilanove" you have a 328p as the main processor.

(The other presently common type of board is the "Leonardo" style where a 32u4 - essentially a bigger version of the 16u2 - is used as a single-chip solution that is both the primary processor and the USB interface. But if that is what you had, it would not say 16u2 on it, unless it was an attempt to make a more limited "budget" version).

# Answer
> 3 votes
the 328p is the microcontoller. It's the larger chip located in the middle of the arduino board surface. This one handles the code/ sketch/ programme that you write). The 16u2, on the other hand, is the smaller chip located near the USB port. This handles data communication through the USB port.

---
Tags: arduino-mega
---


title: L298N motor driver issue

text:
# Question
Title: L298N motor driver issue
I am facing the same issue with my motor driver. Initially I ran the code and connected the L298N with Arduino and it worked fine. At that time motors were running absolutely fine. But when I ran it sometimes later then the motors are not running. However the motors are getting power but I think thy are getting very less power from the Motor Driver.

I directly ran motors from Arduino +5V pin and the motors were running fine. Is there something wrong with my L298N motor driver?

One more thing I checked the power for all the pins for L298N motor Driver and all pins are working fine.

Here is my complete program:

```
const int MOTOR_RIGHT = 1;
const int MOTOR_LEFT =  2;
const int MR_CONTROL_PIN_A = 8;
const int MR_CONTROL_PIN_B = 9;
const int ML_CONTROL_PIN_A = 10;
const int ML_CONTROL_PIN_B = 11;

void setup() {
  // These two pins will act as output pin

  pinMode(MR_CONTROL_PIN_A,OUTPUT);
  pinMode(MR_CONTROL_PIN_B,OUTPUT);
  pinMode(ML_CONTROL_PIN_A,OUTPUT);
  pinMode(ML_CONTROL_PIN_B,OUTPUT);
  Serial.begin(4800);

}

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

  forward(MOTOR_RIGHT);
  forward(MOTOR_LEFT);
  delay(5000);
  stopMotor(MOTOR_RIGHT);
  stopMotor(MOTOR_LEFT);
  delay(1000);
  backward(MOTOR_RIGHT);
  backward(MOTOR_LEFT);
  delay(5000);
  stopMotor(MOTOR_RIGHT);
  stopMotor(MOTOR_LEFT);
  delay(1000);

}
/////////////////////////////////////////////////////////////////////
//Forward

  void forward(int motorNo)
  {

  Serial.print("\r\n Forward : ");
  Serial.print(motorNo);

  switch(motorNo)
  {
    case MOTOR_RIGHT:
    digitalWrite(MR_CONTROL_PIN_A,HIGH);
    digitalWrite(MR_CONTROL_PIN_B,LOW);
    break;

    case MOTOR_LEFT:
    digitalWrite(ML_CONTROL_PIN_A,HIGH);
    digitalWrite(ML_CONTROL_PIN_B,LOW);
    break;

  default:
    Serial.print("\r\n Error :Invalid Motor No ");
    Serial.print(motorNo);
   }
  }

//////////////////////////////////////////////////////////////////////
  void backward(int motorNo)
  {
   Serial.print("\r\n Backward : ");
   Serial.print(motorNo);
  switch(motorNo)
  {
    case MOTOR_RIGHT:
    digitalWrite(MR_CONTROL_PIN_A,LOW);
    digitalWrite(MR_CONTROL_PIN_B,HIGH);
    break;

    case MOTOR_LEFT:
    digitalWrite(ML_CONTROL_PIN_A,LOW);
    digitalWrite(ML_CONTROL_PIN_B,HIGH);
    break;

  default:
    Serial.print("\r\n Error :Invalid Motor No : ");
    Serial.print(motorNo);
   }

  }

///////////////////////////////////////////////////////////////////////
  void stopMotor(int motorNo)
  {
   Serial.print("\r\n STOP : ");
   Serial.print(motorNo);
  switch(motorNo)
  {
    case MOTOR_RIGHT:
    digitalWrite(MR_CONTROL_PIN_A,HIGH);
    digitalWrite(MR_CONTROL_PIN_B,HIGH);
    break;

    case MOTOR_LEFT:
    digitalWrite(ML_CONTROL_PIN_A,LOW);
    digitalWrite(ML_CONTROL_PIN_B,LOW);
    break;

  default:
    Serial.print("\r\n Error :Invalid Motor No : ");
    Serial.print(motorNo);
   }

  }

```

Is there something wrong with my L298N ? How can I test it?

# Answer
> 1 votes
The specified minimum voltage for the motors is **2.5 volts higher than the logic supply**.

You need to use a separate supply for the motor that is higher than the logic power.

# Answer
> 0 votes
9 volt batteries have very low capacity. That could be the cause of your problem. Replace the battery with a power supply with higher capacity. Or other bigger batteries that add up to around 9 volts.

---
Tags: motor, l298n
---


# Question
Title: Arduino stops working when servo makes a few rotations
The sketch rotates servo back and forth with buttons. When I rotate servo MG 995/996R 2-4 times Arduino stops working. Its voltage step-down transformer switches from ~9V to ~3.7V which is not enough for Arduino. To make it work again, I must turn off-on the device.

There is no such a glitch with smaller servos such as SG90.

# Answer
Ground loops can be bad. Do follow up as suggested in the comments regarding ensuring the power supply grounds are the same. To be specific, connecting the power supply grounds through the Arduino is a bad idea! The trace size should not be assumed adequate for the unknown amount of current passing between the ground outputs of the power supplies. And a voltage potential can develop causing the processor to behave unexpectedly or worse burn out components.

Also, consider that some Arduino platforms regulate power to 5 volts on the board and that many servos run fine at 5 volts. If this is true here, you could greatly simplify and possibly solve the describe problem by using a single 5 volt power supply.

Lastly, ensure there is a pull up on the 2 inputs connected to the (assumed) normally-open-momentary-contact switches. There are none in the diagram. So it is assumed pull ups have been activated in the code such as explained here.
> 1 votes

---
Tags: arduino-nano, servo
---


title: Did I kill my ESP8266?

text:
# Question
Title: Did I kill my ESP8266?
So I've been playing with the esp8266 controller lately and today my Usb Host Mini came in that I wanted to connect. So for this I followed the following tutorial https://www.hackster.io/139994/plug-any-usb-device-on-an-esp8266-e0ca8a

The only thing is that I didn't do the following, because I wanted to see that it actually wouldn't work without damaging the Usb Host Mini.

Now I am wondering, because I didn't do that, and just went on with the wiring, did I actually kill my ESP8266 now? Whenever I remove all the wires, and just connect the ESP8266 to my computer, it just won't show up in the ports.

If I did kill it, what did I actually do here? Did I allow 5V to run through the board and did I fry it that way? If I would've actually made the cut shown above, would it have lived? (Because I think what the cut does, is it stops the 5V from going through the circuit.)

# Answer
> 2 votes
Well if it doesn't work then it doesn't work so a safe bet is that chip is damaged.

I found this document. It states:

> **VBUS pad and jumber** can be used to provide 5V to VBUS. By default VBUS is connected to 3.3V; certain USB devices may have issue with this.

So I deduce that this is connected directly to 3.3V rail of the chip. Providing 5V without opening the jumper (cutting the trace) is the same as putting 5V at the 3.3V pin.

> **3.3V.** Power pin of the shield. Do not supply 5V to this pin - MAX3421E won't be able to detect devices on VBUS and may also be damaged!

Apparently the "proper" way of doing things is to actually unsolder that jumper or cut the trace.

Sorry.

---
Tags: esp8266
---


# Question
Title: Arduino accepting only alternate characters
I am writing an Arduino code to receive SMS from a SIM800 module and then send the same message back to the sender. My code is as follows:

```
#include<SoftwareSerial.h>

SoftwareSerial mySerial(9, 10);//Connect to pin 9&10 on GSM module

const byte numChars = 128; //character size
char receivedChars[numChars]; // Store data read from SMS
boolean newData = false; //flag to check if new data has arrived

void setup() {
 Serial.begin(9600);
 mySerial.begin(9600);
 Serial.println("<Arduino is ready>");
 mySerial.println("AT");
 mySerial.println("AT+CMGF=1"); //text mode
 mySerial.println("AT+CNMI=1,2,0,0,0");
 mySerial.println("AT+CSQ"); //Check signal strength
   while (Serial.available())
  {
    mySerial.write(Serial.read());//Forward what Serial received to Software Serial Port
  }
  while(mySerial.available())
  {
    Serial.write(mySerial.read());//Forward what Software Serial received to Serial Port
  }
}

void loop() {
  //code for checking sms
  scanSMS();
  //Print if a new data arrived
  showNewData();
  delay(25000);
}

void scanSMS() {
    static boolean recvInProgress = false;
    static byte ndx = 0;
    char startMarker = '#'; //Start and end markers. Eg. SMS body will be sent as #status#
    char endMarker = '#';
    char rc;
    while (Serial.available())
    {
      mySerial.write(Serial.read());//Forward what Serial received to Software Serial Port
    }

    while (mySerial.available() > 0 && newData == false) {
      Serial.write(mySerial.read());//Forward what Software Serial received to Serial Port

      rc = mySerial.read();

      if (recvInProgress == true) {
        if (rc != endMarker) {
          receivedChars[ndx] = rc;
          ndx++;
          if (ndx >= numChars) {
            ndx = numChars - 1;
          }
        }
        else {
          receivedChars[ndx] = '\0'; // terminate the string
          recvInProgress = false;
          ndx = 0;
          newData = true;
          }
        }
      else if (rc == startMarker) {
        recvInProgress = true;
      }
    }
}

/*PRINT IF THERE IS A NEW DATA*/
void showNewData() {
 if (newData == true) {
   SendMessage(receivedChars);
 newData = false;
 }
}

/*SEND BACK WHATEVER SMS IS RECEIVED*/
void SendMessage(String receivedChars)
{
  Serial.print("here");
  mySerial.println("AT+CMGS=\"+xxxxxxxxxx\"\r"); // Replace x with mobile number
  mySerial.println("Humidity Alert!");// The SMS text you want to send
  mySerial.print(receivedChars);
   mySerial.println((char)26);// ASCII code of CTRL+Z
}

```

The issue is that the module seems to receive only alternate characters instead of the whole message. For example, if I send the text #program#, the Arduino will only print porm or rga. Am I missing something here? Any help is highly appreciated.

# Answer
You wrote:

```
Serial.write(mySerial.read());
rc = mySerial.read();

```

Here you are calling `mySerial.read()` twice, and thus reading two characters from the port's input buffer. You then forward the first character through `Serial`, and process the second one. Note that you should normally not read two characters unless you have tested that `mySerial.available() >= 2`.

You probably want to forward and process one character at a time, thus only call `mySerial.read()` once within this loop:

```
rc = mySerial.read();  // read from mySerial
Serial.write(rc);      // forward through Serial
// now process rc

```
> 2 votes

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


# Question
Title: Multi dimming led - figuring out which led is available for dimming
TL;DR: I tried to have a random fading pattern on several leds and it leads to flickering.

Edited following @chrisl answer.

I am in the process of creating a simple lamp that show some light patterns using 6 led and an arduino uno. The goal is that depending on some inputs and a bit of randomisation, the patterns will change. For instance, only 2 lights at the same time but fading up and down randomly on all 6 led. Or 4 lights fading up and down randomly on the 6 leds.

I decided to create a struct that would be a light pattern named a particle, and this particle have a variable named led\_position that shows which led it is on at a certain moment. The particle can change its position to light up an other led.

I know this is not the clearest of explanation but I hope my code will be more straightforward:

Main code #include "MyTypes.h"

```
int led1 = 9;    // the PWM pin the LED is attached to
int led2 = 10;
int led3 = 11;
int led4 = 6;
int led5 = 3;
int led6 = 5;

//int led;
int brightness;
int fadeAmount;

// Definition of the different particles
particle_type particle[]={
  { 0,led1,0, 2,   false },
  { 1,led2,50, 2,   false },
  { 2,led3,100,  2,   false },
  { 3,led4,80,  2,   false },
  { 4,led5,30,  2,   false},
  { 5, led6,70,  2,   false},
};

led_type led[]={
  { 3,false },
  { 5,false },
  { 6,false },
  { 9,false },
  { 10,false },
  { 11,false },
};

//initiation of the particles

void initiate_particle(particle_type& particle_example,led_type led[]){

 //take a random led from list of led
  int number=random(5);
  led[number];
  if (led[number].busy == false){ //if led non-occupied
    particle_example.led_position=led[number].led_position;
    led[number].busy = true ;//take this led as output
    }

  else{
//    particle_example.led_position=particle_example.led_position; //keep same led
  }

  particle_example.reset = false; //reset turned off
 // delay(30);

}

void update_light(particle_type& particle_example,led_type led[]){ //updating led brightness

  analogWrite(particle_example.led_position, particle_example.brightness);  //updating led brightness
  if (particle_example.brightness >=  160) {
    particle_example.fadeAmount = -particle_example.fadeAmount;

  }

  if (particle_example.brightness <=  160 && particle_example.brightness >=  100 ) {
    particle_example.brightness = particle_example.brightness + 2*particle_example.fadeAmount;

  }

  if (particle_example.brightness >= 50 && particle_example.brightness <=  100){
      particle_example.brightness = particle_example.brightness + particle_example.fadeAmount;

  }

  if (particle_example.brightness >= 0 && particle_example.brightness <=  50){
      particle_example.brightness = particle_example.brightness + 0.5*particle_example.fadeAmount;

  }

  if (particle_example.brightness <= 0){
    particle_example.reset= true;
    int number = particle_example.led_position;
    led[number].busy=false;
    particle_example.fadeAmount = -particle_example.fadeAmount;
  }

}

void activate_particle(particle_type& particle_example,led_type led[]){ //function to keep led activated

  if (particle_example.reset==true){ //if led not initiated or has finished its dimming down
    initiate_particle(particle_example, led); //initiate it again
  ;}

  else {
   update_light(particle_example,led); //update its brightness
  }
}

void setup() { //create led outputs

  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);
  pinMode(led5, OUTPUT);
  pinMode(led6, OUTPUT);
  Serial.begin(9600); //serial for debug

}

void loop() {

  activate_particle(particle[0],led);
//  activate_particle(particle[1],led);

//  activate_particle(particle[2],led);
//  activate_particle(particle[3],led);
//  activate_particle(particle[4],led);
//  activate_particle(particle[5],led);
//

 delay(5); // 20-17-15-12-10-7-2

}

```

Mytypes.h

```
typedef struct {
    int id;
    int led_position;
    int brightness;
    int fadeAmount;
    bool reset;
} particle_type;

typedef struct {
    int led_position;
    bool busy;
} led_type;

```

This seems to work more or less but I still have the problem of particles "choosing" the same led to light up and it make the led flickers.

I am struggling on this. I have tried to add a data field for busy and create a new struct for led to no avail.

Even when only one particle is on, the different leds seems to deactivate after a few rounds.

Let me know if you figure it out, thanks!

EDIT 2:

```
    #include "MyTypes.h"

int led0 = 3;    // the PWM pin the LED is attached to
int led1 = 5;
int led2 = 6;
int led3 = 9;
int led4 = 10;
int led5 = 11;

//int led;
int brightness;
int fadeAmount;

// Definition of the different particles
particle_type particle[]={
  { 0,led0,0, 4,   false },
  { 1,led1,50, 4,   false },
  { 2,led2,100,  4,   false },
  { 3,led3,80,  4,   false },
  { 4,led4,30, 4,   false},
  { 5,led5,70,  4,   false},
};

led_type led[]={
  { 3,false },
  { 5,false },
  { 6,false },
  { 9,false },
  { 10,false },
  { 11,false },
};

//initiation of the particles

void initiate_particle(particle_type& particle_example,led_type led[]){

 //take a random led from list of led
  int number=random(6);
  Serial.println(number);
  led[number];
  if (led[number].busy == false){ //if led non-occupied
    for (int i=0;i<6;i++){
      if (led[i].led_position==particle_example.led_position){
      led[i].busy=false;
      Serial.println("success");
      Serial.println(led[i].led_position);
      }
    }
    particle_example.led_position=led[number].led_position;
    Serial.println(particle_example.led_position);
    led[number].busy = true ;//take this led as output
    particle_example.reset = false; //reset turned off
    }

  else{
//  initiate_particle( particle_example,led);
}

  delay(30);

}

void update_light(particle_type& particle_example,led_type led[]){ //updating led brightness
      analogWrite(particle_example.led_position, particle_example.brightness);  //updating led brightness

  if (particle_example.brightness >=  160) {
    particle_example.fadeAmount = -particle_example.fadeAmount;
    particle_example.brightness = particle_example.brightness + 2*particle_example.fadeAmount;
  }

  else if (particle_example.brightness <  160 && particle_example.brightness >=  100 ) {
    particle_example.brightness = particle_example.brightness + 1.5*particle_example.fadeAmount;

  }

  else if (particle_example.brightness > 50 && particle_example.brightness <=  100){
      particle_example.brightness = particle_example.brightness + particle_example.fadeAmount;

  }

  else if (particle_example.brightness > 0 && particle_example.brightness <=  50){
      particle_example.brightness = particle_example.brightness + 0.25*particle_example.fadeAmount;

  }

  else if (particle_example.brightness <= 0){
    particle_example.reset= true;
    particle_example.brightness =0;
    int number = particle_example.led_position;

    if (particle_example.fadeAmount<0){
      particle_example.brightness = 0;
      particle_example.fadeAmount = -particle_example.fadeAmount;
    }
    else{
      particle_example.brightness = particle_example.brightness + 0.5*particle_example.fadeAmount;
    }

  }

}

void activate_particle(particle_type& particle_example,led_type led[]){ //function to keep led activated

  if (particle_example.reset==true){ //if led not initiated or has finished its dimming down
    initiate_particle(particle_example, led); //initiate it again
  ;}

  else {
   update_light(particle_example,led); //update its brightness
  }
}

void setup() { //create led outputs
  pinMode(led0, OUTPUT);
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);
  pinMode(led5, OUTPUT);

  Serial.begin(9600); //serial for debug

}

void loop() {

  activate_particle(particle[0],led);
  activate_particle(particle[1],led);
  activate_particle(particle[2],led);
//  activate_particle(particle[3],led);
//  activate_particle(particle[4],led);
//  activate_particle(particle[5],led);
//

 delay(10); // 20-17-15-12-10-7-2

}

void loop() {

  activate_particle(particle[0],led);
  activate_particle(particle[1],led);
  activate_particle(particle[2],led);
  activate_particle(particle[3],led);
//  activate_particle(particle[4],led);
//  activate_particle(particle[5],led);
//

 delay(10); // 20-17-15-12-10-7-2

}

```

Now the code works well up to 3 particles but messes things up for 4,5,6 particles with flickering and absence of light.

# Answer
That seems like a logic problem for me. You define a "particle", which is not bound to a special LED (like a particle, that is jumping from one position to another). Then you included a busy flag, that should prevent, that a LED is used by more than one particle at a time. But you included this flag in the particle. Being busy is a state of the LED, not of the particle, so including this in the particle won't do, what you want.

If you want to use this logic, you need to create a struct, which represents the individual LED. The struct's fields would be the pin number and the busy flag. You can create the LED list with instances of this struct. Then to choose a new position for the particle, you need to check if the busy flag of that position is set. If not, choose this position and set the busy flag. Clear the flag, when you remove the particle from the position.

---

After your edit I see more problems. First a general problem: Currently a new particle, that want's to change it's position, needs a free (not busy) position to move to. You have 6 LED positions, so with 6 particles, there won't be any move. You can change this by freeing a LED position (setting it's busy flag to false), when the fading of a particle is finished. Still there might be timing problems with this way, depending on the overall timing behavior of the sketch (The first particle to free a LED position will not find a different free position and has to wait. This might lead to 2 particles just exchanging there positions).

Then in `void update_light()` you have multiple if statements, which all test the particles brightness. But inside these statements you change the brightness. So it is possible, that multiple of the if statements will execute. You should use `if else if` instead, so that only one of the statements can execute.

And in `void initiate_particle()` you check for the chosen LED position to be busy. But if the position is already busy, you are setting the particles `reset` flag to false anyway. That means that `activate_particles()` will update the particles brightness despite the fact, that the particles does not have a valid LED position currently. You should not set `reset` to false, if the particles hasn't got a valid LED position. And the delay at the end of the initiate function does not serve a function in my eyes.
> 0 votes

---
Tags: arduino-uno, led, struct
---


title: multiple graphs on serial plotter

text:
# Question
Title: multiple graphs on serial plotter
I'm trying to run an Arduino code that simultaneously: 1) blinks an led on-off every 3 seconds 2) gets a voltage input from an EMG sensor and positions a servo motor accordingly

While I run this program, I'd like to plot the following on the same graph 1) LED status on/off printed as 600 if on and 0 if off 2) EMG value being fed to the arduino 3) The angle the Arduino is sending to the servo motor

I wrote the following code which works to an extent but the problem I'm facing is, I only get two graphs on the plotter instead of 3, I think the EMG value and the angle have combined into a single line as seen in this picture:

However, if I remove the angle print statement, I get a proper graph for the other 2 as this:

How do I change my code so I can plot all three separately? Thanks in advance.

```
#include <Servo.h>
Servo myservo;
const int ledPin =  LED_BUILTIN;
int ledState = LOW;
unsigned long previousMillis = 0;
const long interval = 3000;
int led=0;
int servovalue=0;
void setup() {
  Serial.begin(9600);
  myservo.attach(9);
  pinMode(ledPin, OUTPUT);
}

void loop() {
  int sensorValue = analogRead(A0);
int angle = map(sensorValue, 0, 1023, 0, 180);
myservo.write(angle);
Serial.print(sensorValue);
Serial.print(“ ”)
Serial.println(angle);
delay(15);
  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;
    if (ledState == LOW) {
      ledState = HIGH;
      led = 600;
    } else {
      ledState = LOW;
      led = 0;
    }
    digitalWrite(ledPin, ledState);
  }
  Serial.print(" ");
    Serial.println(led);
}

```

# Answer
> 1 votes
The part of your code that prints data to the serial looks like this:

```
void loop() {
    (...)
    Serial.print(sensorValue);
    Serial.print(“ ”)
    Serial.println(angle);
    (...)
    Serial.print(" ");
    Serial.println(led);
}

```

The bug is in the `Serial.println(angle);` line. The `println` method inserts a "newline" character at the end. Try changing it to `Serial.print(angle);` so there is only one "newline" character.

```
void loop() {
    (...)
    Serial.print(sensorValue);
    Serial.print(“ ”)
    Serial.print(angle);
    (...)
    Serial.print(" ");
    Serial.println(led);
}

```

---
Tags: arduino-uno
---


# Question
Title: how can I program my sound sensor and pir motion sensor in 1 arduino uno
```
int pirPin=2;
int buzzerPin=12;
int soundSensor = 19;
int LED = 3;
int statusSensor=0;
int pirVal=0;
void setup()
{
Serial.begin(9600);
pinMode(pirPin, INPUT);
pinMode(soundSensor, INPUT);
pinMode(buzzerPin, OUTPUT);
pinMode(LED, OUTPUT);
}
void loop()
{
pirVal=digitalRead(pirPin);
if(pirVal==HIGH)
{
Serial.println("Motion Detected");
digitalWrite(buzzerPin,HIGH);
delay(150);
digitalWrite(buzzerPin, LOW);
}
else
{
digitalWrite(buzzerPin, LOW);
 }
statusSensor = analogRead(soundSensor);

  if (statusSensor == 1)
  {
Serial.println("Sound Detected");
digitalWrite(LED, HIGH);
delay(100);
digitalWrite(LED, LOW);
}
  else
  {
    digitalWrite(LED, LOW);
  }
}

```

# Answer
> 0 votes
First of all there is no pin with pin number 19 (as you defined a soundSensor on it), and there is no problem you can use my sound sensor and pir motion sensor in 1 arduino uno.

But in order to do that please use **millis** instead of **delay** so that your arduino doesn't wait to read reading of other sensor during the reading of first sensor.

Here is a link which shows how to use arduino for multitasking..

https://learn.adafruit.com/multi-tasking-the-arduino-part-1/overview

---
Tags: arduino-uno
---


# Question
Title: Need to know what USB cable to get for Arduino Nano-33-BLE-Sense
I have recently purchased an Arduino Nano-33-BLE-Sense with Headers and wrongly assumed that it would come with a USB cable with it. I was searching the online store for the cable but the only cable on the store that I see is for Type A to Type B which in its description does not mention my board.

Does anyone have any experience with this board and know which cable I need? Thanks in advance!

# Answer
> 1 votes
Looks like this board

Is connected to the PC with connector commonly named simply "Micro USB". Wikipedia calls it "USB 2.0 Micro-B" It's the same cable that all mobile phones used (before USB-C standard arrived). Check your phone charger.

---
Tags: arduino-nano
---


title: AT+CSTT throws an error

text:
# Question
Title: AT+CSTT throws an error
I am getting an error on

```
AT+CSTT="TATA.DOCOMO.INTERNET","",""

```

What am I missing here?

**Code**

```
void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ;
  }
  Serial.println("Goodnight moon!");
  // set the data rate for the SoftwareSerial port
  mySerial.begin(9600);
  mySerial.println("Hello, world?");
  delay(3000);
  Serial.println("AT+CGATT=1");
  delay(500);
  Serial.println("AT+CGDCONT=1,\"IP\",\"TATA.DOCOMO.INTERNET\"");
  delay(500);
  Serial.println("AT+CDNSCFG=\"4.4.4.4\",\"8.8.8.8\"");
  delay(1000);
  Serial.println("AT+CSTT=\"TATA.DOCOMO.INTERNET\",\"\",\"\"");
  delay(2000);
  Serial.println("AT+CIICR");
  delay(5000);
  Serial.println("AT+CIFSR");
  delay(500);
  Serial.println("AT+CIPSTATUS");
  delay(500);
  Serial.println("AT+CDNSORIP=1");
  delay(500);
  Serial.println("AT+CIPSTART=\"TCP\",\"www.google.com\",\"80\"");
  delay(500);
  Serial.println("AT+CIPSEND");
  delay(500);
  Serial.println("AT");
}

void loop() {
  // run over and over
  if (mySerial.available())
    Serial.write(mySerial.read());
  if (Serial.available())
    mySerial.write(Serial.read());
}

```

**Result**

```
AT+CGATT=1

OK
AT+CGDCONT=1,"IP","TATA.DOCOMO.INTERNET"

OK
AT+CDNSCFG="4.4.4.4","8.8.8.8"

OK
AT+CSTT="TATA.DOCOMO.INTERNET","",""

ERROR
AT+CIICR

ERROR
AT+CIFSR

ERROR
AT+CIPSTATUS

OK

STATE: IP IND
AT+CDNSORIP=1

OK
AT+CIPSTART="TCP","www.google.com","80"

ERROR
AT+CIPSEND

ERROR
AT

OK

```

**Edit**

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

```

# Answer
> 2 votes
**For others who reach here by search results**

Before this applying `AT+CSTT` command check if the modem is attached to GPRS using the `AT+CGATT=?` command. If the result is `+CGATT: 0` this means the modem is not attached so attach the modem using `AT+CGATT=1` command.

This will solve the issue as it was in my case. Even applying `AT+CIPCLOSE=0` and `AT+CIPSHUT` didn't help until I checked that that the result of `AT+CGATT=?` was returning `+CGATT: 0` and applied `AT+CGATT=1`.

# Answer
> 1 votes
Sorry for late Siddharth,

try to get response of only `at+cstt=?` Its return a exec syntax and by following it you can make your frame of `at+cstt`

some below point may it will help

> //TCP connection profile AT+CSTT?
>
> +CSTT: "CMNET","",""
>
> OK APN-\>"CMNET"
>
> USER-\>""
>
> PASSWORD-\>""

and

> AT+CSTT="CMNET"
>
> OK
>
> at+cstt=?
>
> +CSTT: "APN","USER","PWD"
>
> OK

It may help you

regards

# Answer
> 0 votes
Try `AT+CSTT="TATA.DOCOMO.INTERNET"`

# Answer
> 0 votes
In most cases the problem is in low balance and account settings. As I see, you doing all right.

```
AT+CGATT=1
AT+CSTT="TATA.DOCOMO.INTERNET","",""

```

Also, check login/password! It's unusual to have blank credential here, in my country.

---
Tags: programming, gsm
---


title: What sensors to measure grass growth?

text:
# Question
Title: What sensors to measure grass growth?
I would like to make a small project, which would allow me to recognize if the grass has grow enough to lawn. I don't know too much the ecosystem of available sensors for such problem. And I have a lot of grass and some irregular areas to clean once in a while.

Is that something I can do with an arduino and some sensors, or should I need to use more processing power and cameras/AI?

TIA!

# Answer
> 2 votes
My idea: Two light sensors on a short stick embedded in the ground. If the top sensor detects light, but the bottom one does not it means that it's daytime, and grass is long enough that it covered the bottom sensor. You will probably need several of those, because there is no guarantee that grass will actually cover the bottom sensor, and you will need to filter out random elements by testing if values don't change to much.

---
Tags: sensors
---


# Question
Title: Follow black and white line simultaneously
I have a line following bot which uses IR sensors (LSA08, more specifically) to detect the white line on black surface and stay on track. For the project however, there is a trick in the track. At a certain point, the line changes from white to black and the bot is expected to follow the black line on the white surface.

My question is, how would I design the algorithm which will make the bot recognise that the track and conditions have changed.

# Answer
Assume the "road" line is narrower than the bot's width. Sense light/dark across the road-width by enough more that it can see both edges plus enough to regain the roadway at a sharp bend.

Now pretend we don't know what color the roadway is - which is in fact, true! But we do know that the sensors should see either: \[W, W, W, ... W, B, B, ..., B, W, ..., W\] (black stripe), or \[B, B, B, ... B, W, W, ..., W, B, ..., B\] (white stripe).

Call W(hite) a 1 and B(lack) a zero. The above conditions, stored in an unsigned int, might look (in binary) like:

1111110000111111, or 0000001111000000.

One is just an inversion of the other, right? So read your sensors (and I'm going to assume perfect robo-vision for a moment: no noisy signals and we know we're on the roadway), and if necessary, *invert the result* so it look like my second case, 0000001111000000, a group of ones surrounded by a group of zeros shows we're (somewhat) centered on the track. *You no longer need to know what color the roadway is!*

We assumed perfect signals - in reality you'll need some smarts to detect and correct an odd 1 in the midst of a bunch (technical term here) of 0s, or vice versa.

We assumed your bot is kind of centered on the track; able to see both roadway edges. In reality, sometimes you may be losing it - 111000000000000, or drifting to the right. If you can't ensure this won't happen, you'll need to be able to recognize it and correct it. And, here is where we need to know something about the roadway color. We knew what color it was recently, just before we started to drift off, so we'll just continue inverting (or not inverting) our stored sensor data - IF the color doesn't change until the bot re-centers itself (nasty track designers)! If your design criteria can include that the bot doesn't lose either edge of the track, you can always recover, even during a color change. Otherwise you'll have to recognize and respond to a color change even when you can only see one edge. Use the recent road-color to keep track of this.

Hope that helps.
> 1 votes

# Answer
It depends a bit on your precise requirements. Currently you are following the black line (meaning sensing black in the middle and white on the sides). Instead you could follow the border of that line. To do this you would have to control the motors in a way, so that in at the middle of the sensors there is a high contrast (black at the right, white at the left, or vice versa). It will not follow the exact same path as before, but a bit to the side.
> 1 votes

---
Tags: ir, robotics, infrared
---