# Question
Title: Can someone help me solve a loop question and a couple others for my program?
I am currently working on the elegoo uno r3 smart car kit that uses arduino. I have written some code and it works for the most part but I could use some help. I am trying to figure out what i need to do to get my square program to loop and continue to until the stop button is pressed. Can anyone help me out please? Also, I have 2 programs in it. One is for obstacle avoidance which is controlled by button 2 and the square program which is controlled by button 3. The stop button will be used to stop either program. I will put the code below.

```
#include <Servo.h>

//#include <ArduinoJson.h>

//     Left motor truth table
//Here are some handy tables to show the various modes of operation.
//  ENB         IN1               IN2         Description
//  LOW   Not Applicable    Not Applicable    Motor is off
//  HIGH        LOW               LOW         Motor is stopped (brakes)
//  HIGH        HIGH              LOW         Motor is on and turning forwards
//  HIGH        LOW               HIGH        Motor is on and turning backwards
//  HIGH        HIGH              HIGH        Motor is stopped (brakes)
#include <IRremote.h>

//#include <Servo.h>
Servo myservo;      // create servo object to control servo
//Servo servo;             //  Create a DC motor drive object
//#include <stdio.h>

//#include "HardwareSerial.h"

int Echo = A4;
int Trig = A5;

//ir remote button values/ data sheet===========================
#define f 16736925    // FORWARD
#define b 16754775    // BACK
#define l 16720605    // LEFT
#define r 16761405    // RIGHT
#define s 16712445    // STOP
#define KEY2 16750695 //obstacle avoidance mode
#define KEY3 16756815 //square mode

#define KEY_STAR 16728765
#define KEY_HASH 16732845

// define IO pin
#define ENB 5
#define IN1 7
#define IN2 8
#define IN3 9
#define IN4 11
#define ENA 6
#define RECV_PIN 12
#define ECHO_PIN A4
#define TRIG_PIN A5
#define LED_Pin 13
#define carSpeed 250
int rightDistance = 0, leftDistance = 0, middleDistance = 0;

IRrecv irrecv(RECV_PIN);

decode_results results;

void forward(){

  analogWrite(ENA, carSpeed);
  analogWrite(ENB, carSpeed);
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4, HIGH);
  Serial.println("Forward");
}

void stop_r() {
  digitalWrite(ENA, LOW);
  digitalWrite(ENB, LOW);
   /* digitalWrite(IN1, LOW);
  digitalWrite(IN2, LOW);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4, LOW);*/
  Serial.println("Stop!");
}

void back() {
  analogWrite(ENA, carSpeed);
  analogWrite(ENB, carSpeed);
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, HIGH);
  digitalWrite(IN3, HIGH);
  digitalWrite(IN4, LOW);
  Serial.println("Back");
}

void left() {
  analogWrite(ENA, carSpeed);
  analogWrite(ENB, carSpeed);
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, HIGH);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4, HIGH);
  Serial.println("Left");
}

void right() {
  analogWrite(ENA, carSpeed);
  analogWrite(ENB, carSpeed);
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);
  Serial.println("Right");
}

void stop_() {
  digitalWrite(ENA, LOW);
  digitalWrite(ENB, LOW);
   /* digitalWrite(IN1, LOW);
  digitalWrite(IN2, LOW);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4, LOW);*/
  Serial.println("Stop!");
}

//Ultrasonic distance measurement Sub function
int getDistance() {
    digitalWrite(Trig, LOW);
    delayMicroseconds(2);
    digitalWrite(Trig, HIGH);
    delayMicroseconds(10);
    digitalWrite(Trig, LOW);
    return (int)pulseIn(Echo, HIGH) / 58;
}

//--------------------ZIG ZAG----------------------------------------------------

//init the car
void setup() {

  //pinMode(IN1, OUTPUT);     //set IO pin mode OUTPUT
  //pinMode(IN2, OUTPUT);
 // pinMode(ENB, OUTPUT);
 // digitalWrite(ENB, HIGH);  //Enable left motor

  myservo.attach(3);  // attach servo on pin 3 to servo object
  Serial.begin(9600);
  pinMode(Echo, INPUT);
  pinMode(Trig, OUTPUT);

  pinMode(IN1, OUTPUT);     //set IO pin mode OUTPUT
  pinMode(IN2, OUTPUT);
  pinMode(ENB, OUTPUT);
  digitalWrite(ENB, HIGH);  //Enable left motor

  pinMode(ENB, OUTPUT);
  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);
  pinMode(IN3, OUTPUT);
  pinMode(IN4, OUTPUT);
  pinMode(ENA, OUTPUT);
  digitalWrite(ENA, HIGH);//forward
  digitalWrite(ENB, HIGH);

  pinMode(IN3, OUTPUT);     //set IO pin mode OUTPUT
  pinMode(IN4, OUTPUT);
  pinMode(ENA, OUTPUT);
  digitalWrite(ENA, HIGH);  //Enable right motor

  //attachInterrupt(0,CHECK_IR,CHANGE);

  irrecv.enableIRIn(); // Start the receiver

  stop_r();

  //pinMode(IN3, OUTPUT);     //set IO pin mode OUTPUT
  //pinMode(IN4, OUTPUT);
  //pinMode(ENA, OUTPUT);
  //digitalWrite(ENA, HIGH);  //Enable right motor
}

//main loop============================================================================================================================
void loop() {

  if(irrecv.decode(&results)){
    Serial.println(results.value);
    irrecv.resume();
  }
  delay(100);

  //square();

 if (results.value == KEY2){
     digitalWrite(ENA, HIGH);
     digitalWrite(ENB, HIGH);
    obstacleavoidance();
    //irrecv.resume();
  } else if (results.value == s){
    stop_r();
    results.value = 12;
    //irrecv.resume();
  }

  if(results.value == KEY3){
    digitalWrite(ENA, HIGH);
     digitalWrite(ENB, HIGH);
    square();
    //irrecv.resume();
  }else if (results.value == s){
    stop_r();
    results.value = 12;
    //irrecv.resume();
  }

 /* if(results.value == KEY3){
    square();
  } else if (results.value == s){
    stop_r();
  }*/

 /*if (key_pressed == KEY2){
    obstacleavoidance();
  }
  while (key_pressed == s){
    stop_r();
  }*/

}

void get_keys(){

}

void CHECK_IR(){
  if(irrecv.decode(&results)){
    Serial.println(results.value);
    //key_pressed = results.value;
    irrecv.resume();
  }
  delay(100);
}

void square (){
  Serial.println("square");
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4, HIGH);   //go forward
  delay(1000);

  digitalWrite(IN1, LOW);
  digitalWrite(IN2, LOW);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4, LOW);   //stop
  delay(1000);

  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);
  delay(660);              //right wheel turning forward

  digitalWrite(IN1, LOW);
  digitalWrite(IN2, LOW);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4, LOW);   //stop
  delay(1000);
}

void obstacleavoidance(){

  myservo.write(90);  //setservo position according to scaled value
    delay(500);
    middleDistance = getDistance();
    //delay(100);
    if(middleDistance <= 20) {
      stop_r();
      delay(500);
      myservo.write(10);
      delay(1000);
      rightDistance = getDistance();

      delay(500);
      myservo.write(90);
      delay(1000);
      myservo.write(180);
      delay(1000);
      leftDistance = getDistance();

      delay(500);
      myservo.write(90);
      delay(1000);
      if(rightDistance > leftDistance) {
        right();
        delay(360);
      }
      else if(rightDistance < leftDistance) {
        left();
        delay(360);
      }
      else if((rightDistance <= 20) || (leftDistance <= 20)) {
        back();
        delay(180);
      }
      else {
        forward();
      }
    }
    else {
        forward();
    }
}

```

# Answer
Hannah, people that write software are inherently lazy, so because your code does the same thing over and over its quite alien to most people on here :) As a rule of thumb if you copy and paste it more than once it should be a function.

You have functions at the top of the code to move the car, but you don't seem to use them. Using them will make the code shorter, but also much more readable.

In your `setup()` function you are repeatedly setting the pinMode of pins. Group all your `pinMode()` call and then use the pins. Again this will make the code easier to read and less likely to break when you change it.

So back to your question, how to you make the bot run around in squares until you press a button? Well it will be something like this:

```
void square ()
{
  while (condition)
  {
    for (int side = 0; side < 4 && condition; ++side)
    {
      forward ();
      delay (1000);
      stop ();
      right ();
      delay (660);
      stop();
    }
  }
}

```

You need to work out a way to tie make `condition` be updated by your stop button, I don't want to do everything for you.

Hope that helps, if not shout out.
> 1 votes

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


# Question
Title: Circuit with a tip120 works with a Led but, don't with a vibrator motor
I have 2 Arduino Nano's. One with RF transmitter and the other with an RF receiver of 433 MHz and both have two 3v vibration motors. I want one Arduino to send a string to the other Arduino to let him know which vibrator he needs to vibrate. The connection works, when the Arduino with the transmitter sends a message, the other Arduino gets the message and sets pin 2 (the pin for the vibrator via a tip120) HIGH. But the vibrator does not vibrate. When I change the vibrator with a led it works, the led goes on and off. So why does the led work but the vibrator motor not?

I use the VirtualWire library for the RF modules.

Here is the code and I also provided a summary:

Summary: This is the receiver Arduino code. `message_received` is the string variable where the message is stored and in the loop, that message is to check what it contains. And then the led goes off and on.

```
#include <VirtualWire.h>

byte message[VW_MAX_MESSAGE_LEN]; // a buffer to store the incoming messages
byte messageLength = 255; // the size of the message

String message_received;

String message_go_on = "GO_ON";
String message_go_off = "GO_OF";

void setup() {
  Serial.begin(9600);
  vw_setup(2000); // Bits per sec
  vw_rx_start(); // Start the receiver
  Serial.println("RECEIVER MONITOR");
}

void loop() {
  // put your main code here, to run repeatedly:
  if (vw_get_message(message, &messageLength)){ // Non-blocking
    Serial.print("Incoming message: ");
    for (int i = 0; i < messageLength; i++){
      Serial.write(message[i]);
      message_received += (char)message[i];
    }
    Serial.println();
  }
  if(message_received == message_go_on){
    digitalWrite(2, HIGH);
  }
  if(message_received == message_go_off){
    digitalWrite(2, LOW);
  }
  message_received = "";
}

```

---

Summary: This is the code of the transmitter. I have 2 messages that I want to send every 200 milliseconds. The send method is for the transmitter and it needs a char array so I change the string to a char\[\] with a toCharArray() method.

```
#include <VirtualWire.h>

String message_go_on = "GO_ON";
String message_go_off = "GO_OF";

char buf1[VW_MAX_MESSAGE_LEN];
char buf2[VW_MAX_MESSAGE_LEN];

void setup() {
  Serial.begin(9600);
  vw_setup(2000); // Bits per sec

  message_go_on.toCharArray(buf1,VW_MAX_MESSAGE_LEN);
  message_go_off.toCharArray(buf2,VW_MAX_MESSAGE_LEN);
  Serial.println("TRNASMITTER MONITOR");
}

void loop() {
  send(buf1);
  delay(200);
  send(buf2);
  delay(200);
}

void send (char *message)
{
  vw_send((uint8_t *)message, strlen(message));
  vw_wait_tx(); // Wait until the whole message is gone
}

```

The circuit of the receiver Arduino:

I think the vibrator might be undersupplied but why would the led work?

Thanks for the help!

# Answer
The TIP120 is possibly the worst transistor you could choose for this job. It is a Darlington Pair transistor, and those have a (relatively) massive forward drop of between 2 and 4 volts. It works with the LED because an LED needs a tiny amount of current to operate compared to the motor and has a fixed forward voltage of its own. The motor doesn't, and is being starved of power by that huge voltage drop (it's getting maybe half the voltage it should be getting).

Throw away that TIP120 and replace it with a decent N-channel MOSFET - one with a "threshold voltage" (VGS) of 2.5V or less ideally.
> 3 votes

---
Tags: arduino-nano, power
---


# Question
Title: Which Datasheet applies to the ATmega328p?
While researching minimum-voltage requirements of Uno, I came across what appear to be two datasheets for the ATmega328P:

http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P\_Datasheet.pdf

http://ww1.microchip.com/downloads/en/DeviceDoc/ATmega48A-PA-88A-PA-168A-PA-328-P-DS-DS40002061A.pdf

Specifically, the power requirements (and processor speed for each power level) differ. How could I know which datasheet applies to the chip I'm using? I'm actually using an Arduino clone:

# Answer
> 3 votes
You have ATmega328P-AU. Classic Uno with DIP socket has ATmega328P-PU. Arduino Uno SMD has Atmega328P-MU.

The automotive versions ATmega328P-15AZ and ATmega328P-15MZ have separate datasheet starting in Revision History with

> Creation of the automotive version starting from industrial version based on the ATmega48P/88P/168P/328P datasheet 8025F-AVR-08/08. Temperature and voltage ranges reflecting automotive requirements.

# Answer
> 0 votes
I think there is an error concerning the information about supply voltages. At least it's not consistent: microchip has separate websites for ATmega328 and ATmega328p. On the site for the ATmega328p it says: "The device operates between 1.8-5.5 volts". But the datasheet they link on the exact same site says: "Operating voltage: 2.7V to 5.5V for ATmega328p".

This is not just confusing, but contradictory and so I think the only one who can say for sure is the manufacturer.

Actually, the specified supply voltages are determined by the manufacturer by testing at various levels, but the device **might** operate even below or above this range (of course, a developer has to comply with the specs). The 2.7V rating could be an old spec and in the meantime they might have found out that the device indeed runs fine even at 1.8V. Maybe, they have just missed to apply this change everywhere this rating is mentioned, but that's just a guess.

---
Tags: atmega328
---


title: SoftwareSerial interfers with TVout

text:
# Question
Title: SoftwareSerial interfers with TVout
I'm using an Arduino uno and a Nodemcu for making a game with the phone as a WiFi controller. The Nodemcu is the server that receives inputs from the phone connected via WiFi and sends to the Arduino a signal via SoftwareSerial. The Arduino reads the signal and then decides what to do and sends output to TV. It works good but every time the nodemcu sends something, the TV signal gets distorted.

note: the code for the game is not completed

code for Nodemcu:

```
#include<SoftwareSerial.h>
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>

const char* ssid = "SpaceInvaders";
const char* password = "12345678";

IPAddress local_ip(192,168,1,1);
IPAddress gateway(192,168,1,1);
IPAddress subnet(255,255,255,0);
SoftwareSerial SUART(4, 5); //SRX=Dpin-D2; STX-DPin-D1
ESP8266WebServer server(80);

void setup() {
  SUART.begin(115200);
  Serial.begin(115200);
  WiFi.softAP(ssid, password);
  WiFi.softAPConfig(local_ip, gateway, subnet);
  server.on("/", handle_OnConnect);
  server.on("/0", nope);
  server.on("/1", left);
  server.on("/2", right);
  server.on("/3", left_right);
  server.on("/4", shoot);
  server.on("/5", left_shoot);
  server.on("/6", right_shoot);
  server.on("/7", left_right_shoot);
  server.onNotFound(handle_NotFound);

  server.begin();
  Serial.println("HTTP server started");
}

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

void handle_OnConnect() {}

void nope()             {SUART.print(0); server.send(200, "text/html", " "); Serial.println(0);}
void left()             {SUART.print(1); server.send(200, "text/html", " "); Serial.println(1);}
void right()            {SUART.print(2); server.send(200, "text/html", " "); Serial.println(2);}
void left_right()       {SUART.print(3); server.send(200, "text/html", " "); Serial.println(3);}
void shoot()            {SUART.print(4); server.send(200, "text/html", " "); Serial.println(4);}
void left_shoot()       {SUART.print(5); server.send(200, "text/html", " "); Serial.println(5);}
void right_shoot()      {SUART.print(6); server.send(200, "text/html", " "); Serial.println(6);}
void left_right_shoot() {SUART.print(7); server.send(200, "text/html", " "); Serial.println(7);}

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

```

code for arduino (note: seems that stackexcange identifies this function as spam so i posted them here ):

```
#include<SoftwareSerial.h>
#include <TVout.h>
#include <fontALL.h>
SoftwareSerial SUART(2, 3); //SRX=Dpin-2; STX-DPin-3
TVout TV;
//#define debug 1
#define numberOfEnemies 15
#define maxEnemyMovement 20
#define playerDefaultY 75

int points = 0;
unsigned long int millisLastEnemyMovement = 0;
int enemyMovementDelay = 850;
int enemyMovement = 0;
bool directionIsRight = true;

struct b {
  int x;
  int y;
  bool shootable;
} bullet;

struct p {
  int x;
} player;

typedef struct {
  int x;
  int y;
  bool alive;
} Enemy;

Enemy enemyList[numberOfEnemies];

void renderEnemy(int x, int y){ //draws sprite of enemy

}

void renderPlayer(int x, int y){  //draws player sprite

}

void shoot(){
  if(bullet.shootable){
    bullet.shootable = false;
    bullet.x = player.x;
    bullet.y = 100;
  }
}

void left(){
  if(player.x > 0){
    player.x--;
  }
}

void right(){
  if(player.x < 105){
    player.x++;
  }
}

void spriteUpdate(){
  if(!bullet.shootable){
    bullet.x--;
    if(bullet.x < 0){
      bullet.x = 0;
      bullet.y = 0;
      bullet.shootable = true;
    }
    for(int i = 0; i < numberOfEnemies; i++){
      if(bullet.x > enemyList[i].x && bullet.x < enemyList[i].x + 11 && bullet.y > enemyList[i].y && bullet.y < enemyList[i].y + 8){
        bullet.shootable = true;
        enemyList[i].alive = false;
        points++;
      }
    }
  }
  if(millis() - millisLastEnemyMovement > enemyMovementDelay){
    millisLastEnemyMovement = millis();
    if(directionIsRight){
      enemyMovement++;
      for(int i = 0; i < numberOfEnemies; i++){
        enemyList[i].x++;
      }
    }else{
      enemyMovement--;
      for(int i = 0; i < numberOfEnemies; i++){
        enemyList[i].x--;
      }
    }
    if(enemyMovement == 0 || enemyMovement == maxEnemyMovement){
      directionIsRight = !directionIsRight;
    }
  }
}

void render(){
  TV.delay_frame(1);
  TV.clear_screen();
  renderPlayer(player.x, playerDefaultY);
  for(int i = 0; i < numberOfEnemies; i++){
    if(enemyList[i].alive){
      renderEnemy(enemyList[i].x, enemyList[i].y);
    }
  }

}
void setup()
{
  char x;
  Serial.begin(115200); //enable Serial Monitor
  SUART.begin(115200); //enable SUART Port
  bullet.x = 0;
  bullet.y = 0;
  bullet.shootable = true;
  for(int i = 0; i < 5; i++){
    enemyList[i] = {4+i*20, 3, true};
    enemyList[i+5] = {4+i*20, 18, true};
    enemyList[i+10] = {4+i*20, 33, true};
  }
  player.x = 50;
  TV.begin(PAL, 120, 96);
  while(true){

  }
}

void loop(){
    if (SUART.available() != 0){
      x = SUART.read();  //read char
      switch(x){
        case 'a':
          left();
          break;
        case 'b':
          right();
          break;
        case 'c':
          //left and right same time?
          break;
        case 'd':
          shoot();
          break;
        case 'e':
          left();
          shoot();
          break;
        case 'f':
          right();
          shoot();
          break;
        case 'g':
          //left and right at same time?
          shoot();
          break;
      }
    }
    spriteUpdate();
    render();
}

```

This is the schematic:

# Answer
Software Serial is a pretty crummy library. It disables interrupts while receiving for long periods of time. That causes any other library that uses interrupts to have issues with timing. There are a plethora of other soft serial libraries out there. Try one of those instead. AltSoftSerial comes to mind.
> 0 votes

# Answer
> It works good but every time the nodemcu sends something, the TV signal gets distorted.

That's correct. SoftwareSerial is terrible. Don't use it. When it's sending or receiving data nothing else at all can happen.

If you have to resort to SoftwareSerial then you are using the wrong hardware for your project. Maybe an ESP32 would be a better choice.

---

Basically you have two software hacks. Both require precise timing and neither is happy if that timing is messed with. To that end both will disable interrupts to stop things interfering. You can use one or the other, but not both.
> 0 votes

---
Tags: arduino-uno, nodemcu, softwareserial
---


title: facing issue with while loop

text:
# Question
Title: facing issue with while loop
I'm trying to develop one code in which I'm facing issue with while loop. Once I enter any newString it enter in while loop it count till 10 times, when (n\>10) then it is coming out from the while loop. Facing issues in this part

```
while (n < 10)
  {
    while (!ret) {
      if ((time + 15) < millis()) {
        ret = dmd.stepMarquee(-1,0);
        time = millis();
      }
    }
     ret = false;
     n++;
    }

```

I just want when I enter any newString when loop is running it break while loop and start display newString.

Please help me out with this. Thanks for your help, greatly appreciated.

Here is my full code:

```
#include <SPI.h>
#include <DMD.h>
#include <TimerOne.h>
#include "SystemFont5x7.h"
#include "Arial_black_16.h"

//Fire up the DMD library as dmd
#define DISPLAYS_ACROSS 2
#define DISPLAYS_DOWN 1
DMD dmd(DISPLAYS_ACROSS, DISPLAYS_DOWN);

String inputString = "";
boolean stringComplete = false;
String commandString = "";

void ScanDMD()
{
  dmd.scanDisplayBySPI();
}

void setup()
{
   Serial.begin(9600);
   Serial.println("Arduino Start");
   Timer1.initialize( 5000 );
   Timer1.attachInterrupt( ScanDMD );
   dmd.clearScreen( true );
}

void loop() {

if(stringComplete)
{
  stringComplete = false;
  getCommand();

  if(commandString.equals("STAR"))
  {
   dmd.clearScreen( true );
  }

  else if(commandString.equals("PRSC"))
  {
    String text = getTextToPrint();
    printText(text);
  }
  inputString = "";
}

}

void getCommand()
{
  if(inputString.length()>0)
  {
     commandString = inputString.substring(1,5);
  }
}

String getTextToPrint()
{
  String value = inputString.substring(5,(inputString.length())-2);
  return value;
}

void printText(String text)
{
  char newString[256];
  int sLength = text.length();
  text.toCharArray( newString, sLength+1 );
  dmd.selectFont(System5x7);
  dmd.drawMarquee( newString , sLength , (32*DISPLAYS_ACROSS )-1 ,1);
  unsigned long time;
  boolean ret = false;
  time = millis();
  int n;
  n= 0;
  while (n < 10)
  {
    while (!ret) {
      if ((time + 15) < millis()) {
        ret = dmd.stepMarquee(-1,0);
        time = millis();
      }
    }
     ret = false;
     n++;
    }
}

void serialEvent() {
  while (Serial.available()) {            // get the new byte:
    char inChar = (char)Serial.read();    // add it to the inputString:
    inputString += inChar;                // if the incoming character is a newline, set a flag
    // so the main loop can do something about it:
    if (inChar == '\n') {
      stringComplete = true;
    }
  }
}

```

# Answer
> 0 votes
Forget using `serialEvent()`. It is one of the more stupid things that Arduino implemented. It is nothing more than a function that gets called (wrapped in a check to `Serial.available()`) once per iteration of the main `loop()` function.

It is not really an "event" function at all.

To have anything happen inside your `while` loop you have to *manually* implement that thing within your `while` loop. Nothing outside of the `while` loop (with the exception of interrupts) can affect the operation of the `while` loop.

# Answer
> 0 votes
**Now my code is working like** I'm sending the data to Arduino UNO via serial(Keyboard) when it receive any serial data it scroll till 10 time and when *(n\>10)* then will loop stop. In between this whenever I'm send any new data it is not accepting.

**what exactly I want** whenever I send new data to Arduino UNO via serial(Keyboard) and then UNO is to turn expected to scroll the received text on P10 DMD display at the same time. Whenever it receive new serial data it start displaying that data into display.

---
Tags: serial
---


title: Help me get my robotic car to work?

text:
# Question
Title: Help me get my robotic car to work?
So I recently followed a tutorial on youtube and I've assembled the car and connected all the wires.

What I've done: Car

Now in the video, when the guy connects all the wires, the wheels constantly turn while in mine they're completely still. Is this a problem? Is it an indicator of some connection issue or something else?

For context, here is the schematic:

# Answer
> 1 votes
The ENA/ENB (enable A/B) pins have to be at HIGH level (either hardwired or set by an mcu). There exist lots of different driver boards (mostly based on the same ICs) which sometimes don't provide this enable pin, but they are "enabled" by default. You didn't tell us which board you use, but you'll know.

# Answer
> 0 votes
I don't know your motor-driver board but here are several things to check out, based on your schematic:

* The motor driver board has two enable pins. Neither of them is connected. It would make sense that these pins turn the two motors on and off.
* The pin marked 12v is connected to +5v.
* The linked photo of your car shows two 9v "Transistor" batteries. This kind of battery in particular is not capable of supplying much current and they most likely unable to turn the motors.

# Answer
> 0 votes
Check These:

As you have used two power source you must **common ground them**.

\**You must check L298N motor drivers enable pins.As you have only 4 wire to motor driver from arduino.So you must give EnA and EnB pin 5v/HIGH or You can give it (0-255) pwm value from arduino to control the speed of your motor \**

If wiring is ok then you must go throw you Sketch.

---
Tags: arduino-nano, motor, hardware, hc-05, l298n
---


# Question
Title: Can I power Raspberry Pi 3 via 3V3 and GND pin?
Can I power my Pi 3 using the 3v3 pin (pin 1) and GND pin (pin 6)? Also, if I want to protect the board from power surges can I just put a fuse between my power supply and the 3v3 pin?

Thanks in advance,

# Answer
> -1 votes
This is not an Arduino question **BUT** definitely do **NOT** try this!

The Foundation Hats Master has recommendations.

*"It is possible to power the Pi by supplying 5V through the GPIO (sic) header pins 2,4 and GND. The acceptable input voltage range is 5V ±5%. ⋯ Implement a duplicate power safety diode ⋯ supply 5V at a minimum of 1.3A ⋯ Under no circumstances should a power source be connected to the 3.3V pins."*

---
Tags: power, pins, raspberrypi
---


title: Measuring current directly with Arduino

text:
# Question
Title: Measuring current directly with Arduino
Is it safe to measure current like this as long as measured voltage drop don't exceed 5V? I'm asking this because in almost all current sense circuits they used an opamp in their design.

Do I need a resistor between shunt resistor and ADC? Is there any noticeable current flowing to Arduino ADC that can damage it?

simulate this circuit – Schematic created using CircuitLab

# Answer
> 2 votes
Let's imagine that you expect to have 1A of current going through your circuit. Resistor of 0.1 Ohm will give you a voltage drop of 0.1V. This causes two problems.

Firstly Arduino has a cheap ADC builtin. It's supposed to be easy to use, but not really precise. It has nonlinearities towards lower and higher range. You will get more precise reading when measuring voltages around 2.5V.

Secondly The precision of your measurement is cut by factor of 50. Arduino contains ADC that has resolution of 10 bits. This means that there are only 20 steps between 0V and 0.1V That's not really precise.

Solution? Use an opamp as "differential amplifier". If you multiply the voltage difference by 25 you will get 2.5V on the amplifier output when the resistor has 0.1V of drop on it. This value is much more precise when reading it by analogRead of the Arduino, and even a tiny change in voltage on the resistor will give you 25 times larger change on the amplifier output. This way it's much more precise and accurate.

# Answer
> 1 votes
There's a bad current flowing into your Arduino, if ADC voltage exceeds Vcc (5V). This undesired current can be limited by a resistor. But if there's such a high voltage across a shunt resistor, something else is wrong. You rather suffer from a too small voltage for useful measurement.

My first doubt is rather, whether it's safe for the shunt resistor.

---
Tags: current, adc
---


# Question
Title: Sound sensor's output stucks to high values when I include a delay in the loop function
I use Waveshare's Sound Sensor module.

I use this simple code to test the module:

As you can see, the problem is that when I have a delay in the program, once the analogRead is bigger than 10 (by slightly knocking the mic with my finger), "sound" is printed, but sound sensor's output doesn't decrease back to normal values and "sound" keeps repeating. If I don't use delay, everything works fine, but I need that delay.

\*NOTE: on this test I use a STM32 nucleo development board, but I don't think that contributes to the problem.

# Answer
The AOUT pin of that device is no more than an amplified audio signal. It is AC coupled, and that means that it is a small signal varying around 0v. It is not suitable for feeding directly into an ADC.

The AC coupling capacitor will be being charged up by the DC offset it is there to remove, and the lack of any drain on that capacitor while the ADC is not sampling means it never discharges as it should. By sampling faster you increase the load and thus it can discharge somewhat.

To properly read that AOUT pin you need to add your own DC offset to half the VCC voltage of your Arduino board, which can be done by adding two 10k resistors. One from VCC (5v) to the analogue input, and the other from the analogue input to ground.

The signal you read will then be "idle" at around 2.5v (512 ADC reading) and vary around that as sound is picked up.

Note that you can't just sample once per second and hope: there is no provision for "did sound happen in the past second". Instead you really need to be sampling all the time.

If all you care about is if some sound above a threshold has happened then you would be better using DOUT connected to a digital input or even an interrupt pin, and using the threshold setting trim pot on the board.
> 1 votes

---
Tags: sensors, analogread, code-review
---


# Question
Title: Receiving two values over serial port using servos
So I have a java program that picks up the mouses x and y coords on the display and I would like to send those to my arduino and then move my two servos to those locations (I have two servos ontop of each other, one for x and one for y).

The java (processing) code i have is below

```
void draw(){  //same as loop in arduino
  background(52, 152, 219); // background color of window (r, g, b) or (0 to 255)
  //lets give title to our window
  fill(0, 255, 0);               //text color (r, g, b)
  textFont(font);
  text("Ripple Effect Maker", 80, 30);  // ("text", x coordinate, y coordinat)
  ellipse(mouseX, mouseY, 33, 33);
  int x = mouseX;
  int y = mouseY;
  port.write(x+":"+y);
  println(x+":"+y);
  //println("y="+y);
  delay(100);
}

```

I don't have much arduino code because I can't seem to find a way to split the data into two seperate variables and then move the servos to their corresponding variables.

Thanks for the help!

# Answer
> 1 votes
Your problem is that you aren't providing anything to split the data on. You just send the X and y coordinates with a : between X and y. There's nothing between the y and the next X.

By changing the line

```
port.write(x+":"+y);

```

To

```
port.write(x+":"+y+"\n");

```

You then get the linefeed character to split your data on.

---
Tags: arduino-uno, processing-lang, java
---


# Question
Title: What image formats are accepted for displays?
Sorry if there is information missing, im new to the topic.

I have an ESP32 connected to a Waveshare 7,5" RWB display, and i can display images by converting them to .xbm and including the hex code in the sketch. So far, so good.

But heres my question: What exactly are the requirements? Because when looking at the .xbm image code, i see that its a pattern like this:

`0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00`

But when i used a python script

```
import binascii
filename = 'test.png'
with open(filename, 'rb') as f:
    content = f.read()
print(binascii.hexlify(content))

```

to convert an image to hex code, i got this: `b'89504e470d0a1a0a0000000d4948445200000280000001800802000000b2...'`(continues for thousands of characters, didnt want to paste all of that here

However, when trying to run the sketch that successfully displayed the first hex code with the second image code, i got this error(cut out the big string clutter again):

```
...0000000049454e44ae426082};

^

C:\Users\Administrator\Desktop\SPI_test_example\SPI_test_example.ino: In function 'void loop()':

SPI_test_example:167:21: error: 'showBitmapExample' was not declared in this scope

   showBitmapExample();

                     ^

SPI_test_example:171:51: error: 'showFont' was not declared in this scope

   showFont("FreeMonoBold9pt7b", &FreeMonoBold9pt7b);

                                                   ^

exit status 1
'showBitmapExample' was not declared in this scope

```

So, i would like to know - does the image code have to have exactly the format i mentioned first? This is very important for me because i want to automate the process from inputting any image to using the resulting code to feed the display.

Thanks in advance!

EDIT: As far as my understanding goes, both formats are the same data, just that the first one is displaying a white pixel as 0xFF,0xFF,0xFF and the second one as FFFFFF.

# Answer
> 2 votes
This is not a question of image format but of what format c accepts data in.

What you have is a python representation of binary data in hexadecimal encoding. That can only be used with python.

C represents hexadecimal values by prefixing them with `0x`.

You will have to change your python code to output each byte individually and prefix it with `0x` and separate each one with a comma. That can then be wrapped in an array structure.

---
Tags: esp32, display
---


title: Stuck Arduino Relay?

text:
# Question
Title: Stuck Arduino Relay?
I am looking for a relay that stays on (NC=Normally Closed), and when I send a new signal switches to off (NO=Normally Open).

So the relay doesn't consume any power while being in a specific position.

Do you guys know any type?

Thanks :)

# Answer
Finally, I found it!

Google Image: https://www.google.com/search?biw=1974&bih=1050&tbm=isch&sxsrf=ACYBGNSImNFTI2vRTPD5bbjE-eRkJUzdow%3A1571311366907&sa=1&ei=Bk-oXcSJN5K78gKG4brgCw&q=HFD2%2F005&oq=HFD2%2F005&gs\_l=img.3..0j0i24l6.1135292.1138931..1139132...0.0..0.80.289.4......0....1..gws-wiz-img.......0i5i30j0i30.yfdL1Ivd0sU&ved=0ahUKEwjEpOz-lqPlAhWSnVwKHYawDrwQ4dUDCAc&uact=5

Aliexpress: https://www.aliexpress.com/item/32988578668.html?spm=2114.13010708.0.0.57a64c4dkzjFcM
> 1 votes

---
Tags: relay
---


title: send data from serial to client

text:
# Question
Title: send data from serial to client
I am using Arduino Yun to send data from serial to client, and it's partially working because I only get short data delivered, while long data (like more than 100Byte) get the most of them lost.

on the other hand when I use the softwareSerial example in the IDE to send from serial to serial it works with no data lost. I am trying to do like the example as possible with the serial to client code using client.write(mySerial.read()) but not working as expected!

what am I missing? I guess client.write doesn't hold long data or is too slow to transmit. How can I solve this or even another way to achieve my point?

I am sending the data (as a file content on one time, not in sequence- it's a must) from pc using terminal Programm sscom32e. I am receiving the data as client using netcat on the same pc (Yun and PC connected with RS232-USB and are on the same network).

```
#include <SoftwareSerial.h>
#include <Bridge.h>
#include <BridgeClient.h>

#define PORT 9000
// Make the client connect to the desired server and port
IPAddress addr(192, 168, 0, 100);

//not all pins on the yun are assignable as rx/tx
SoftwareSerial mySerial(10, 11); // RX, TX

// Define our client object
BridgeClient client;

int led = 4;
bool Connected;
void setup() {
 pinMode(led, OUTPUT);

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

 // Start Bridge
 Bridge.begin();
 //delay(1000);

 // Start Console communications and wait for port to open:
 //Console.begin();
 //delay(1000);

 //Console.println("Client connecting on port 9000");
 Connected = false;

 //delay(1000);
 //connectToClient();
 connectToClient();
}

void loop() // run over and over
{
 while (mySerial.available()) {

 client.write(mySerial.read());

 //mySerial.read();
 }

}

void connectToClient() {

 // is a connection currently active?
 if (!Connected)
 {
 // not currently connected, try to establish a connection
 client.connect(addr, PORT);
 delay(1000);

 if (client.connected())
 {
 // send something to the client
 client.println("hello server!");
 digitalWrite(led, HIGH);
 }
 else
 {
 connectToClient();
 digitalWrite(led, LOW);

 }
 }
}

```

# Answer
I believe now that serial.read and client.write cann't work together at the same time efficiently. when client.write starts, serial.read stops and therefore data get lost. Now I am saving the serial.read in 3 arrays of each 255Byte, when they are full or I receive an end-marker I call client.write to send them and Serial stops anyway. This works but for max. 765 Byte data. I can't do more arrays to save the serial data due to the limited memory of the module, which means it's not the best solution right now. I will post the code for this later when I optimate it. the other Idea coming to my mind is to send orders to the serial to wait until client.write finishes and then continue receiving and so on. Is this possible? Is Serial that flexible? How could I communicate with Serial to wait and to continue?
> 0 votes

---
Tags: arduino-yun
---


# Question
Title: How to control multiple leds independently with arduino but they share a 12v external power source
I have a project with many components. I'd like to use 12v adapter from wall. I have a simplified experiment to apply to the actual project. I can't find any info on the internet after days of searching. I want to control each of 6 leds independently with an arduino. They all have different forward voltages. But I would like them to be powered by the same 12v external power supply. I suspect I would use transistors, Could someone point me in the right direction to wire these up? I can figure out the code myself.

# Answer
The basic schematic for one LED is:

simulate this circuit – Schematic created using CircuitLab

Make sure that:

* R1 is the right resistance for the supply voltage, forward voltage, and desired current
* M1 has a threshold low enough that the Arduino turns it fully on.

Just duplicate the circuit for each LED you want to control. The code is no different to having an LED directly attached to the Arduino.
> 2 votes

---
Tags: led
---


title: AD7476 adc and SPI

text:
# Question
Title: AD7476 adc and SPI
I'm trying to understand if I can use the AD7476 with Arduino and SPI:

datasheet

My rough idea is that I should put CS low, then read two bytes using SPI.transfer() twice, and then bring CS high again. Is that correct?

But looks like the AD7476 doesn't have any buffer, so I guess timing must be really precise in order to not miss any bit? what if SPI.transfer() occurs too late after CS going low?

# Answer
> My rough idea is that I should put CS low, then read two bytes using SPI.transfer() twice, and then bring CS high again. Is that correct?

Yes, that is correct.

> But looks like the AD7476 doesn't have any buffer, so I guess timing must be really precise in order to not miss any bit?

No. The conversion is controlled *by the SPI clock*. The ADC is a *successive approximation* ADC. That means for each "sample clock" a more accurate approximation of the voltage is created. In this instance that "sample clock" is the same as the "SPI clock". Each time you send one clock pulse a new, more accurate, approximation is created.

> what if SPI.transfer() occurs too late after CS going low?

Within reason, nothing untoward.

The way an SAR ADC works is it uses a DAC which is controlled by a clock to create a voltage. That voltage is halfway between 0V and "the current estimated voltage" (starting at "vref" - 5V in this case). The voltage is compared with the "sampled" voltage (stored in a tiny capacitor). That forms one bit of the resultant value. At the next clock the DAC voltage is halved (and maybe added to the previous voltage depending on the previous comparison result) and repeated. This is the next bit of the result. It repeats with the voltage getting smaller and smaller and smaller.

Each time you clock one bit through your SPI interface it generates and compares the next voltage generating the next bit of data for you to read.

The knock-on effect of this is that there is both a maximum and a minimum frequency that you can use the SPI interface at. Too fast and it is unable to generate the comparison voltages and do the comparison in time. Too slow and the internal capacitor loses charge through self-discharge and leakage current. Thgis is why on page 8 of the datasheet it specifies a minimum and a maximum frequency for the SPI interface (10kHz to 20MHz).
> 2 votes

---
Tags: spi, adc
---


# Question
Title: Dshot implementation on Arduino (ESC protocol)
Does anyone one know if it's possible to implement Dshot on Arduino? I want to interface the Arduino with ESCs (electric speed controllers). These ESCs use Dshot, (https://oscarliang.com/dshot/) a digital protocol. From what I read online, you can make PWM follow a duty cycle. However, I want to change the duty cycle after each pulse and not just repeat the same duty cycle. I understand this requires DMA (direct memory access) but it's a bit over my head.

# Answer
In short, I ended up creating a library capable to drive multiple DShot600 ESCs: DShot-Arduino It still need a lot more polish, but the bit-banging works really well.

---

**SPI method**

I tried the method @dannyf mentioned, which involved combining 3 SPI bytes to form 1 dShot bit and it actually works.

But there's a few problem with SPI:

* It takes up the valuable SPI port, in theory you can still connect other SPI devices, but;
* maximum 1 dShot ESC can be connected
* During transmission of the packet, the CPU need to wait for the whole task, assume we are sending DShot300, each packet is about 54us long so CPU is halt for that amount of time. If you are doing this in 1000Hz, that is 5% CPU time.
* The timing is not very accurate to the DShot protocol standard

e.g. for DShot300, each bit is

> 1.25us High - 1.25us H/L - 0.83 Low
>
> for a 16MHz Arduino, 1.25us will be 20 CPU cycles which is not accurate to transmit with a SPI byte

I end up with the following codes to send a bit:

```
inline void dshot_0(){
  SPDR = 0xFF;
  NOP;
  while (!(SPSR & _BV(SPIF))) ;
  SPDR = 0x60;
  NOP;
  while (!(SPSR & _BV(SPIF))) ;
  SPDR = 0x00;
  NOP8;
  while (!(SPSR & _BV(SPIF))) ;
}

inline void dshot_1(){
  SPDR = 0xFF;
  NOP;
  while (!(SPSR & _BV(SPIF))) ;
  SPDR = 0xFF;
  NOP;
  while (!(SPSR & _BV(SPIF))) ;
  SPDR = 0xF0;
  NOP8;
  while (!(SPSR & _BV(SPIF))) ;
}

```

Above code is for DShot150, the SPI was set to 4Mbps, to adhere to the correct timing, I cannot transmit a full DShot byte as all on or all off, here's how the calculation done:

> 4Mbit SPI, each bit 0.25us. Thus for 16M clock arduino:
>
> * DShot 0 sequence: 10 bits of 1, 14 bits of 0
> * DShot 1 sequence: 20 bits of 1, 4 bits of 0

Those NOPn are just macro for the number of NOPs. I avoided using SPI library code here since the overhead of making library call is quite a lot.

**Pure software bit-banging**

This is the method resulted in my library, since using hardware SPI won't give me any advantages of releasing CPU time, and doing some Math gives me that a DShot600 require total 27 CPU cycle on 16MHz UNO. Which the pattern is the following:

> 10 Cycle High -\> 10 Cycle H/L (depending on bit 1/0) -\> 7 cycles low

Which gives total of 1.6875us per bit or 27us per packet. To allow the very tight timing those are coded in assembly.

Also by applying bit-masking the library is capable of driving at most 8 ESCs on the same hardware port (on UNO, Digital pin 0-7, PORTD).

***Update cycle***

One last note about DShot is during my test, I found it is quite strict on the update frequency. It must be updated at exact time interval and I found the slowest update frequency will be around 500Hz. To provide the correct timing for that, the library used Timer 1 and by default update in 1000Hz frequency.
> 6 votes

# Answer
> you can make pwm follow a duty cycle.

single shot pwm would be difficult to do on an avr.

much better to use hardware spi. Looks like you can do use 3 spi bits for every dshot bit. So 6 bytes of spi transmission would enough for every dshot frame (16 dshot bits).

running hardware spi at 3\*0.6Mhz = 1.8Mhz or where about on a 16MIPS avr would be quite doable.
> 2 votes

---
Tags: serial, motor, pwm
---


# Question
Title: Control DC Motor with Arduino Uno WiFi Rev2 Html Slider Code
I would like to control my dc motor using the Arduino Uno WiFi Rev2 using an html range slider. Now I can control the motors speed and direction using push buttons just fine. My code is posted below of what I've done so far.

```
client.println("<style>");
client.println(".class-name{writing-mode: bt-lr; webkit-appearance: slider-vertical;width: 8px;height: 175px;padding: 0 5px;}</style>");
client.println("<center><input type=\"range\" class=\"class-name\" orient=\"vertical\" id=\"range\" min=\"0\" max=\"255\" step=\"0\" onchange=\"motor1(this.value)\" value=\"0\"></center>");

```

This code below is the current button code. I need the below code to be used by the slider code above:

```
if (currentLine.endsWith("GET /MONFWD")) {
digitalWrite(MOTOR_A_ONE, HIGH);  // Establishes forward direction of Channel A
digitalWrite(MOTOR_A_TWO, HIGH);  // ENGAGE BRAKE
delay(1000);                      // DELAY BEFORE RELEASING BRAKE
digitalWrite(MOTOR_A_TWO, LOW);   // Disengage the Brake for Channel A
analogWrite(MOTOR_A_ENGAGE, 255); // Spins the motor forward on Channel A at full speed

```

# Answer
**Here's an example of slider that changes a Servo speed,** **In html page code you have to add this:**

```
  <div class="slidecontainer">
  <input type="range" min="0" max="1023" value="512" class="slider" id="myRange">
  <p>Value: <span id="demo"></span></p>
</div>

<script>
var slider = document.getElementById("myRange");

var output = document.getElementById("demo");

output.innerHTML = slider.value;

slider.onchange = function() {
  output.innerHTML = this.value;
  pwm_change(output.innerHTML);

}
function pwm_change(val) {
  var xhttp = new XMLHttpRequest();
  xhttp.open("GET", "setPWM?PWMval="+val, true);
     xhttp.send();
}
</script>

```

**In arduino you have to define handler like this:**

```
void handle_pwm() {
 String  pwm_val = server.arg("PWMval"); // reading from slider on html pagae

 Serial.print("slider val: ");
 Serial.println(pwm_val);
int pwm_value = map(pwm_val.toInt(), 0, 1023, 0, 180);
Servo.write(pwm_value);

server.send(200,"text/plane","0"); // handling the webpage update

}

```

**And define servo and handler in Setup() section:**

```
void setup(void){
....
Servo.attach(MotorPin,1000,2000);
server.on("/setPWM", handle_pwm);
....
 }

```
> 2 votes

---
Tags: motor, web-server
---


title: Stepper Motor Direction via Flow Amps

text:
# Question
Title: Stepper Motor Direction via Flow Amps
I have a problem with stepper motor direction.

I want to change the direction of the stepper motor rotation, when the stepper motor shaft is stuck.

For example, when I hold the shaft of the stepper motor with my hand, the direction should change.

How can I do it? Someone told me you should calculate the current, but I don't know how to do this?

My material components:

* Arduino
* stepper motor gearbox 12 V
* ULN 2003A

# Answer
> 1 votes
When motors stuck their current draw increases, you can sense that increase in the current and then change the rotation of the motor. The simplest way to measure current is with using a shunt resistor, for sensing high currents, current sensors based on hall effect sensors is usually used. ACS712 is one example.

How to sense current using a shunt?

Basically we're measuring the voltage drop over a resistor (RS), but the voltage drop is too small for Arduino to measure so we need an opamp to "amplify" the input:

simulate this circuit – Schematic created using CircuitLab

The schematic above is the simplest way to measure the voltage drop at "LOW SIDE", there is differential mode and "HIGH SIDE" measurement methods.

The gain of opamp can be set with resistors and this formula:

VOUT = (1 + R2/R1) * V1

The output of opamp then can be calculated to get current using ohm's law:

I = V / R

A simple code to calculate current:

```
int rawAnalog;
float voltageDrop;
int resistor = 0.1;
float current;

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

void loop() {
  rawAnalog = analogRead(A0); // Read A0 input
  voltageDrop = (rawAnalog * 5) / 1024; // Convert the raw value to voltage
  current = voltageDrop / resistor; // calculate the current
}

```

Bonus: INA219 is an easy to use high-side I2C module which can measure both current and voltage.

---
Tags: motor, stepper
---


title: Controlling multiple servos as one

text:
# Question
Title: Controlling multiple servos as one
I want to attach multiple servos to Arduino but all them must receive same command. If it possible to connect all servos to one command pin (I don't want to use "for" in code to minimize processor time for operation)?

# Answer
> 2 votes
IMHO it is possible to connect more than one server PWM control inputs to a Arduino output pin.

The Servo input is something like a comparator with an very high resistance. So the servos should not influence each other in any way, nor will the output pin be overloaded.

Because of the input capacities of the servos, there might be a limit of the count of the servos.

And if you supply the servos with power from the arduino then, there is of cause a limit.

EDIT:

It is always a good idea to use buffers in a servo control circuit, to keep a sharp square wave signal. Parasitic capacities can reshape the signal even to a sinus signal.

That might confuse the servo control unit which works well only with a square wave (i.e a PWM-Signal).

simulate this circuit – Schematic created using CircuitLab

---
Tags: arduino-uno, servo
---


title: DS1820B only returns -127

text:
# Question
Title: DS1820B only returns -127
ive used one DS1820B sensor in a AVR bread board circuit and it works there, now i tried attaching it to a arduino mega board with the code below and also another library below that.

currently the data pin is connected to pin 10 on the arduino board, but i also tried pin 2 as in this picture:

https://lastminuteengineers.com/wp-content/uploads/2018/12/Wiring-Multiple-DS18B20-Temperature-Sensors-With-Arduino.png

i changed: #define ONE\_WIRE\_BUS 10 accordingly.

So after that i put the chip back onto the bread board and it still works. I also tried it with the 4.7k resistor on the data line as pullup....still -127.

Any ideas?

```
#include <SPI.h>
#include <SD.h>
/********************************************************************/
// First we include the libraries
#include <OneWire.h>
#include <DallasTemperature.h>
/********************************************************************/
// Data wire is plugged into pin 2 on the Arduino
#define ONE_WIRE_BUS 10
/********************************************************************/
// Setup a oneWire instance to communicate with any OneWire devices
// (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
/********************************************************************/
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
/********************************************************************/

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

void loop() {

  Serial.print("Temperature is: ");
 Serial.print(sensors.getTempCByIndex(0)); // Why "byIndex"?
   // You can have more than one DS18B20 on the same bus.
   // 0 refers to the first IC on the wire
   delay(1000);

}

```

second code:

```
#include "DS18B20Events.h"

// Pin for DS18B20
#define ONE_WIRE_BUS 10

/********************************************************************/
// Setup a oneWire instance to communicate with any OneWire devices
// (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);

// Init DallasTemperature
DallasTemperature dallasTemperature(&oneWire);

//Init thermometer with index 0 (default)
DS18B20Events thermometer(0);

// the setup function runs once when you press reset or power the board
void setup() {
  Serial.begin(9600);
  DS18B20Events::setup(&dallasTemperature); // Link DS18B20Events to DallasTemperature object
  DS18B20Events::setInterval(5000); // Set min interval in milliseconds between 2 measurements. Default 10000 set in setup() method.

  // subscribe to temperature changed event
  thermometer.onChange = temperatureChanged;
}

// the loop function runs over and over again until power down or reset
void loop() {
  thermometer.loop(); // Mandatory to measure temperature and fire an event if needed

  Serial.print(thermometer.getTempC()); // Get last measured tempC if needed.
  Serial.print(" measured ");
  Serial.print((millis() - thermometer.getMillis()) / 1000);
  Serial.println(" seconds ago.");

  delay(1000);
}

void temperatureChanged(uint8_t index, float tempC)
{
  Serial.print(tempC);
  Serial.print(" new tempC at index ");
  Serial.println(index);
}

```

# Answer
127 error is a **connection error**, check the wiring:
> 1 votes

---
Tags: ds18b20
---


title: Convert byte* to int in Arduino

text:
# Question
Title: Convert byte* to int in Arduino
I am trying to convert `byte*` value to `int` here is how I have it.

```
void mqttCallback(char* topic, byte* payload, unsigned int length) {

  String topicStr = topic;
  int* payload_value;
  int updates_cal;

    payload_value = (int*)payload;
    //updates_cal = *payload_value;

    Serial.print((int)payload_value);

  delay(1);

  Serial.println();
  Serial.println("-----------------------");

}

```

I am getting MQTT payload as Integer value. Which I want to receive in my NodeMCU (ESP8266).

Is there any way to do this?

Thank you!

# Answer
Judging by the comments, you are actually receiving your integer data as text, as a sequence of ASCII characters. This is what you send yourself using `mosquitto_pub`. The buffer is apparently not zero-terminated.

If these characters represent an integer value, then the way to retrieve it as an integer value would be

```
char buffer[128];

// Make sure here that `length` is smaller than the above buffer size.
// Otherwise, you'd need a bigger buffer

// Form a C-string from the payload
memcpy(buffer, payload, length);
buffer[length] = '\0';

// Convert it to integer
char *end = nullptr;
long value = strtol(buffer, &end, 10);

// Check for conversion errors
if (end == buffer || errno == ERANGE)
  ; // Conversion error occurred
else
  Sterial.println(value);

```

---

Another approach, which avoids using a separate large\[ish\] buffer just for the purposes of zero-termination, would be

```
// Build a `scanf` format string that will read no more than `length`
// characters without relying on zero-termination of the payload
char format[16];
snprintf(format, sizeof format, "%%%ud", length);

// Convert the payload
int payload_value = 0;
if (sscanf((const char *) payload, format, &payload_value) == 1)
  Serial.println(payload_value);
else
  ; // Conversion error occurred

```

However, this approach is less protected from integer overflow than the previous one.

---

Note that most of the above "jumping through the hoops" is dedicated to adding a zero-terminator to the input buffer. If instead you opt for ensuring zero-termination on the sender's side, then it would all reduce to a simple

```
// Convert C-string to integer
char *end = nullptr;
long value = strtol((const char *) payload, &end, 10);

// Check for conversion errors
if (end == buffer || errno == ERANGE)
  ; // Conversion error occurred
else
  Sterial.println(value);

```

No extra buffers required.
> 2 votes

# Answer
Don't know if you found an answer yet, but I had the exact same issue and eventually came up with this:

```
   payload[length] = '\0'; // Add a NULL to the end of the char* to make it a string.
   int aNumber = atoi((char *)payload);

```

Pretty simple in the end!
> 1 votes

# Answer
`byte*` means "pointer to byte(s). It is usually used to point to a byte buffer, and usually will also have a length value so you know how many bytes are in the buffer. It looks like your function does have a length value.

If you're certain that the data in the `payload` parameter is a single int, and the length is correct for an int (2 bytes on Arduino I believe) then you should be able to cast the pointer to `int*` type and then fetch the value from the buffer:

```
void mqttCallback(char* topic, byte* payload, unsigned int length) {
  String topicStr = topic;
  int payload_value;
  int updates_cal;

  if (length >= 2) {
    //Cast payload to an int pointer and fetch the value
    intValue = *((int*)payload);
  }
}

```
> 0 votes

---
Tags: esp8266, arduino-ide, c++, nodemcu, mqtt
---


title: Water pump control hysteresis

text:
# Question
Title: Water pump control hysteresis
I'm using arduino with analog pressure sensor, temperature sensor and a relay to control water pump. The simple code I wrote works, but I want better control.

```
#include <OneWire.h>
#include <DallasTemperature.h>

 const int pinCidlaDS = 2;
 int pinA0 = A0;
 int teplota;
 int rele;
 float tlak = 0;  //ideal 290+-

OneWire oneWireDS(pinCidlaDS);
DallasTemperature senzoryDS(&oneWireDS);

void setup() {
 senzoryDS.begin();
 rele = 3;
 pinMode(3, OUTPUT);
 Serial.begin(9600);
}

void loop() {
 tlak = analogRead(A0);
 teplota = (senzoryDS.getTempCByIndex(0));
  if ((tlak < 285) && (teplota < 30)) {
   digitalWrite(rele, LOW);
   delay(7000);
 }
   else {
   digitalWrite(rele, HIGH);
   delay(500);
 };
 Serial.print("Tlak: ");
 Serial.println(tlak);
 Serial.print("Teplota: ");
 senzoryDS.requestTemperatures();
 Serial.print(senzoryDS.getTempCByIndex(0));
 Serial.println(" stupnu Celsia");
 teplota = (senzoryDS.getTempCByIndex(0));
 delay (200);

}

```

So now I'm using delay to get away from the treshold value. And I wanted to write a code that would work like:

**Pressure is lower than 'x', relay ON. Pressure rises to 'Y', relay OFF until Pressure is lower than 'x'.**

What should I use? Could you please give me a example, if there is? Thank you very much! :)

# Answer
Implementing hysteresis turns out to be quite straight-forward:

```
float pressure = read_pressure();
if (pressure < x)
    turn_relay_on();
else if (pressure >= y)
    turn_relay_off();

```
> 2 votes

---
Tags: arduino-uno
---


title: Multiple buttons to control relays

text:
# Question
Title: Multiple buttons to control relays
Dears,

I have a problem that I could not solve for a while, I tried the code below but it did not work. There will be 4 buttons controlling 4 relays but in a way that button one will turn relays 1&3 on, if button 2 is pressed only relay 2 turns on, if button 3 is pressed relays 1,2 and 3 will turn on, if button 4 is pressed it is supposed to toggle relays 1&4. one more thing: I need to be able to pass from any button to any of the others and the corresponding relays will be activated while the others will go off.

```
    #include <Bounce2.h>

    const int     BUTTON_COUNT = 4;
    const int16_t DEBOUNCE_DELAY = 50;
    const uint8_t buttonPins[BUTTON_COUNT] = {28, 29, 30, 31};
    const uint8_t ledPins[BUTTON_COUNT] = {34, 35, 36, 37};

    Bounce buttons[BUTTON_COUNT];
    uint8_t ledStates[BUTTON_COUNT];

    void setup() {
    for (int i = 0; i < BUTTON_COUNT; i++) {
    buttons[i].attach(buttonPins[i], INPUT);
    buttons[i].interval(DEBOUNCE_DELAY);
    pinMode(ledPins[i], OUTPUT);
    ledStates[i] = HIGH;
    digitalWrite(ledPins[i], ledStates[i]);
     }
    }

    void loop() {

// Update the debouncers.
for (int i = 0; i < BUTTON_COUNT; i++)
    buttons[i].update();

// When the first "laban" button is pressed:
if (buttons[0].rose()) {

    // Light up the first LED.
    digitalWrite(ledPins[1], LOW);
    digitalWrite(ledPins[3], LOW);

    // and turn off all the others.
    for (int i = 0; i < BUTTON_COUNT; i++) {
        ledStates[0] = HIGH;
        ledStates[2] = HIGH;
        digitalWrite(ledPins[i], ledStates[i]);
    }
}

// When the first button is released:
if (buttons[0].fell()) {

    // turn off relays.
    digitalWrite(ledPins[1], HIGH);
    digitalWrite(ledPins[3], HIGH);

}

// When the first "Soda" button is pressed:
if (buttons[1].rose()) {

    // Light up the first LED.
    digitalWrite(ledPins[2], LOW);

    // and turn off all the others.
    for (int i = 0; i < BUTTON_COUNT; i++) {
        ledStates[0] = HIGH;
        ledStates[1] = HIGH;
        ledStates[3] = HIGH;
        digitalWrite(ledPins[i], ledStates[i]);
    }
}

// When the first button is released:
if (buttons[1].fell()) {

    // turn off the first LED.
   digitalWrite(ledPins[2], HIGH);

}

// When the first "labanUP" button is pressed:
if (buttons[2].rose()) {

    // Light up the first LED.
    digitalWrite(ledPins[1], LOW);
    digitalWrite(ledPins[2], LOW);
    digitalWrite(ledPins[3], LOW);

    // and turn off all the others.
    for (int i = 0; i < BUTTON_COUNT; i++) {
        ledStates[0] = HIGH;
        digitalWrite(ledPins[i], ledStates[i]);
    }
}

// When the first button is released:
if (buttons[0].fell()) {

    // turn off the first LED.
     digitalWrite(ledPins[1], HIGH);
     digitalWrite(ledPins[2], HIGH);
     digitalWrite(ledPins[3], HIGH);
}

// When circulation button is pressed:
 if (buttons[3].rose()) {

    // Toggle its state.
    ledStates[3] = !ledStates[3];
    digitalWrite(ledPins[3], ledStates[3]);
    digitalWrite(ledPins[0], ledStates[0]);
     }
    }

```

# Answer
> 1 votes
Below code is an simple example of what you described, each button will turn on the relays defined for them and turn off other relays. except for button 4 which will toggle relay 1 and 4.

```
int relay1 = 2;
int relay2 = 3;
int relay3 = 4;
int relay4 = 5;
int sw1 = 6;
int sw2 = 7;
int sw3 = 8;
int sw4 = 9;
int sw1Status, sw2Status, sw3Status, sw4Status;
int order = 1; // default is to set all relays off.

void setup() {
  pinMode(relay1, OUTPUT);
  pinMode(relay2, OUTPUT);
  pinMode(relay3, OUTPUT);
  pinMode(relay4, OUTPUT);
  // input pull-up, so default state of buttons is HIGH.
  pinMode(sw1, INPUT_PULLUP);
  pinMode(sw2, INPUT_PULLUP);
  pinMode(sw3, INPUT_PULLUP);
  pinMode(sw4, INPUT_PULLUP);
}

void loop() {
  // read the buttons status
  sw1Status = digitalRead(sw1);
  sw2Status = digitalRead(sw2);
  sw3Status = digitalRead(sw3);
  sw4Status = digitalRead(sw4);

  if (sw1Status == LOW) { // if button 1 pressed
    order = 2; // go to case 2
  }
  if (sw2Status == LOW) {
    order = 3;
  }
  if (sw3Status == LOW) {
    order = 4;
  }
  if (sw4Status == LOW) { // button 4 toggle
    if (order != 5) { // if order is not equal 5 turn on relay 1 & 4
      order = 5;
    }
    else { // else go to case 1, which will turns off all relays
      order = 1;
    }
  }

  switch (order) {
    case 1: // if order equals 1
      digitalWrite(relay1, LOW);
      digitalWrite(relay2, LOW);
      digitalWrite(relay3, LOW);
      digitalWrite(relay4, LOW);
      break;

    case 2: // if order equals 2
      digitalWrite(relay1, HIGH);
      digitalWrite(relay2, LOW);
      digitalWrite(relay3, HIGH);
      digitalWrite(relay4, LOW);
      break;

    case 3: // if order equals 3
      digitalWrite(relay1, LOW);
      digitalWrite(relay2, HIGH);
      digitalWrite(relay3, LOW);
      digitalWrite(relay4, LOW);
      break;

    case 4: // if order equals 4
      digitalWrite(relay1, HIGH);
      digitalWrite(relay2, HIGH);
      digitalWrite(relay3, HIGH);
      digitalWrite(relay4, LOW);
      break;

    case 5: // if order equals 5
      digitalWrite(relay1, HIGH);
      digitalWrite(relay2, LOW);
      digitalWrite(relay3, LOW);
      digitalWrite(relay4, HIGH);
      break;

    default: // if none of above cases is valid go to case 1
      order = 1;
      break;
  }
}

```

Having a tidy code format and using simple coding style (if possible) will help to debug/edit/improve the code more easily.

*Don't forget to de-bounce the buttons.*

---
Tags: arduino-mega, button, relay
---


# Question
Title: Can't burn bootloader through Arduino Nano clone ISP to atmega328p
I'm trying to use a Nano v3 as ISP to program an atmega328p on a board with ISP headers:

I followed the instructions under https://www.arduino.cc/en/Tutorial/ArduinoISP which I think have been recently updated. I'm simply connecting ISP headers together except for D10 from programmer to reset on the target AVR.

The ISP sketch seems to be working fine as far as I can see the heartbeat pulsing a led. But when trying to burn bootloader with settings:

```
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x15
avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0x15

avrdude: stk500_getparm(): (a) protocol error, expect=0x14, resp=0x14

avrdude: stk500_getparm(): (a) protocol error, expect=0x14, resp=0x01
avrdude: stk500_initialize(): (a) protocol error, expect=0x14, resp=0x10
avrdude: initialization failed, rc=-1
         Double check connections and try again, or use -F to override
         this check.

avrdude: stk500_disable(): unknown response=0x12
Error while burning bootloader.

```

~~I noticed something weird though, the 5V and GND on the ISP header on the programmer nano only has around 0.4V. This even without anything external but the usb connected. Is my nano broken or is the usb connection not able to deliver enough power?~~

# Answer
> 2 votes
Your slave micro isnt resetting when your master wants it to reset.

Ie: master sends a reset signal before initiating further communication, and it seems that your slave not being reset.

So its not responding.

Once cross check your isp signal lines.

# Answer
> 2 votes
Try adding the 10µF capacitor connected to `RESET` and `GND` on the board you are using as programmer (in this case, your Nano). This is required according to the Documentation.

> The 10µF electrolytic capacitor connected to RESET and GND of the programming board is needed only for the boards that have an interface between the microcontroller and the computer's USB, like Mega, Uno, Mini, Nano.

I just encountered the exact same error output, and the capacitor solved it.

---
Tags: avr
---


# Question
Title: How do I properly use the WiFi capabilities of ESP8266?
I am creating a project with an ESP8266 (Arduino IDE) which requires it to serve a webpage to a client. The module will be connected to a WiFi network by default, but when that WiFi network is not available, I need it to turn on its Soft Access Point, so that the user can still access that webpage by connecting to the AP. When the WiFi network becomes available, I want the module to reconnect to the WiFi network and disable the SoftAP.

Here is the chunk of code in my sketch that deals with all the WiFi stuff:

```
void wifi() {
  if(WiFi.status() != WL_CONNECTED){
    WiFi.mode(WIFI_AP_STA);

    if((unsigned long)(millis() - waitUntil) >= interval){            //this section I used as an alternative to the delay() function, the delay is 3 sec
      WiFi.begin(ssid, password);
      waitUntil = waitUntil + interval;

      if(WiFi.status() == WL_CONNECTED){
        Serial.println("Connection successful! ");
        Serial.print("IP: ");
        Serial.print(WiFi.localIP());
        WiFi.softAPdisconnect(true);
      }
    }
  }

  if(WiFi.status() != WL_CONNECTED && softAPEnabled == false){
    Serial.println("WiFi not connected, enabling SoftAP...");

    WiFi.softAP(softAP_ssid, softAP_password);

    softAPEnabled = true;

    Serial.println("SoftAP ON");
  }
  else if(WiFi.status() == WL_CONNECTED && softAPEnabled == true){
    WiFi.softAPdisconnect(true);
    softAPEnabled = false;
    Serial.println("SoftAP OFF");
  }
}

```

Here are the problems:

1. The webpage works fine when the module is connected to WiFi and I go to the IP address from a browser, but when SoftAP mode is enabled, and I connect to the AP and go to 192.168.1.1, it does not work. The next problem may be related to this.
2. I don't think I'm using WiFi.mode() correctly. I currently have it set to WIFI\_AP\_STA, but after problem 1 occurred, I tried to change it to WIFI\_AP and WIFI\_STA individually as I needed each mode, but this still did not work.

# Answer
> 1 votes
The following may not solve of your problems, but just in case it helps... I was using the ESP8266 both in Station mode and AP. Both worked. In AP mode, it worked but the ESP8266 ignored my instructions to set name and password for the AP , until I realised the following . The password must at least be 8 characters long, otherwise the instruction is ignored . in the IDE, you should erase flash AND WiFI settings, otherwise it will be "lazy" and use previous settings

---
Tags: esp8266, web-server
---


# Question
Title: Control 4 digital outputs with one switch
I want to control 4 digital outputs (d0, d1, d2, d3) with one switch. When the Arduino starts, they should all be in state LOW.

Now, after pressing the button once, d0 should get HIGH. Another push brings d0 to LOW and d1 to HIGH. So actually the 4 outputs shall behave like a bitmask. After every push the bitmask shall increment by one.

```
d0 LOW
d1 LOW
d2 LOW
d3 LOW

```

push

```
d0 HIGH
d1 LOW
d2 LOW
d3 LOW

```

push

```
d0 LOW
d1 HIGH
d2 LOW
d3 LOW

```

Is there an easy way to implement this, without typing every case in the code?

I am glad for any hints. Cheers and thanks.

# Answer
As usual with programming, there are many solutions, for example:

1. You can use a bitmask, put 4 variables in an array with binary values 1000, 0100, 0010 and 0001 and when the switch is pressed, you store the value into each LED pin by comparing the value.
2. However, a more simpler solution is just use a counter from 0 to 4, if the value is 1, the first LED should be one, then after a switch increase the value, and use modulo 5 (% 5) to go back to 0.

To check if a button is clicked, use a boolean, which check against the previous value. Also implement the debounce algorithm which can be found at the Arduino site.

Without debouncing it could look like this:

```
#include "stdlib.h"

int buttonPin    =   7;
int buttonState  = LOW;

int led1Pin      =   8;
int led2Pin      =   9;
int led3Pin      =  10;
int led4Pin      =  11;
int ledMode      =   0; // All off, 1-4 means LED 1-4 is on

void setup()
{
}

void loop()
{
   // Add debouncing yourself
   if ((buttonState == LOW) && (digitalRead(buttonPin) == HIGH))
   {
      buttonState = HIGH;
      ledMode = (ledMode + 1) % 5;
   }
   else if ((buttonState == HIGH) && (digitalRead(buttonPin) == LOW))
   {
      buttonState = LOW;
   }

   digitalWrite(led1Pin, ledMode == 1 ? HIGH : LOW);
   digitalWrite(led2Pin, ledMode == 2 ? HIGH : LOW);
   digitalWrite(led3Pin, ledMode == 3 ? HIGH : LOW);
   digitalWrite(led4Pin, ledMode == 4 ? HIGH : LOW);
}

```

If you put the LEDs on subsequent pins, you can use the following code which is more simpler and works for any number of LEDs:

```
#include "stdlib.h"

int buttonPin    =   7;
int buttonState  = LOW;

int nrOfLeds     =   4;
int startLed     =   8;
int ledMode      =   0; // All off, 1 means led on pin startLed, 2 means led on pin startLed + 1 etc.

void setup()
{
}

void loop()
{
   // Add debouncing yourself
   if ((buttonState == LOW) && (digitalRead(buttonPin) == HIGH))
   {
      buttonState = HIGH;
      ledMode = (ledMode + 1) % (nrOfLeds + 1);
   }
   else if ((buttonState == HIGH) && (digitalRead(buttonPin) == LOW))
   {
      buttonState = LOW;
   }

   for (int led = 0; led < nrOfLeds; ledPin++)
   {
       digitalWrite(startLed + led, ledMode == led + 1 ? HIGH : LOW);
   }
}

```
> 1 votes

---
Tags: arduino-nano, switch, bit
---


title: ignoring potentiometer value variations

text:
# Question
Title: ignoring potentiometer value variations
I've got a 50k potentiometer connected to an Arduino Uno. The user should adjust the hue of an Adafruit NeoPixelStrip.

I've got the following code inside the loop function:

```
int hue = analogRead(poti1);
int mappedHue = map(hue, 0, 1023, 0, 65535);

neoPixelStrip.fill(neoPixelStrip.gamma32(neoPixelStrip.ColorHSV(mappedHue, 255, 255)));
neoPixelStrip.show();

```

If I turn the potentiometer knob, the colors are updating correctly and reflect the correct hue. But if I let go of the knob, the LEDs are flickering a little (changing their hue values ever so slightly). If I print the potentiometer values to the console, they are changing a little. If I turn the potentiometer all the way to the left, the values range from 0 ... 13 or something. This change affects the hue of the pixels.

**How do I ignore those value variations? I want the user to constantly change the color, so I have to read the value constantly.**

**Any ideas?**

# Answer
You have two issues going on - noise pickup, and a potentiometer with imprecise stops at one or both ends.

The pot is the easiest to fix: What are the lowest low reading and highest high reading you can reliably get when you turn it to its stops? Use those in place of '0' and '1023' in your `map()` function.

Improving the noise is only slightly more involved. An exponential average is an easy filter to write and quite effective at quieting noisy data, as long the signal to noise ratio is fairly low. The basic idea is you add only a fraction of each new value and keep (1 - that fraction) of the old average; so if your chosen fraction is 0.1, you only consider 10% each new datum, keeping 90% of the current average.

`avg = f*avg + (1-f)*new_value`

The output of this averaging filter can be slow to respond to changes if your fraction is too small, but less effective at quieting noise if your fraction is too large.

I usually use .25, or 25% of each new point and 75% of the current average, when I'm just trying to clean up minor noise, which is what you probably have.

Here is my 25% averaging filter:

```
int16_t xpavg(int16_t newdat, int16_t avg){

   // (3 * avg + 1 * newdat) / 4
   return( (((avg<<2) - avg + newdat) + 2) >> 2 );
}

```

As you can see, I do the arithmetic in Fixed Point - just like integer arithmetic, but with an assumed binary point 2 places to the left during the computation. And I choose a fraction that represents "nicely" in binary - 1/4 in this case - to keep the arithmetic faster (since multiplication and division can be replaced by shifting).

The function just multiplies the current average by 4 and subtracts the old average (effectively multiplying by 3), adds the new value, and divides the sum by 4. (That extra "+2" rounds the fractional bits just before we shift them away). The end result is:
(3\*avg + newData)/4 (== 3/4\*avg + 1/4\*newData).

If you were to only sample the pot every second or two, you could probably observe the delay as the filter falls behind while you turn the pot and catches up when you stop. If you're sampling at 10x/sec or less, you shouldn't be able to notice.

Update:

You need to add the function `xpavg()` to your code, and call it each time you read a new pot value (that is "newdat"), passing it the old average as well. It returns a new average pot value, now less affected by noise. You use that new average value instead of the raw number you just read from the pot, in your hue calculation. As Duncan offered, you can - and I do - initialize the average with a raw value from the pot. You could also start it at zero but it will take a few samples to converge on the current actual pot reading. The downside of using one raw sample to start it is that if that one value is terribly noisy, i.e. way different from the pot reading, it will *still* take a few samples to converge.

```
unsigned int AvgPot = analogRead(poti1);        // initialize pot average

// Exponential averaging functions
int16_t xpavg(int16_t newdat, int16_t avg)
{
   // (3 * avg + 1 * newdat) / 4
   return( (((avg<<2) - avg + newdat) + 2) >> 2 );
}

void setup()
{
   ;    // initializations go here
}

void loop()
{
   int hue = analogRead(poti1);
   hue = xpavg(poti1, PotAvg);
   int mappedHue = map(hue, 0, 1023, 0, 65535);

   neoPixelStrip.fill(neoPixelStrip.gamma32(neoPixelStrip.ColorHSV(mappedHue, 255, 255)));
   neoPixelStrip.show();
}

```
> 3 votes

# Answer
There are many ways to remove noise, below are some ways:

* Only change the value when it differs enough. Assume the range is 0-1023. Than only change the value if the input value differs more than a constant value (like 5 or 10, experiment with this to find a good value for your pot meter).
* Another way is to use the average of the last x readings, You can also combine this with the previous approach. There might be a small delay because of the averaging.

There are many more solutions, from reasonably easy to very complicated, search for removing noise in sensor data.
> 2 votes

---
Tags: arduino-uno, analogread, potentiometer, neopixel, led-strip
---


title: How to convert char[12] to byte[6]

text:
# Question
Title: How to convert char[12] to byte[6]
I am trying to convert a char\[12\] array that contains a Mac Address into a byte\[6\] in order to use within the Ethernet.begin method. I have tried various methods from online, but had little success to date. The char array currently contains "A4BDC334688C" and i would like a byte array containing { A4, BD, C3, etc }.

The following is extremely close to working, with the output of the following "File Opened. A4BDC334688C A4 9D C3 34 68 6C" With BD incorecctly converting to 9D, and 8C becomming 68.

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

byte ByteMacAddress[6]; // RESERVED MAC ADDRESS
StaticJsonDocument<200> doc;

int ShotCount = 0;
byte buf[40];

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

  //Initialise SD Card for Config
  if (!SD.begin(4)) {
    Serial.println("initialization failed!");
  }

  // open the file for reading:
  File ConfigFile = SD.open("Config.txt");
  if (ConfigFile) {
    Serial.println("File Opened.");
  } else {
    Serial.println("error opening Config.txt");
  }

  //Deserialize Json Config in File
  delay(5);
  DeserializationError error = deserializeJson(doc, ConfigFile);
  ConfigFile.close();
  // Test if parsing succeeds.
  if (error) {
    Serial.print(F("deserializeJson() failed: "));
    Serial.println(error.c_str());
    return;
  }

  char* SDMacAddress = doc["MacAddress"];
  Serial.println(SDMacAddress);

  char arr[12];
  strcpy(arr, SDMacAddress);

  auto getNum = [](char c){ return c > '9' ? c - 'a' + 10 : c - '0'; };
  byte *ptr = ByteMacAddress;

  for(char *idx = arr ; *idx ; ++idx, ++ptr ){
    *ptr = (getNum( *idx++ ) << 4) + getNum( *idx );
  }

  //Check converted byte values.
  for( byte b : ByteMacAddress )
    Serial.println( b, HEX );
}

void loop(){
  //Maintain DHCP Lease
  //Ethernet.maintain();

  //GetShotCount();
  delay(500);
}

```

# Answer
> 2 votes
Please see the comments in the code:

```
// SDMacAdress is zero terminated
// (it should be because you use strcp not strncp)
// char arr[12]; you need one extra byte for the zero
char arr[13];
strcpy(arr, SDMacAddress);

auto getNum = [](char c)
{
  // you forgot upercase HEX letters (A-F)
  // don't use sophisticated code
  // the best programmers produce understandable code IMHO at least ;-)
  // perhaps you copied it from the internet
  // return c > '9' ? c - 'a' + 10 : c - '0';

  if ( c >= '0' && c <= '9' ) return c - '0';
  if ( c >= 'a' && c <= 'f' ) return 10 + c - 'a';
  if ( c >= 'A' && c <= 'F' ) return 10 + c - 'A';

  return 0;
};

byte *ptr = ByteMacAddress;

for(char *idx = arr ; *idx ; ++idx, ++ptr )
{
  *ptr = (getNum( *idx++ ) << 4) + getNum( *idx );
}

```

# Answer
> 2 votes
It is not clear why you are trying to implement it from scratch. If your input is always properly formatted you can perform the conversion in one call to `sscanf`

```
char arr[] = "A4BDC334688C";
byte ByteMacAddress[6];

sscanf(arr, "%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx",
  &ByteMacAddress[0],
  &ByteMacAddress[1],
  &ByteMacAddress[2],
  &ByteMacAddress[3],
  &ByteMacAddress[4],
  &ByteMacAddress[5]);

```

Of course, you can also implement it \[more elegantly\] through a cycle, i.e. `sscanf` it one byte at a time.

---
Tags: convert, bytes
---


# Question
Title: How to dynamically set pinMode and dynamically write value to pins in Arduino using arrays?
I am trying to create a library called "LED" for LED Sequencer in Arduino IDE,where the user has to configure the LED pins using an array and pass it to LED constructor in program and then will be able to use BlinkAll(),LeftToRight() and RightToLeft() Functions which lights the LED from Left to Right or Right to Left based on the sequence mentioned in the array. The problem is when I initiate the array and pass it to the constructor Pins 4,5,7 are not working at all , Please help me find what is the possible issue the code in LED.cpp file is shown below

```
#include <Arduino.h>
#include "LED.h"

LED::LED(int channel, int* a){
  _channel = channel;
  for(int i = 0 ; i < channel; i ++)
  {
    _pins[i] = a[i] ;
    pinMode(_pins[i],OUTPUT);
  }
}
void LED :: BlinkAll(int delay_ms)
{
   for (int i = 0 ; i<_channel;i++)
   {
    digitalWrite(_pins[i],HIGH);
   }
   delay(delay_ms);
   for (int i = 0 ; i<_channel;i++)
   {
    digitalWrite(_pins[i],LOW);
   }
   delay(delay_ms);
}
void LED :: LeftToRight(int numberofLEDs, int delay_ms)
{
  for(int i =0 ;i<_channel; i++)
  {
    digitalWrite(_pins[i], LOW);
  }
  for(int i =0 ;i<_channel; i++)
  {
//    if (i > 0)
//    {
//     digitalWrite(_pins[i-1], LOW);
//    }
  for(int i =0 ;i<_channel; i++)
  {
    digitalWrite(_pins[i], LOW);
  }
    digitalWrite(_pins[i], HIGH);
    delay(delay_ms);
  }
}
void LED :: RightToLeft(int numberofLEDs,int delay_ms)
{
    for(int i =_channel ;i>0; i--)
  {
    digitalWrite(_pins[i], LOW);
  }
  for(int i = _channel ;i>0; i--)
  {
    if (i < _channel)
    {
     digitalWrite(_pins[i+1], LOW);
    }
    digitalWrite(_pins[i], HIGH);
    delay(delay_ms);
  }
}

```

LCD.h

```
#ifndef LED_h
#define LED_h

#include <Arduino.h>

class LED
{
public:
  LED(int channel, int* pins);
  void BlinkAll(int delay_ms);
  void LeftToRight(int numberofLEDs, int delay_ms);
  void RightToLeft(int numberofLEDs, int delay_ms);
  void BlinkAlternate(int delay_ms);
private:
  int _channel;
  int _pins[16];
};

#endif

```

Sample Code

```
#include "LED.h"

int const LED_pins[8]={5,6,7,8,9,10,11,12};
int const No_of_LED = 8;

LED led(8,LED_pins);

void setup()
{
  Serial.begin(9600);
}
void loop()
{
  led.LeftToRight(1,500);
  led.RightToLeft(1,500);
}

```

# Answer
> 1 votes
It seems in the `LeftToRight` method, you didn't comment out enough (or too much), because you use a for loop inside another for loop which is probably unintended.

In the `RightToLeft' method I will try to fix the problem, so you can change the`LeftToRight\` method similarly.

```
void LED :: RightToLeft(int numberofLEDs,int delay_ms)
{
  for(int i =_channel ;i>0; i--)
  {
    digitalWrite(_pins[i], LOW);
  }
  for(int i = _channel ;i>0; i--)
  {
    if (i < _channel)
    {
     digitalWrite(_pins[i+1], LOW);
    }
    digitalWrite(_pins[i], HIGH);
    delay(delay_ms);
  }
}

```

The first for loop is to switch off the LEDs, I would make this a separate method, so it can be reused in both the `LeftToRight` and `RightToLeft` method, so you get:

```
void LED::RightToLeft(int numberofLEDs, int delay_ms)
{
  switchAllLedsOff();

  for(int i = _channel; i > 0; i--)
  {
    if (i < _channel)
    {
     digitalWrite(_pins[i + 1], LOW);
    }
    digitalWrite(_pins[i], HIGH);
    delay(delay_ms);
  }
}

void LED::SwitchAllLedsOff()
{
  for(int i = _channel; i > 0; i--)
  {
    digitalWrite(_pins[i], LOW);
  }
}

```

The problem is also, that you always write HIGH to a pin, since it overwrite the possible LOW assignment within the if statement. To correct this you get:

```
void LED::RightToLeft(int numberofLEDs, int delay_ms)
{
  switchAllLedsOff();

  for(int i = _channel; i > 0; i--)
  {
    digitalWrite(_pins[i + 1], i >= _channel ? HIGH : LOW);
    delay(delay_ms);
  }
}

```

You also can use an `if` statement, but in this case the ternary (? :) statement is more clear since the assignment is for a single destination (\_pins\[i + 1\]). So in case i \>= channel, it is set to HIGH, otherwise set to FALSE. I also inverted the operator, but you can keep it inverted too.

Third, \_channel seems to be the number of elements in the array, if you use it in an index it should start with \_channel - 1, so you get:

```
void LED::RightToLeft(int numberofLEDs, int delay_ms)
{
  switchAllLedsOff();

  for(int i = _channel - 1; i >= 0; i--)
  {
    digitalWrite(_pins[i + 1], i >= _channel - 1 ? HIGH : LOW);
    delay(delay_ms);
  }
}

```

There might be more problems, but the above are at lest some of them.

Also I changed your way of using spaces, although it's a matter of personal style, yours I never saw before (which doesn't mean it's incorrect of course).

(note I have not tested the program).

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


# Question
Title: Need a component to connect a 9v water pump
I have a 9v water pump that i want to turn on\off from the arduino, What module should i use to turn it on and off?

I am using now a mosfet for my 5v pump, can a mosfet be used for 9v as well? Or is there some better solution?

# Answer
Yes, a MOSFET should work just fine. As others have said in the comments, you just need to make sure that it's rated for your desired voltage and current, and that it's threshold voltage is low enough (around 2.5V) that the Arduino is able to drive it to saturation with a logic level 1 (5V).

I've used this one (rated at 60V and 30A) in various projects:

https://www.sparkfun.com/products/10213
> 0 votes

---
Tags: arduino-uno, motor
---


# Question
Title: Why are my thermistor readings backward?
I'm trying to build a thermistor that will flash an LED when the temperature is above 30 C. My set-up appeared to be reporting the room temperature correctly to the Serial Monitor, but then I noticed that exposing the thermistor to a hot object causes the reported temperature to drop, whereas exposing it to a cold object causes the reported temperature to rise.

I'd built a simpler thermistor circuit earlier with a similar approach and everything seemed to function correctly. I'm not sure what I broke here:

```
const int WarningLED = 7;
const int Thermistor = 0;

/* Thermistor information:
 * P/N: BC2301-ND
 * MFG P/n: NTCLE100E3103JB0
 * DESC: THERMISTOR NTC 10KOHM 3977K BEAD, IDX: 1 */

int Vo; // voltage between thermistor and R1
float R1 = 10000; //10 KOHM resistor used for voltage divider
float TR; // resistance of negative temperature coefficient (NTC) thermistor
float beta;  //beta will later equal ln( TR / Rref )
float Tk, Tc, Tf;

/* Steinhart-Hart equation coefficients via data table at
 * http://www.vishay.com/docs/29049/ntcle100.pdf
 * Bead used: 3977K (refer to #9 values on Nominal R table) */
float A = 3.354016e-03,B = 2.569850e-04;
float C = 2.620131e-06,D = 6.383091e-08;

void setup() {
  pinMode(WarningLED, OUTPUT); //sets the warning LED pin as a digital output
  Serial.begin(9600);          //  setup a serial port to enable comms with the computer.
 }

void loop() {

  Vo = analogRead(Thermistor);
  Serial.print("Vo: ");
  Serial.print(Vo);
  Serial.println(" mV");

  //Voltage divider equation: R2 = R1 * [Vo / (Vi - Vo)]
  //where R2 = TR, Vi = 1023.0 :
  TR = R1 * ((float)Vo / (1023.0 - (float)Vo));
  Serial.print("Thermistor resistance: ");
  Serial.print(TR);
  Serial.println(" ohms");

  beta = log(TR/10000); // As per extended Steinhart-Hart equation,
  //  where Rref = 10,000 (refer to page 10 of the PDF linked above)
  Tk = (1.0 / (A + B*beta + C*beta*beta + D*beta*beta*beta));
  Tc = Tk - 273.15;
  Tf = (Tc * 9.0)/ 5.0 + 32.0;

  Serial.print("Temperature: ");
  Serial.print(Tk);
  Serial.print(" K; ");
  Serial.print(Tf);
  Serial.print(" F; ");
  Serial.print(Tc);
  Serial.println(" C");
  Serial.println();

  if (Tc > 30.0) digitalWrite(WarningLED, HIGH);
  else if (Tc < 30.0) digitalWrite(WarningLED, LOW);
  delay(1000);
}

```

On the Serial Monitor, this reports:

```
Vo: 550 mV
Thermistor resistance: 11627.91 ohms
Temperature: 294.74 K; 70.86 F; 21.59 C

```

Exposing this to a warmer temperature incorrectly reports:

```
Vo: 597 mV
Thermistor resistance: 14014.08 ohms
Temperature: 290.61 K; 63.43 F; 17.46 C

```

I notice that, among other issues, this is reporting increased resistance in the thermistor despite that I'm using an NTC, but I'm not sure why this is occurring.

Notable parts used in this circuit:

* Thermistor: NTCLE100E3103JB0
* R1: 10 KOHM
* R2: 1 KOHM
* C1 & C2: 33 nf

# Answer
The voltage Vo is not the voltage over the thermistor, it is the voltage over R1! Switch the place of the thermistor and R1. /Mikael
> 2 votes

# Answer
In addition, note that the Vo is definitely not expressed in mV (millivolts), but in ADC steps , i.e. 1024th of the Vref, that is here 5V (default). And the reference is there that it should be 512 for 25deg.

Also, don't be fooled with the precision of the numbers given. Tolerance is 2% to 5% on the R25 value, which means up to ~25 "steps" (Vo). Assuming that reversing the R1 and TR gives you 450 at 22 deg, it means that your real threshold of 30 deg could be anywhere between 28 and 32 (roughly).

You can get better results by calibrating your TR: at 25deg, measuring its real resistance and using that instead of 10000 in your calculation is a first option. Calibrating for other temperatures is already way more complicated.
> 1 votes

---
Tags: arduino-uno, thermistor
---


# Question
Title: find out the pin numbers for the Arduino IDE for a certain board - the esp 32
I followed the tutorial I found here https://techtutorialsx.com/2019/03/29/esp32-arduino-controlling-a-dc-motor/ On the very interesting topic controlling a DC motor with the esp32 and Arduino I have some questions:

The first one: Where in the world did the guy find out the pin numbers for the Arduino IDE for this board? I have no idea how to find them!?

> Taking in consideration that the digital IO pins of the ESP32 can only source a maximum current of 40 mA \[1\], we cannot directly use them to control a DC motor.
>
> Instead, we are going to use a ULN2803A integrated circuit to actually provide the current to the motor, while the ESP32 will simply control if the motor is running or stopped.
>
> The connection diagram to control a DC motor from the ESP32 using an ULN2803A can be seen below at figure 1. for controlling a DC motor with the ESP32, using a ULN2803A integrated circuit
>
> The controlling of the DC motor with the ESP32 and a ULN2803A IC. In short, the ULN2803A will act as a switch, which will turn on / off the connection of the motor to GND, depending on the state of the input pin labeled as In 1. So, when the GPIO of the ESP32 is at a digital high value (VCC), the ULN2803A will connect the motor to GND, and thus the motor will be on. When the GPIO is at a digital low value (GND), then the motor will be disconnected from GND, and thus it will be off. Furthermore, the ULN2803A can be controlled by 3.3 V inputs and provide higher voltages, allowing us to control a 5 V DC motor with the ESP32.
>
> The code
>
> The code for this tutorial will be very simple, since we basically only need to control the status (high or low) of a digital pin of the ESP32.
>
> So, we will start by declaring as a global variable the number of the pin that will be connected to the DC motor.
>
> In my case I’ll be using GPIO 13. Note that for the Beetle ESP32 board, which is the one I’m using, this maps to the pin labeled as D7.
>
> ```
> int motorPin = 13;
>
> ```
>
> After that, we need to initialize the pin as output, in the Arduino setup function. To do that, we simply need to call the pinMode function.
>
> This function receives as first argument the number of the pin and as second argument a constant indicating the operating mode. So, we will pass the as first argument the value of the pin stored in our previously declared global variable and as second argument the constant OUTPUT.
>
> ```
> void setup() {
>
>   pinMode(motorPin, OUTPUT);
>
> }
>
> ```
>
> We will write the rest of our code in the Arduino main loop. We will first turn on the motor, wait some seconds, turn it off, wait some more seconds and then repeat.
>
> So, to turn the motor on, we simply need to set the value of the ESP32 digital pin to high, which will make the motor run at full speed. We can set the digital level of a pin with a call to the digitalWrite function.
>
> This function receives as first argument the number of the pin and as second argument a constant indicating the digital level to which the pin should be set.

# Answer
> 1 votes
An Arduino boards package with configuration for your board has constants for pins which correspond to labels on the PCB. The constants are defined in pins\_arduino.h file, which is applied only if you choose the corresponding board in Tools menu. In code you should use this constants as values for your constants, like for example `const uint8_t LED1_PIN = D2;`.

If the boards package doesn't have the board and you use generic settings, the you can study the schematics of the board to see which PCB pin goes to which MCU pin. Usually the logical pin numbers are labeled in schematics additionally to physical pin numbers of the chip.

Note: The linked pins\_arduino.h is for FireBeetle ESP32. The Beetle ESP32 is not defined in ESP32 boards package yet.

The schematics is on the Wiki page.

---
Tags: python, linux
---


title: Matching baud rate on serial monitor

text:
# Question
Title: Matching baud rate on serial monitor
I am using different codes which set different values of baud rate through the Serial.begin() function. Do I need to change the baud rate of the serial monitor to match the initialized value on the code I am running every time, or can I just leave the serial monitor baud rate set at the highest frequency of all my sketches (115200)?

# Answer
> 1 votes
If your sketch has

```
  ...
void setup() {
  Serial.begin(115200);
  // ... other stuff here;
}
  ...

```

And you run the IDE serial monitor at 9600, you will get gibberish. The same happens the other way round. You need to match the monitor to the baud rate you've defined on the `Serial.begin();` call.

# Answer
> 0 votes
Sometimes yes, and sometimes no.

The majority of Arduino boards are connected to your computer through a USB connection (there are some rare outside cases that use other connections like bluetooth or RS485...). That USB connection can fall into two broad categories:

1. A USB to UART adaptor that then connects to a UART on the Arduino's main MCU, and
2. A direct USB connection to the main MCU

Type 1 are such boards as the Uno, Mega and Nano. Basically any board that has both a main MCU and a secondary chip that lies between the USB connection and that MCU.

In this case the baud rate in the serial monitor is communicated to the USB interface chip and tells that chip "You are to communicate with the main MCU at this speed". You also then have to have the main MCU communicate with the USB chip at that same speed. So it is *imperative* that those two speeds match.

In the second case this isn't true. USB itself has no real concept of "baud rate". Instead the baud rate you set is merely a piece of configuration information the device at the end of the USB connection can use for something if it sees fit (what that "something" is, is entirely up to the device). Changing that baud rate has no real effect on the communication. Boards like the Leonardo and the Mini fall into this category. They all have a "U" chip, like the ATMega32U4, which directly talk USB.

So, in short:

* If you have a "Non-U" chip based board with a USB interface chip you *must* match the baud rates, and
* If you have a "U" chip based board (or some other make of board with a direct USB interface) then the whole concept of baud rate is meaningless1 and it really doesn't matter what the numbers are you choose to use where.

---

1. 1200 baud is a special case in Arduino USB boards as it is used to trigger the bootloader for uploading new code.

---
Tags: serial, baud-rate
---