# Question
Title: How to modify this code to use serial event to act after carriage return?
In part of a code used with UNO, I want to send number A and number B at once as A,B to the Arduino board if there is carriage return. So at the moment in HyperTerminal when I type: 100,0.5 the Arduino board immediately reacts x becomes 100 and n becomes 0.5. Following parts are related to reading with serial event:

```
void loop() {

      if (stringComplete){

      delay(1000);
      Mwrite(level);
      sendFrequency(n);
      delay(100);

      stringComplete = false;

   }
}

```

and in serial event:

```
void serialEvent() {

     while (Serial.available()) {

     slevel  = Serial.readStringUntil(',');
     Serial.read(); //next character is comma, so skip it using this
     x = Serial.readStringUntil(',');

     level = slevel.toInt();
     n = x.toDouble();
     stringComplete = true;
  }
}

```

But what I want to do is, I want the board only read the serial data only if I hit carriage return. So I should type 100,1 and then I should also hit carriage return for Arduino to react to the serial data.

How can this code be modified to achieve that?

# Answer
There are multiple ways you can solve it. The easiest way to do it is by just adding one more line in your code.

```
static bool stringComplete = false;
String x;
String slevel;
static int level;
static int n;

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

void loop()
{
  if (stringComplete)
  {
    Serial.println(level);
    Serial.println(n);
    stringComplete = false;
  }
}

void serialEvent()
{
  while(Serial.available())
  {
    slevel  = Serial.readStringUntil(',');

    //Serial.read(); // <-- You don't need this line. readStringUntil() will read ','

    x = Serial.readStringUntil(',');

    level = slevel.toInt();
    n = x.toDouble();
    Serial.readStringUntil('\r'); // <--------- Add this line
    stringComplete = true;
  }
}

```

But this is not probably the right way to do it. First, ***serialEvent()*** executes in between ***loop()*** i.e. this is what it looks like:

```
while(1)
{
    loop();
    serialEvent();
}

```

So, it is not like that the function will get called during a serial event. It just gets executed right after ***loop()***. Also ***readStringUntil()*** has a timeout (default: 1s). So if your 'until' character doesn't show up within one second of the function call, it will return with whatever it has. To test this, just type one character on your HyperTerminal and wait at least for a second, and see the output.

Ideally, this is how you should handle the serial's incoming byte:

* Check if there is serial byte available to read
* If there is, read one byte and save it in a buffer/string. (I'm not really a fan of **String** variables, but in the example, I will use String because you were using a **String**)
* If the byte you just read is delimiter (e.g. CR or '\r'), indicate the main loop that string is complete.
* In the main loop parse the whole string.

So this is how the code looks like with above-mentioned points:

```
static bool stringComplete = false;
String x;
String slevel;
static int level;
static int n;
String rxString = "";

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

void loop()
{
  if (stringComplete)
  {
    // Parse the rxString
    int index1 = rxString.indexOf(',');             // finds location of first ,
    slevel = rxString.substring(0, index1);         // captures first data String
    int index2 = rxString.indexOf(',', index1 + 1); //finds location of second ,
    x = rxString.substring(index1 + 1, index2);     //captures second data String

    level = slevel.toInt();
    n = x.toDouble();

    Serial.println(level);
    Serial.println(n);

    // Reset the string
    rxString = "";
    stringComplete = false;
  }
}

void serialEvent()
{
  while(Serial.available())
  {
    // get the new byte:
    char inChar = (char)Serial.read();
    // add it to the rxString:
    rxString += inChar;
    // if the incoming character is a carriage return, indicate main loop
    if (inChar == '\r')
    {
      stringComplete = true;
    }
  }
}

```
> 0 votes

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


# Question
Title: Why does my ATtiny85 blink program only work with 4 out of the 16 registers?
The following blink program runs fine on my Attiny85 SparkFun Tiny AVR programmer board. It produces 5 short blinks and then stops.

It also works fine when I change r16 to any one of the registers r17, r21 or r29. But trying with any other register gives either no blink at all (r19, r20, r23, r25, r26, r27, r28, r31) or indefinite blinks (r18, r22, r24, r30).

Can anyone explain?

```
int ledPin = 0;

void setup() {

  pinMode(ledPin, OUTPUT);

  asm("ldi r16, 5");
  asm("blink:");
  digitalWrite(ledPin, HIGH);
  delay(500);
  digitalWrite(ledPin, LOW);
  delay(500);
  asm("dec r16");
  asm("brge blink");
}

void loop() {
}

```

# Answer
Solved it myself! The high-level command "delay(500)" destroys the register contents. Saving the register (using push/pop) while doing delay() solves this issue. (Btw, is should be "brpl" and not "brge".)
> 0 votes

# Answer
As you discovered, calling a function may clobber some registers. To be precise, the avr-gcc documentation says:

> Call-Used Registers
>
> The call-used or call-clobbered general purpose registers (GPRs) are registers that might be destroyed (clobbered) by a function call.
>
> R18–R27, R30, R31 These GPRs are call clobbered. An ordinary function may use them without restoring the contents. Interrupt service routines (ISRs) must save and restore each register they use.
>
> Call-Saved Registers
>
> R2–R17, R28, R29 The remaining GPRs are call-saved, i.e. a function that uses such a registers must restore its original content. This applies even if the register is used to pass a function argument.

Now, an interesting detail here is that according to the documentation, one would expect R28 to work. Maybe that's not clobbered by the called procedure, but by your local procedure (mixing assembly and C in nontrivial amounts is a difficult task for precisely this reason).
> 0 votes

---
Tags: attiny85
---


# Question
Title: Arduino Uno & ESP32 communication using RS485
I am trying to establish a communication between Arduino Uno ( Master) and ESP32 (Slave) using RS485 protocol (using MAX485 module). I have successfully done this between two Arduino Unos. SoftwareSerial library is what i am using between two Arduino Unos, now trying with ESP32 and Arduino Uno (using MAX485 module) . For ESP32 i have used SoftwareSerial (https://github.com/akshaybaweja/SoftwareSerial) library.

After reading the library and making connection i am not be able to establish a communication between them. Sharing my code below.

**Receiver**

```
#include <SoftwareSerial.h>

SoftwareSerial softwareSerial(9, 10);
String str;

void setup()
{

  Serial.begin(9600);
  softwareSerial.begin(9600);

}

void loop()
{

  while (softwareSerial.available() > 0) {

    char inChar = softwareSerial.read();

    if (inChar == '$') {

        str.trim();
        Serial.println("received command" + str);
        memset(&str, 0, sizeof(str));
        Serial.flush();
        softwareSerial.flush();
    }
    else {
        str = str + inChar;
    }

 }

}

```

**Sender**

```
#include <SoftwareSerial.h>

SoftwareSerial swSer1(22, 23, false, 256);
String str;

void setup() {

  Serial.begin(9600);
  swSer1.begin(9600);

}

void loop() {

  String sendCmd = "MSG1$";
  Serial.println("Sending ");
  Serial.println(sendCmd );
  char copy[50];
  sendCmd.toCharArray(copy, 50);
  swSer1.write(sendCmd);
  delay(1000);

}

```

Here my question is where i am going wrong in this project. Please guide me.

**Note :** DE AND RE PINS are connected to high for sender device and to low for receiver device as given in the RS485 documentation.

# Answer
> 1 votes
Maybe you have already solved this but in any case, have you tried working with the hardware serial ports? You have three of them in the ESP32. I read sowhere else that there may be some interrupt issues using the SoftwareSerial library on the ESP devices, especially at higher baud rates.

# Answer
> 1 votes
I don't think you can use pins 9 and 10 they are connected to the internal mSPI flash, uart0 is connected to FTDI usb chip, use uart2 on 16 and 17.

---
Tags: arduino-uno, esp32, rs485, modbus, espressif
---


# Question
Title: not able to figure out what is wrong with my nodemcu code
```
#include <ESP8266WiFi.h>
#include <FirebaseArduino.h>

//Firebase settings
#define FIREBASE_HOST "..........firebaseio.com/"     //cant share
#define FIREBASE_AUTH "..............."               //cant share

//Wi-Fi settings
#define WIFI_SSID "kello"
#define WIFI_PASSWORD "8888"

//Define trigger and echo digital pins
const int trigPin = 4;
const int echoPin = 3;

// The amount of time the ultrassonic wave will be travelling for
long duration = 0;
// Define the distance variable
double distance = 0;

void setup()
{
     Serial.begin(9600);
    // Connect to Wi-Fi
    Serial.print("Wi-Fi...");
    WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
    Serial.print("Connecting...");
    while (WiFi.status() != WL_CONNECTED)
    {
        Serial.print(".");
        delay(500);
    }
    Serial.println();
    Serial.print("Connected to: ");
    Serial.println(WiFi.localIP());

    Firebase.begin(FIREBASE_HOST, FIREBASE_AUTH);

    // Ultrasonic sensor, set echo as Input and trigger as Output
    pinMode(trigPin, OUTPUT);
    pinMode(echoPin, INPUT);

}

void loop()
{

    getDistance();
    // Prints the distance value to the serial monitor
    Serial.print("Distance: ");
    Serial.println(distance);

    delay(500);
}

void getDistance()
{
    // Clear trigPin
    digitalWrite(trigPin, LOW);
    delayMicroseconds(2);

    // trigPin HIGH por 10ms
    digitalWrite(trigPin, HIGH);
    delayMicroseconds(10);
    digitalWrite(trigPin, LOW);

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

    // Calculating the distance, in centimeters, using the formula described in the first section.
    distance = duration * 0.034 / 2;

    // Sends the distance value to Firebase
    Firebase.setFloat("distance", distance);

}

```

I am a computer graduate so i do not have much knowledge about nodemcu. I saw some documentations about nodemcu. I want to show the data obtained by the ultrasonic distance sensor in the realtime database of firebase. But i am not able to figure out why i am not able to get output of **serial.println(distance)** in the com5 window even though the code compiles successfully . This is what i get when running the program

```
Executable segment sizes:

IROM   : 330560          - code in flash         (default or ICACHE_FLASH_ATTR)

IRAM   : 27760   / 32768 - code in IRAM          (ICACHE_RAM_ATTR, ISRs...)

DATA   : 1408  )         - initialized variables (global, static) in RAM/HEAP

RODATA : 2044  ) / 81920 - constants             (global, static) in RAM/HEAP

BSS    : 25160 )         - zeroed variables      (global, static) in RAM/HEAP

Sketch uses 361772 bytes (34%) of program storage space. Maximum is 1044464 bytes.
Global variables use 28612 bytes (34%) of dynamic memory, leaving 53308 bytes for local variables. Maximum is 81920 bytes.
esptool.py v2.8
Serial port COM5
Connecting....
Chip is ESP8266EX
Features: WiFi
Crystal is 26MHz
MAC: ec:fa:bc:c1:44:d2
Uploading stub...
Running stub...
Stub running...
Configuring flash size...
Auto-detected Flash size: 4MB
Compressed 365920 bytes to 264395...

Writing at 0x00000000... (5 %)
Writing at 0x00004000... (11 %)
Writing at 0x00008000... (17 %)
Writing at 0x0000c000... (23 %)
Writing at 0x00010000... (29 %)
Writing at 0x00014000... (35 %)
Writing at 0x00018000... (41 %)
Writing at 0x0001c000... (47 %)
Writing at 0x00020000... (52 %)
Writing at 0x00024000... (58 %)
Writing at 0x00028000... (64 %)
Writing at 0x0002c000... (70 %)
Writing at 0x00030000... (76 %)
Writing at 0x00034000... (82 %)
Writing at 0x00038000... (88 %)
Writing at 0x0003c000... (94 %)
Writing at 0x00040000... (100 %)
Wrote 365920 bytes (264395 compressed) at 0x00000000 in 23.4 seconds (effective 125.3 kbit/s)...
Hash of data verified.

Leaving...
Hard resetting via RTS pin...

```

Is the ultrasonic sensor not getting enough power supply as nodemcu is connected to my laptop? Please help me out and let me know if more information is required.

# Answer
Your `echoPin` Is defined as `3`. GPIO3 of the NodeMCU is also the “RX” pin needed for serial communication to the host. This might explain why you don’t see any output. You should change it to a different pin (for example pin 5 / D1 is a safe choice).

Each pin on the NodeMCU has a “GPIO” number (which is just the pin number as defined by the ESP8266 architecture) and a corresponding “Dx” designation (which is usually marked on the NodeMCU board).

Which GPIO pin corresponds to which which “D” pin is shown in pinout diagrams, like the one here. Scroll to the NodeMCU 12-E pinout.

Some of the safest pins to use are:

* Pin 5 (D1)
* Pin 4 (D2)
* Pin 12 (D6)
* Pin 13 (D7)
* Pin 14 (D5)

Some of the other pins could also be used, but have some restrictions, as you can see on the page I linked to.

Note that pins 12-14 are used for SPI and pins 4 and 5 are (normally) used for (software) I2C. If you want to control hardware that uses these protocols, these are the default pins it uses.
> 1 votes

---
Tags: nodemcu
---


# Question
Title: Converting the 3.3V PWM signal to 5V PWM signal
I am using ESP32....the max Pwm signal of it is 3.3V...And I have to control two motors speed by TB6612FNG motor driver...when i was using Arduino.. The arduino can send max 5V Pwm signal to the motor drivers PWM pin.. And the motor runs at the exact speed...but now i have to use ESP32..which sends 3.3V and the motors slow down..

So what should I do to convert the ESP32's PWM signal to 5v and according If i change the PWM value at the program..the output will also change similarly as Arduino?? Please help me

# Answer
> 1 votes
Looking at TB6612FNG datasheet i read

> Logic supply voltage (VCC) can be in the range of 2.7--5.5VDC

So, if you supply 3.3V to VCC all should be ok, if the motors themselves get enough power (via VM)

---
Tags: arduino-nano, esp32
---


# Question
Title: Combined code and nothing works. Head scratcher for sure
I have spent a little over 2 hours trying to debug this code. All I did was combine a section of code to write to the SD card. Both of the codes work fine on their own. I can't figure this one out. I am hoping fresh eyes can spot the error. I am using a Arduino Nano with a Robot-Deek data logger board. Pin 10 is used for the data logger. I was using a DTH11 but switched to a LM35, both codes worked with LM35.

```
#include "RTClib.h"
#include <SD.h>
#include <SPI.h>
#define sample 500
#define current_ms millis()
RTC_DS1307 rtc;
File myFile;
int inPin = 0;   //analog in
float val;       //where to store info from inPin reading
int pinRed = A3;  //output of red led
float tempin = A5;  //input of temp sensor
float tempf;     // variable to hold temp in Fahrenheit
float vout;      // variable to hold voltage from sensor
int array1[sample];  //creates an array with number of elements equal to "sample"
unsigned long averaging;  //the program uses this variable to store the sum of each array it makes
int pinCS = 10;   // write to SD card
float last_dht11_reading_ms = 1;
DateTime now = rtc.now();
#define DHT11_SAMPLE_DELAY 500

void setup() {

  Serial.begin(9600);
  delay(500);//Delay to let system boot
  SD.begin();
  pinMode(pinCS, OUTPUT);
  pinMode(tempin, INPUT);
  Serial.println("Volt and Temperature\n\n");
Serial.println("middle the setup loop");
 // SD Card Initialization
  if (SD.begin())
  {
    Serial.println("SD card is ready to use.");
    File myFile = SD.open("Datalog.csv",FILE_WRITE);
    if (myFile) {
      myFile.println("Time, Temp, Volt");
      myFile.close();
    }
  } else
  {
    Serial.println("SD card initialization failed");
    return;
  }
  rtc.begin();
  rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}//end "setup()"

void loop() {

  for (int i = 0; i < sample; i++) {         //this code tells the program to fill each element in the array we made with
    array1[i] = analogRead(inPin);           //information from the antenna wire coming out of the Arduino
    averaging += array1[i];                  //more information about for loops http://arduino.cc/en/Reference/For
  }                                          //the averaging line is simply saying: add averaging to whatever is in array position i
                                             //averaging += array[i] is the same as averaging = averaging + array[i]

  val = averaging / sample;                  //here the program takes the sum of all numbers in array1, and divides by the number of elements "sample"
  val = constrain(val, 0, 100);              //this constrains the variable value to between two numbers 0 and 100
  val = map(val, 0, 100, 0, 255);           //for more information about constrain http://arduino.cc/en/Reference/Constrain
  analogWrite(pinRed, val*20);                  //the map statement tells the program to map out 0-100 to 0-255
  averaging = 0;                                 //this line of code sets averaging back to zero so it can be used again
Serial.println("past the emf loop");

  if ( (current_ms - last_dht11_reading_ms) > DHT11_SAMPLE_DELAY ) {
    vout = analogRead(tempin);                //read LM35 output
    float mv = (vout/1024)*5000;              // conversion to mV
    float celc = mv/10;                       // convert to C
    float tempf = ((celc*9)/5 + 32)/10;       // convert to F
    myFile = SD.open("Datalog.csv", FILE_WRITE);      //open datalog file on SD card

  if (myFile) {                              //write to the SD card time, tempf and val
    myFile.print(now.hour());
    myFile.print(":");
    myFile.print(now.minute());
    myFile.print(":");
    myFile.print(now.second());
    myFile.print(",");
    myFile.print(tempf);
    myFile.print(",");
    myFile.println(val);
    myFile.close(); // close the file;    // close the file
    last_dht11_reading_ms = current_ms;
  }
Serial.println("past the logger loop");
  //delay(1000);//Wait 1 seconds before accessing sensor again.

}
}
// end loop()

```

# Answer
> 1 votes
`DateTime now = rtc.now();` Does not belong above void setup() 4hours to troubleshoot this little mistake.

---
Tags: arduino-nano, datalogging, data
---


title: Programming pic microchip

text:
# Question
Title: Programming pic microchip
I have a few pic chips, mainly pic16f72 and pic16f73 on old ups circuits, realized they are not that bad. Their adc capabilities are my point of focus.

I have an esp32 (my first mcu) and i am very disappointed mainly because its adc being crap, I did some research on programming pic chips, some could be programmed via an arduino but my chips were not mentioned anywhere. I wanna program them via my esp32..

Is there a way to program them via arduino (esp32 in my case)? I can build some basic circuits but diy pic programmers require a preprogrammed pic chip which I can't produce if I can't program one already.

# Answer
For PIC32 you need chipKIT. Not all chips are supported, but most of the PIC32MX and PIC32MZ chips are. Which exact PIC32 chip(s) do you have?

You will need to install a bootloader, for which you will need a programmer. It is possible to build a programmer using an Arduino, though TBH I'd just pick up a cheap PICkit2 clone from China.

As for the 8-bit PICs, no, they can't be programmed like an Arduino, simply because there is no open source C++ compiler available.
> 2 votes

# Answer
It seems, that you are talking about 2 different things:

* The programming/burning of the PIC can be done via an Arduino (so you don't need to build a complex PIC programmer circuit). It is irrelevant, what microcontroller type is on the programmer, as long as the programmer speaks ISP (the programming protocol). So even, when your specific PIC is not mentioned at your found sites, it should work nonetheless. The connections are every time the same, though of your specific PIC the used pin functions might be on other pins (consult the datasheet for this).
* An Arduino project - meaning the sketch/program, that was written for a normal Arduino, is normally not easily reusable. PICs are different microcontrollers with different hardware, so you need to port those projects to your specific microcontroller, which might involve extensive changes. When you have an Arduino Project, that was directly written for your PIC, then you can reuse it. (Be sure to install the correct core for your PIC in the Arduino IDE)
> 0 votes

---
Tags: programming
---


title: "Manually" generating a PWM signal

text:
# Question
Title: "Manually" generating a PWM signal
I've been trying, just out of curiosity, to write my own function that generates a PWM signal, just like `analogWrite()`, and to make it light up an LED. Here's my attempt so far:

```
const int pin = 3;
int cycle = 2; // analogWrite() outputs a 498 Hz signal, so each cycle has approximately 2ms

int duty = 0.5; // for a 50% duty cycle

void setup() {
  Serial.begin(9600);
  pinMode(pin,OUTPUT);
}

void loop() {
  digitalWrite(pin,HIGH);
  delay(cycle*duty);
  digitalWrite(pin,LOW);
  delay(cycle*(1-duty));
}

```

The LED does light up, but very dimly, as shown below:

However, when using `analogWrite()` with a 50% duty cycle to achieve the same result, the LED shines much brighter:

Is there something wrong with my code, or is there a special reason why more power is dissipated with `analogWrite()`?

# Answer
You need to review your code and also the capabilities of the Arduino UNO.

* `int` declares an integer. So `int duty = 0.5;` is going to get rounded to either 0 1.
* `delay(0);` also will not work. The instruction will simply get skipped. Likely the reason why you get a brighter LED. Try to use `delayMicroseconds();` if you need shorter time but the minimum delay you can have is 4 us for Arduino UNO.
* If you are using times as short as 2 us, then from the above comment the `delayMicroseconds();` function is not going to be sufficient. Also, you should consider the loop overhead, which will be a few microseconds.

All in all this is not a great method. If you do want to create your own PWM signals, it is much better to use the hardware timers. For example this tutorial on the Arduino website. You should also be able to find posts about hardware timers on Arduino SE.
> 4 votes

---
Tags: led, pwm, analogwrite
---


title: Run two Loops Simultaneously on Arduino

text:
# Question
Title: Run two Loops Simultaneously on Arduino
I am not able to combine the below two sketches. What I require is to either run both the loops together or find a way to run both the functions inside a single loop.

Sketch 1

```
#include <SevSeg.h>
#include <DS1307RTC.h>
#include <Time.h>
#include <TimeLib.h>
#include <Wire.h>

// Create an instance of the object
SevSeg sevseg;
bool militaryTime = false; // true for 24 hour clock

void setup() {
  byte numDigits = 4;
  byte digitPins[] = {2, 3, 4, 5};
  byte segmentPins[] = {6, 7, 8, 9, 10, 11, 12, 13};
  bool resistorsOnSegments = false; // 'false' means resistors are on digit pins
  byte hardwareConfig = COMMON_ANODE; // See README.md for options
  bool updateWithDelays = false; // Default. Recommended
  bool leadingZeros = true; // Use 'true' if you'd like to keep the leading zeros

  sevseg.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments, updateWithDelays, leadingZeros);
  sevseg.setBrightness(90);
}

void loop() {
  tmElements_t tm;
  int time;
  int dot;

  if (RTC.read(tm)) {
    time = tm.Hour * 100;
    if (time > 1200 && militaryTime == false) {
      time = time - 1200;
    }
    if (time == 0 && militaryTime == false) {
      time = 1200;
    }
    time += tm.Minute;
  }

  if ((tm.Second % 2) == 0) {
    dot = 4;
  } else {
    dot = 2;
  }

  //Produce an output on the display
  sevseg.refreshDisplay();
  sevseg.setNumber(time, dot);
}

```

Sketch 2

```
// Change this to the output pin you are using
#define TICK_PIN A0

void setup()
{
  pinMode(TICK_PIN,OUTPUT);
  while (1) {
    tone(TICK_PIN,1000,2);
    delay(1000);
  }
}

void loop()
{
}

```

# Answer
> 1 votes
Basically you need to get rid of the delay and any other blocking loops. Here is a way to do it.

Define this variable globally.

```
unsigned long lastTime = 0;

```

Then in your first loop, add the following code either to the beginning or the end:

```
if (millis() - lastTime >= 1000 || !lastTime) {
    lastTime = millis();
    tone(TICK_PIN,1000,2);
}

```

# Answer
> 1 votes
I fund the easiest way to work on this challenge when you have to deal with a long delay and think you need a second loop, is to make make a counter in the main loop using centiseconds (10 milliseconds) and then trigger your required response when the counter reaches your time like void loop(void) { counter=counter +1; if (counter==100){ tone(TICK\_PIN, 1000, 2); counter =0; } ....rest of code

# Answer
> 0 votes
One way is to use a timer callback.

```
// Include the timer1 library
#include "TimerOne.h"

// Other code here...

void setup()
{
    // Other setup code here....

    // Setup timer
    Timer1.initialize(1000000);          // 1 second
    Timer1.attachInterrupt(callback);    // Set callback
}

void callback()
{
    tone(TICK_PIN, 1000, 2);
}

void loop()
{
    // Code from 1st loop here...
}

```

If that doesn't work (if something else is using timer1) you could just keep track of the time between beeps:

```
uint32_t last_beep = 0;
const int beep_timeout = 1000;

void loop() {
    // Code from first loop here

    uint32_t now = millis();
    if (now - last_beep >= beep_timeout) {
        tone(TICK_PIN, 1000, 2);
        last_beep = now;
    }
}

```

# Answer
> -1 votes
> Run two Loops Simultaneously on Arduino

in general, the answer depends on your definition of "simultaneously".

But in this case, the answer is "definitively yes", as the other loop is empty.

a generic approach to this kind of questions is:

```
void setup(void) {
  setup1();  //run setup 1
  setup2();  //run setup 2
  ...
}

void loop(void) {
  loop1();  //run loop1
  loop2();  //run loop2
  ...
}

```

this approach would only fail if the original setup() and loop() are written poorly.

---
Tags: 7-segment
---


title: Mosquitto TLS over WifiMulti on ESP8266

text:
# Question
Title: Mosquitto TLS over WifiMulti on ESP8266
With these few lines I am able to attach my certificate, tell it to `WifiClientSecure` the certificate, start the `wifi` as well as the mosquito `pubsubclient`:

```
WiFiClientSecure espClient;
WiFi.begin(ssid, password);

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

PubSubClient mqtt_client(espClient);
mqtt_client.setServer(mqtt_server, 8883);
mqtt_client.setCallback(mqtt_callback);
espClient.setCertificate(ca_crt, ca_crt_len);

if (!mqtt_client.connected()) {
  mqtt_reconnect();
}

mqtt_client.loop();

```

With these lines I am able to connect to wifi, depending on which the closest station is:

```
ESP8266WiFiMulti wifiMulti;

wifiMulti.addAP("primary-network-name", "pass-to-primary-network");
wifiMulti.addAP("secondary-network-name", "pass-to-secondary-network");
wifiMulti.addAP("tertiary-network-name", "pass-to-tertiary-network");

wifiMulti.run();

```

How can I combine both? I.e, I am interested in sending data to secure MQTT over a set of possible wifi networks?

# Answer
> 2 votes
The WiFiMulti has nothing to to with the MQTT and TLS side of things at all. It only has anything to do with the WiFi. As such it just replaces the code that directly interfaces with the WiFi.

That is, this code:

```
WiFi.begin(ssid, password);

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

```

is replaced by this in the global scope:

```
ESP8266WiFiMulti wifiMulti;

```

This in setup():

```
wifiMulti.addAP("primary-network-name", "pass-to-primary-network");
wifiMulti.addAP("secondary-network-name", "pass-to-secondary-network");
wifiMulti.addAP("tertiary-network-name", "pass-to-tertiary-network");

```

and this in `loop()`:

```
wifiMulti.run();

```

All the MQTT side of things remains exactly the same.

# Answer
> 0 votes
Follow up on the answer from @Majenko.

```
#include <WiFiClientSecure.h>
#include <ESP8266WiFiMulti.h>
ESP8266WiFiMulti wifiMulti;
WiFiClientSecure espClient;

#include <PubSubClient.h>
PubSubClient mqtt_client(espClient);

Serial.println("setup_wifi_multi_addAP()");
wifiMulti.addAP("ap1", "pass1");
wifiMulti.addAP("ap2", "pass2");
wifiMulti.addAP("ap3",  "pass3");

while (wifiMulti.run() != WL_CONNECTED)
{
  Serial.print(".");
  delay(500);
}

Serial.printf(" connected to %s\n", WiFi.SSID().c_str());

mqtt_client.setServer(mqtt_server, 8883);
mqtt_client.setCallback(mqtt_callback);
espClient.setCertificate(ca_crt, ca_crt_len);

if (!mqtt_client.connected()) {
  mqtt_reconnect();
}
mqtt_client.loop();

void mqtt_reconnect() {
  Serial.println("mqtt_reconnect()");
  // Loop until we're reconnected
  while (!mqtt_client.connected()) {
    Serial.print("Attempting MQTT connection...");
    if (mqtt_client.connect("ESP8266mqtt_client-1")) {
      Serial.println("connected");
    } else {
      Serial.print("failed, rc=");
      Serial.print(mqtt_client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

```

# Answer
> 0 votes
If you are using only secure connection without require\_certificate in mosquitto configurattion just change espClient.setCertificate(ca\_crt, ca\_crt\_len); to espClient.setCACert(ca\_crt, ca\_crt\_len);

setCertiticate is used mainly to mutual authentication.

---
Tags: wifi, mqtt
---


# Question
Title: How do I put timers by using millis on 3 PIR sensors?
I want to make the PIRs to stay on for about 1 minute. I've found the code that can do so for 1 PIR, but I dont know how to apply the code for 3 PIRs.

Here is the code for 1 PIR with timer using `millis`:

```
int ledPin = 8;
int pirPin = 3;

unsigned long piron;
//the time we give the sensor to calibrate (10-60 secs according to the datasheet)
int calibrationTime = 10;

int off;
int on;
const int LDR = A0;
int ldrStatus;

unsigned long currentMillis =( millis()/1000 ) / 60;

/////////////////////////////
//SETUP
void setup(){
  Serial.begin(9600);
  pinMode(pirPin, INPUT);
  pinMode(ledPin, OUTPUT);
  digitalWrite(pirPin, LOW);

  //give the sensor some time to calibrate
  Serial.print("calibrating sensor ");
    for(int i = 0; i < calibrationTime; i++){
      Serial.print(".");
      delay(1000);
      }
    Serial.println(" done");
    Serial.println("SENSOR ACTIVE");
    delay(50);
  }

////////////////////////////
//LOOP
void loop()

{
ldrStatus = analogRead (LDR);
if (ldrStatus <= 700)     // variable reading(ldrStatus) according to ldr
                          // the higher reading(ldrStatus), the dimmer light
                          // the lower the reading(ldrStatus), the brighter light

{
analogRead (pirPin) == off;

Serial.println ("Its SUNNY DAY !!!");
digitalWrite(ledPin, LOW);

}

if (ldrStatus >= 700)
{
Serial.println ("Its DARK already");

    if(digitalRead(pirPin) == HIGH){
       digitalWrite (ledPin, HIGH);
     piron = ( millis()/1000 ) / 60;
  }

  if ((currentMillis - piron) > 1) {
    digitalWrite(ledPin, LOW);

  }

    }
}
`

and here is the code for 3 PIRs without the timer

    int calibrationTime = 10;

int pirPin = 3;
int ledPin = 8;

int pirPin1 = 4;
int ledPin1 = 9;

int pirPin2 = 5;
int ledPin2 = 10;

int ledPin3 = 11;

int off;
int on;
const int LDR = A0;
int ldrStatus;

/////////////////////////////
//SETUP
void setup(){
  Serial.begin(9600);
  pinMode(pirPin, INPUT);
  pinMode(ledPin, OUTPUT);
  digitalWrite(pirPin, LOW);

   pinMode(pirPin1, INPUT);
  pinMode(ledPin1, OUTPUT);
  digitalWrite(pirPin1, LOW);

   pinMode(pirPin2, INPUT);
  pinMode(ledPin2, OUTPUT);
  digitalWrite(pirPin2, LOW);

 pinMode (ledPin3, OUTPUT);

  //give the sensor some time to calibrate
  Serial.print("calibrating sensor ");
    for(int i = 0; i < calibrationTime; i++){
      Serial.print(".");
      delay(1000);
      }
    Serial.println(" done");
    Serial.println("SENSOR ACTIVE");
    delay(50);
  }

////////////////////////////
//LOOP
void loop()
{
ldrStatus = analogRead (LDR);
if (ldrStatus <= 700)     // variable reading(ldrStatus) according to ldr
                          // the higher reading(ldrStatus), the dimmer light
                          // the lower the reading(ldrStatus), the brighter light

{
analogRead (pirPin) == off;
analogRead (pirPin1) == off;
analogRead (pirPin2) == off;
Serial.println ("Its SUNNY DAY !!!");
digitalWrite(ledPin, LOW);
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, LOW);
digitalWrite(ledPin3, LOW);
}

if (ldrStatus >= 700)
{
Serial.println ("Its DARK already");
digitalWrite(ledPin3, HIGH);

    if(digitalRead(pirPin) == HIGH && digitalRead(pirPin1)== LOW && digitalRead(pirPin2) == LOW){
      digitalWrite (ledPin, HIGH);
      digitalWrite(ledPin1, LOW);
      digitalWrite(ledPin2,LOW);
    }

    if(digitalRead(pirPin) == LOW && digitalRead(pirPin1)== HIGH && digitalRead(pirPin2) == LOW){
      digitalWrite (ledPin1, HIGH);
      digitalWrite (ledPin, LOW);
      digitalWrite(ledPin2,LOW);

}
   if(digitalRead(pirPin) == LOW && digitalRead(pirPin1)== LOW && digitalRead(pirPin2) == HIGH){
      digitalWrite (ledPin2, HIGH);
      digitalWrite (ledPin1, LOW);
      digitalWrite (ledPin, LOW);

   }

     if(digitalRead(pirPin) == HIGH && digitalRead(pirPin1)== HIGH && digitalRead(pirPin2) == LOW){
    digitalWrite (ledPin1, HIGH);
    digitalWrite (ledPin, HIGH);
    digitalWrite (ledPin2, LOW);

}

     if(digitalRead(pirPin) == HIGH && digitalRead(pirPin1)== LOW && digitalRead(pirPin2) == HIGH){
      digitalWrite (ledPin, HIGH);
      digitalWrite (ledPin2, HIGH);
      digitalWrite (ledPin1, LOW);
     }

     if(digitalRead(pirPin) == LOW && digitalRead(pirPin1)== HIGH && digitalRead(pirPin2) == HIGH){
     digitalWrite (ledPin2, HIGH);
     digitalWrite (ledPin1, HIGH);
     digitalWrite (ledPin, LOW);
     }

    if(digitalRead(pirPin) == HIGH && digitalRead(pirPin1)== HIGH && digitalRead(pirPin2) == HIGH){
      digitalWrite (ledPin2, HIGH);
      digitalWrite (ledPin1, HIGH);
      digitalWrite (ledPin, HIGH);

    }

     if(digitalRead(pirPin) == LOW && digitalRead(pirPin1)== LOW && digitalRead(pirPin2) == LOW){
      digitalWrite (ledPin2, LOW);
      digitalWrite (ledPin1, LOW);
      digitalWrite (ledPin, LOW);
     }

}

}

```

# Answer
> 1 votes
This is not a complete answer, but an idea of how to accomplish the task.

I just typed it in without testing the code.

Use arrays to hold variables. That way a loop can be used to service the three sensors and the three LEDs..

```
for (i = 0; i<3; i++) {
   currentTime = millis();                             // save current millis() value

   if (digitalRead(pirPin[i]) == HIGH) {               // check if PIR is detecting motion
      trigTime[i] = millis();                          // save trigger time
      trig[i]     = true;                              // set a state variable that indicates
   }                                                   //   that a trigger happened

   if (trig[i]) {                                      // if trigger happened
      if (currentTime - trigTime[i] < 50000) {         // is it less than 50 sec since last motion?
         digitalWrite (ledPin[i], HIGH);
      }
      else {
         trig[i] = false;                              // 50 second timer ran out
         digitalWrite (ledPin[i], LOW);
      }
   }
}

```

---
Tags: arduino-uno, sensors, led, millis
---


title: Problem with if condition

text:
# Question
Title: Problem with if condition
So my project is including detecting the temperature in the room by using dth11 sensor. my idea is to add 3 LED lights were each light represent the temperature if its cold or hot or perfect.

the wiring and coding is done and it's working .However, i'm having a problem were the perfect temperature is always on no matter if the temperature is hot or cold. example: if the temperature is cold the cold LED will blink and the perfect temperature LED will be on.

```
#include <Adafruit_Sensor.h>
#include <DHT.h>
#define DHTPIN A0
#define DHTTYPE DHT11
#define LED_TOO_COLD 6
#define LED_PERFECT 8
#define LED_TOO_HOT 7
DHT dht(DHTPIN, DHTTYPE);
void setup() {
  Serial.begin(9600);
  Serial.println("DHT11 test!");

  dht.begin();
}

void loop() {

  pinMode (6 , OUTPUT);
  pinMode (7 , OUTPUT);
  pinMode (8 , OUTPUT);
  delay(2000);

  float h = dht.readHumidity();
  float t = dht.readTemperature();
  float f = dht.readTemperature(true);

  if (isnan(h) || isnan(t) || isnan(f)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }

  Serial.print("Humidity: ");
  Serial.print(h);
  Serial.print(" %\t");
  Serial.print("Temperature: ");
  Serial.print(t);
  Serial.println(" *C ");
  if (t < 22) {
    Serial.println("Too cold!");
    digitalWrite(6, HIGH);
    digitalWrite(7, LOW);
    digitalWrite(8, LOW);
    delay (2000);
  }
   if (t >26) {
    Serial.println("Too hot!");
    digitalWrite(7, HIGH);
    digitalWrite(6, LOW);
    digitalWrite(8, LOW);
    delay (2000);

  } else {
    Serial.println("Perfect temperature!");
    digitalWrite(8, HIGH);
    digitalWrite(6, LOW);
    digitalWrite(7, LOW);
    delay (2000);
  }

}

```

# Answer
firstly, move your `pinMode()` settings to `setup` section.

in your code, when the temperature is `21` active pin will be 6 and 8. you should rewrite your code in next ways:

1:

```
if (t < 22) {
  ... its cold temp ...
} else if (t > 26) {
  ... its hot temp ...
} else {
  ... it's nor temp ...
}

```

2:

```
if (t < 22) {
   ... its cold temp ...
}
if (t > 26) {
   ... it's hot temp ...
}
if (t >= 22 && t <= 26) {
   ... it's nor temp ...
}

```

and my small advice for u, rewrite in this way, it is more readable

```
digitalWrite(6, HIGH);
digitalWrite(7, LOW);
digitalWrite(8, LOW);

digitalWrite(6, LOW);
digitalWrite(7, HIGH);
digitalWrite(8, LOW);

digitalWrite(6, LOW);
digitalWrite(7, LOW);
digitalWrite(8, HIGH);

```

visually changing ENUMS (like LOW or HIGH) more noticeable than changing numbers (6/7/8)
> 1 votes

---
Tags: arduino-uno, programming, sensors, temperature-sensor, temperature
---


# Question
Title: LCD write a line at bottom without lcd.setCursor and without deleting any char above already there?
lcd.cursor and lcd.noCursor won't work for what I want to use it for since it seemed to be "global" sort of speak and follow lcd.setCursor which I don't want it to but it is otherwise exactly what I want to be done; just to put a line at the very bottom and also remove the line whenever I want to but without removing the entire char above.

Just like lcd.cursor do but as said it won't work in the code since the line has to reside where it is even if lcd.setCursor is used elsewhere but then the cursor line follow to that other point which I don't want and such a controllable cursor that sits at the place even if lcd.setCursor is used elsewhere. But the char there first and then the line of vice versa doesn't matter just as long as there it a line. And I cant create custom chars with a line under them since its numbers from 0 - 9 and so many custom chars can't be made.

It's fully possible to write to the bottom row though and I thought it would be possible to do something with lcd.createChar by not no write anything at all at the bytes rows but the lowest one, but that surprisingly failed. This is what I tested:

```
byte line[8] = {

  B,
  B,
  B,
  B,
  B,
  B,
  B,
  B11111,
};

```

And that writes on the lowest row as expected, but strangely enough STILL deletes any char that is written above even if nothing should have been written there as I see it.

The test here put out pretty much garbage and pretty much delete the char written but something still remain but the line is written at top instead of bottom and I guess it all goes out of the normal bounds in the registry or something:

```
#include <LiquidCrystal.h>
LiquidCrystal lcd(40, 42, 28, 26, 24, 22);

byte line[1] = {

  B00000,
};

byte noline[1] = {

  B11111,
};

byte sure[8] = {   //It didn't like to use "square" as name by whatever the reason

  B00000,
  B00000,
  B01110,
  B01110,
  B01110,
  B01110,
  B00000,
  B00000,
};

void setup() {

  lcd.createChar(0, line);
  lcd.createChar(1, noline);
  lcd.createChar(2, sure);

  lcd.begin(20, 4);
  lcd:clear:
}

void loop() {

  delay(500);
  lcd.setCursor(0, 0);
  lcd.write(byte(2));
  delay(500);
  lcd.setCursor(0, 0);
  lcd.write(byte(1));
  delay(500);
  lcd.setCursor(0, 0);
  lcd.write(byte(0));

}

```

Any tips on how to do the same with create.Char or any other simple way? I mean the lcd.cursor and lcd.noCursor can do it, how do that do it then? It's an ordinary 20X4 LCD if that would matter.

# Answer
I do not really understand what you mean by your first sentence. Did you succeed in getting a "hardware" cursor to display together with a character or not? And if you do, why doesn't this fulfill your requirements?

You have to realize that your LCD cannot display partial characters, like a line at the bottom, leaving the rest of the character that was already there intact. An exception is a hardware generated cursor.

You also have to realize that createChar always expects a full character with 8 rows.

**Your code examples**

In your first example, starting with `byte line[8] = {`, the first 7 "empty" `B,` lines actually produce a value of (binary) zero. So here you create an empty character with a line at the bottom, exactly like you said you see on the display.

In your second piece of code, you define characters `byte line[1] =` and `byte noline[1] =` consisting of just 1 byte. createChar expects 8 bytes. createChar will fill the characters with the single byte defined in your character definition, plus whatever it finds in the 7 memory locations following your actual definition (which will probably contain some random data). This explains the "garbage" you see on the screen.

**Possible solution**

One solution would be to re-create each character you want your cursor to display under, on the fly. I.e. if you want your cursor to be displayed under the letter "A", you create a complete custom character which contains "A", plus a cursor underneath and you display it in place of the real "A" at this location. When you move the cursor, you replace the "custom" A with the real "A" again.

This will be cumbersome in code complexity as well as code size (you'd have to create a complete character map for every character you wish to display), but should be a feasible solution.
> 1 votes

---
Tags: custom
---


title: Arduino Nano 33 IOT issue

text:
# Question
Title: Arduino Nano 33 IOT issue
Nano 33 IOT is not detecting by windows . When i plug the usb cable only green light on the board. Board is installed from the board manager. the cable is usb DATA cable and not charging cable. I tried the double press on the reset button but nothing happen. The L light is Off and the green light isnt flashing. I plugged the board into another usb port, the same issue. I tried the board on my friend computer also but no luck. I dont have ATmel ICE or any other debugger like j-link. https://www.youtube.com/watch?v=C0tXa0uxv5c

I hope someone can explain what is the issue, is it hardware or software.

# Answer
If you upload to a SAMD board like the MKR boards or the Nano 33 IoT **with Nano 33 BLE selected in Tools menu** of Arduino IDE, **the upload** is executed and **deletes the bootloader of the SAMD** MCU.

The problem is that bossac uploader doesn't check the chip, because it was developed only for the SAMD chips, but Arduino created a bootloader for the Nano 33 BLE nRF52 MCU to use the SAMD bossac uploader.

The SAMD boards use the native USB support of the MCU, so without a bootloader or good sketch running the USB doesn't work.

You have to restore the bootloader on Nano 33 IoT. It is done over the SWD pads on the bottom side of the board. You can use a SWD programmer or other Arduino board with the Adafruit DAP library.

You can use your Nano 33 BLE or some other board and a SD card with Adafruit DAP library as programmer.

I had this problem with MKR Zero and I used a LPC-Link2 programmer to burn the bootloader. Once before I lost the bootloader for other reason and back then I didn't have the programmer so I used the Adafruit DAP library with an Arduino M0.
> 2 votes

# Answer
After I waited to get my order on ebay. I managed to restore the bricked board. The issue was related to bootloader fail. either the producer shipped it without a bootloader or some kind of static discharge caused to erase or stop the booloader from working and that why windowws didnt detect the board. I used a converted cortex m3 to swd programmer debugger and one line cmd command.

Thank for all who contributed solutions. If anyone experience the same hardware failure, it is due to missing or corrupted bootloader.
> 2 votes

---
Tags: arduino-uno, arduino-ide, arduino-nano
---


title: Arduino IR remote control hold value

text:
# Question
Title: Arduino IR remote control hold value
I am trying to make a remote controlled robot with Arduino and the IR remote control is kinda weird. When I press a button, sometimes I get the right hex value, other time I get the hold value FFFFFF.

How can I implement some code so that I can, for example, run the motors as long as I hold the button or detect which button it was since the hold code is the same for all codes?

Since I know that the hold value is 0xFFFFFFFF, is there a function that:

```
(any hex not 0xffff) func(OR?) (0xffffffff) = (any hex ...)

```

and

```
( 0xfffff)           func (0xffffff)   != (0xffffff)

```

Or do I need to implement some kind of state machine? It is kinda difficult with the `delay()` as well.

By the way, I'm using Keyes KY 022. What are the signal length times? (I don't have an oscilloscope).

Maybe would be useful to set the press value to other? Or to ignore it?

LE: And some code to test: one single key:

Maybe other libraries are interrupting the timer...

```
    #include <IRremote.h>
    #define IR_PIN 11
    IRrecv irrecv(IR_PIN);
    decode_results results;
    long int Key;
    const unsigned long int UP = 0x00FF629D;
    const unsigned long int DOWN = 0x00FFA857;
    const unsigned long int LEFT = 0x00FF22DD;
    const unsigned long int RIGHT = 0x00FFC23D;
    const unsigned long int OK = 0x00FF02FD;
    const unsigned long int k1 = 0x00FF6897;// C101E57B
    const unsigned long int k2 = 0x00FF9867;// 97483BFB
    const unsigned long int k3 = 0x00FFB04F;// F0C41643
    const unsigned long int k4 = 0x00FF30CF;
    const unsigned long int k5 = 0x00FF18E7;
    const unsigned long int k6 = 0x00FF7A85;
    const unsigned long int k7 = 0x00FF10EF;
    const unsigned long int k8 = 0x00FF38C7;
    const unsigned long int k9 = 0x00FF5AA5;
    const unsigned long int STAR = 0x00FF42BD;
    const unsigned long int k0 = 0x00FF4AB5;
    const unsigned long int HASH = 0x00FF52AD;
    const unsigned long int HOLD = 0xFFFFFFFF;

   void setup(){
   // put your setup code here, to run once:
      Serial.begin(9600);
      delay(2000); while (!Serial);
      irrecv.enableIRIn();
  //irrecv.blink13(true);
  //setup1(); From IRremoteInfo TAB
   }
char buff[1000];
unsigned long int msg;
void processIR(unsigned long int msg)
{
  sprintf(buff, "READ IR %x \n", results.value);
  Serial.print(buff);
  switch (msg)
  {
    case UP:
      Serial.println("UP");
      break;
    case DOWN:
      Serial.println("DOWN");
      break;
    case LEFT:
      Serial.println("LEFT");
      break;
    case RIGHT:
      Serial.println("RIGHT");
      break;
    case k1:
      Serial.println("k1");
      break;
    case k2:
      Serial.println("k2");
      break;
    case k3:
      Serial.println("k3");
      break;
    case k4:
      Serial.println("k4");
      break;
    case k5:
      Serial.println("k5");
      break;
    case k6:
      Serial.println("k6");
      break;
    case k7:
      Serial.println("k7");
      break;
    case k8:
      Serial.println("k8");
      break;
    case k9:
      Serial.println("k9");
      break;
    case STAR:
      Serial.println("STAR");
      break;
    case k0:
      Serial.println("k0");
      break;
    case HASH:
      Serial.println("HASH");
      break;
    case HOLD:
      Serial.println("HOLD");
      break;
      //case default:
      //    delay(500);
      //       irrecv.decode(&results);
      //       msg = results.value;
      //       processIR(msg);
  }
}

void loop() {
  // put your main code here, to run repeatedly:
  if (irrecv.decode(&results))
  {
    irrecv.resume();
    char buff[255];
    sprintf(buff, "Val %010x \n " , results.value );
    Serial.print(buff);
    //results.decode();
    //results.DumpResults();
    //      msg = results.value;
    //      Serial.println(msg, HEX);
    //      Serial.println(results.decode_type);
    //      processIR(msg);

  }

}

```

And values, of course:

```
 Val 0x0000629d
 Val 0x0000ffff
 Val 0x0000629d
 Val 0x0000ffff
 Val 0x0000629d
 Val 0x0000ffff
 Val 0x0000629d
 Val 0x0000ffff
 Val 0x0000629d
 Val 0x0000ffff
 Val 0x0000629d
 Val 0x0000ffff
 Val 0x0000629d
 Val 0x0000ffff
 Val 0x0000629d
 Val 0x0000ffff
 Val 0x0000629d
 Val 0x0000ffff
 Val 0x0000629d
 Val 0x0000ffff
 Val 0x0000629d
 Val 0x0000ffff
 Val 0x0000629d
 Val 0x0000ffff
 Val 0x0000629d
 Val 0x0000ffff
 Val 0x0000629d
 Val 0x0000ffff
 Val 0x0000629d
 Val 0x0000ffff
 Val 0x0000629d
 Val 0x0000ffff
 Val 0x0000629d
 Val 0x0000ffff
 Val 0x0000ffff
 Val 0x0000629d
 Val 0x0000ffff
 Val 0x0000629d
 Val 0x0000ffff
 Val 0x0000629d
 Val 0x0000ffff
 Val 0x0000629d
 Val 0x0000629d
 Val 0x0000ffff
 Val 0x0000629d
 Val 0x0000ffff
 Val 0x0000629d
 Val 0x0000ffff
 Val 0x0000629d
 Val 0x0000ffff
 Val 0x000002fd
 Val 0x0000ffff
 Val 0x0000629d
 Val 0x0000ffff
 Val 0x0000629d
 Val 0x0000629d
 Val 0x0000ffff
 Val 0x000022dd
 Val 0x0000ffff
 Val 0x0000c23d
 Val 0x0000ffff
 Val 0x0000629d
 Val 0x0000ffff
 Val 0x0000629d
 Val 0x0000ffff
 Val 0x0000629d
 Val 0x0000ffff
 Val 0x0000629d
 Val 0x0000ffff
 Val 0x0000ffff
 Val 0x0000ffff
 Val 0x0000ffff
 Val 0x0000ffff
 Val 0x0000ffff
 Val 0x0000ffff
 Val 0x0000629d
 Val 0x0000ffff
 Val 0x0000629d
 Val 0x0000ffff
 Val 0x0000629d
 Val 0x0000ffff
 Val 0x00005282
 Val 0x000038d6
 Val 0x0000ffff
 Val 0x0000efb5
 Val 0x00006897
 Val 0x00006897
 Val 0x00006897
 Val 0x0000ffff
 Val 0x00006897
 Val 0x00006897
 Val 0x0000ffff
 Val 0x00006897
 Val 0x00009867
 Val 0x00009867
 Val 0x0000b04f
 Val 0x0000ffff
 Val 0x00004794
 Val 0x00009424
 Val 0x0000ffff
 Val 0x000042bd
 Val 0x0000ffff
 Val 0x00004ab5
 Val 0x0000ffff
 Val 0x000052ad
 Val 0x0000ffff
 Val 0x00004ab5
 Val 0x00005aa5
 Val 0x0000ffff
 Val 0x000038c7
 Val 0x000010ef
 Val 0x0000ffff
 Val 0x000030cf
 Val 0x0000ffff
 Val 0x000018e7
 Val 0x0000ffff
 Val 0x00007a85
 Val 0x0000ffff
 Val 0x00004ec5
 Val 0x00007a2a
 Val 0x00007d4f
 Val 0x0000a33f
 Val 0x00007a28
 Val 0x00008dd8
 Val 0x00004b78
 Val 0x0000144b
 Val 0x00006781
 Val 0x0000040a
 Val 0x0000ffbf
 Val 0x00007d4f
 Val 0x0000ee7c
 Val 0x0000629d
 Val 0x0000ffff
 Val 0x0000629d
 Val 0x0000ffff
 Val 0x0000629d
 Val 0x0000ffff
 Val 0x0000629d
 Val 0x0000ffff

```

So each press of a key gives 2 values.

# Answer
> 1 votes
If I understand your question correctly, a button press will first generate a distinct hex code, and then after a while a series of `0xFFFFFF`?

In that case, why don't you simply store the last distinct code you received, and replace occurrences of `0xFFFFFF` with the stored code?

# Answer
> 1 votes
I found out that by adding this while loop to an IRremote use, the code after it won't run until the button is released.

```
while(irrecv.decode(&results)){
    irrecv.resume();
    delay(150);
}

```

This will keep the buttons pressed if the code at the end on `loop()` ends the input.

---
Tags: programming
---


# Question
Title: Arduino Mega LED doesn't light as expected
I wrote this for my Arduino Mega 2560:

```
int LED[14] = { 28,29,30,31,32,33,34,35,36,37,38,39,40,41 } ;
...
... (some other code like setup(), etc. Note:pinmode output for this 14 leds wich pins is defined in
... array named LED[]
...
void intro(){
  for(int j=1; j<100; j++ ){
    for(int r=1; r<15; r++ ){ digitalWrite(LED[r],HIGH); delay(100);  }
    delay(100);
    for(int r=1; r<15; r++ ){digitalWrite(LED[r],LOW); delay(100);}
    delay(100);
  }
  Serial.print("Pattern started");
  delay(1000);
}

```

So when I run this script, I expect that each LED will light up in the sequence and remain lit until the second loop to turn it off, but I see that when lighting each LED, when lighting the 9th LED, the first 8 LEDs shut off inexplicably and LEDs 9 through 14 light one by one, remaining lit. That I expected but why do the first 8 LEDs shut off before the loop ends and the second loop starts?

# Answer
While it is true that your loop is incorrect, the coding error is unlikely to cause the behaviour that you have described.

Please ensure that a current limiting resistor is placed in series with each LED. Since you have 14 LEDs, you will need 14 current limiting resistors. 470 Ohm resistors (or similar) should be adequate for this purpose.

As per the other comments, C++ Arrays start at 0, not 1. The last element is the size of the array minus 1. In your case 14 - 1 = 13. Thus the loop can continue as long as the index is \< 14 (or \<= 13)

Thus your loops should read:

```
for(int r=0; r<14; r++ ) {
  digitalWrite(LED[r],HIGH);
  delay(100);
}

```
> 1 votes

# Answer
your for statements with r=1 need to be changed to r=0;r\<14 Arrays always start with the first item being 0, so yours is 0 to 13.
> 0 votes

---
Tags: arduino-mega
---


title: Hooking Up 8 ohm Speaker to Arduino

text:
# Question
Title: Hooking Up 8 ohm Speaker to Arduino
Is this a correct way to connect an 8 ohm beaker to an Arduino?

https://www.c-sharpcorner.com/article/audio-play-using-sd-card-module-and-arduino/

# Answer
To effectively drive a speaker from an Arduino you need an amplifier. The good ol' LM386 is a common choice for this (readily available and cheap, though not recommended for battery based projects).

While it is *possible* to drive a speaker directly it's not recommended. Not only is it very quiet, but also it can damage the IO pin. Not only from excess current draw (peak current at 5V through 8Ω \[nominal\] is 626mA, more than 15x the maximum the pin can supply, which not only stresses the pin but also distorts the output waveform) but a speaker is also an inductive load which has all the associated issues of back-EMF and such.
> 1 votes

# Answer
You had to put a resistor in serial with the speaker, Max current from the pin is 40 mA if put 8 ohm speaker on the pin it can't drive the speaker. Try a speaker with higher impedans.
> -1 votes

---
Tags: speaker
---


title: Making Cases for Projects

text:
# Question
Title: Making Cases for Projects
I've been messing around with arduinos and other microcontrollers for around a year now and I've always struggled to find ways to encase my projects. I've seen some people use custom PCBs and then 3D print a case for that. How would one go about that? I am only a computer science student so I know nothing about electrical circuitry. For example, lets say I have a UltraSonic Sensor that uses a Arduino nano to light an LED. How would I transfer that to a single PCB? And are there websites where I can order custom 3D printed cases for my projects? Please let me know if you need me to make my question clearer. Thank you!

# Answer
> 2 votes
Your question has multiple layers:

1. **The custom PCB:** Breadboards are good for experimenting, but not for a finalized circuit. Depending on some factors you can decide between multiple options. One, that I myself often use, is soldering the parts onto a perfboard. That are cheap PCBs, where - depending on the type - you have a grid of single through-hole solder pads or connected groups of through-hole solder pads. I like to use these:

The pads are connected nearly like a breadboard, so it is easy to use with Arduinos and such. You can build your circuit on there by soldering the parts to it, and make the PCB the right size by cutting it into the needed size.

A more professional option is to buy real custom PCBs. You need to create the PCB layout on your PC (common programs are Eagle or Kicad, though there are many others). Then you can choose the PCB manufacturer of your trust and give them your layout files. They will manufacture the PCBs and send them to you. This options costs a bit money (though not a lot) and you will have to wait for the PCBs to arrive.
2. **The casing:** There are many options to choose from:

* You can buy a generic case somewhere (hardware store, or the internet shop of your trust). Then you can work on it to fit your purpose (drilling holes for the LEDs, using screws or glue to fix your PCB, ...)
    * There are some standard cases to buy, though most of them most likely don't fit you good, since they are made for special industrial purposes.
    * You can create a custom 3D printed case. For this you first need to design the case on your PC (a common program is Fusion360, though I'm using FreeCAD). For the actual printing you can either use your own 3D printer, or you can again find a good 3D printing service, that you can give your design file (commonly in the `stl` format). They will print it for you for a bit of money. You will have to choose between different manufacturing methods, mainly FDM (putting lines of molten plastic onto each other layer after layer) or Resin printing (curing layers of fluid resin one after another). FDM is still cheaper. And you need to decide on the material (PLA is common, others are ABS or even metal (though the last is expensive). Also you need to design your case in a way, that it is good printable with the chosen method. You need to read more about 3D printing elsewhere (there are tons of material about it on the web).

One rule of this site is to not give product recommendations. That's not, what the site is for, and they are pretty fast outdated. Instead you need to do the research yourself.

---
Tags: project
---


title: Controlling an RC car using Arduino

text:
# Question
Title: Controlling an RC car using Arduino
I'm trying to replicate this: https://zhengludwig.wordpress.com/projects/self-driving-rc-car/ using pretty much the exact same controller and car.

I've soldered 4 wires to the controller, 1 for each direction. If I let the wires touch the ground on the controller everything works perfect. However, when I connect the wires to the Arduino nothing works. Sometimes left/right works for about 0.5 seconds then it goes back to doing nothing. Any idea on what the problem might be? Do I need to connect the controllers ground to the Arduino ground?

I've tried removing the batteries from the controller and connecting 3.3V and ground from the Arduino, which sorta works but I feel like it shouldn't be needed.

If I use the buttons on the controller while it's connected to the Arduino it goes either forward, right or forward+right.

The code I'm using to test everything looks like this:

```
void setup() {
  //Initialize the pins and serial
  pinMode(reversePin, OUTPUT);
  pinMode(forwardPin, OUTPUT);
  pinMode(leftPin, OUTPUT);
  pinMode(rightPin, OUTPUT);
}

void reset() {
  digitalWrite(forwardPin, HIGH);
  digitalWrite(reversePin, HIGH);
  digitalWrite(leftPin, HIGH);
  digitalWrite(rightPin, HIGH);
}

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

  digitalWrite(forwardPin, LOW);
  delay(4000);
  reset();
  digitalWrite(reversePin, LOW);
  delay(4000);
  reset();
  digitalWrite(leftPin, LOW);
  delay(4000);
  reset();
  digitalWrite(rightPin, LOW);
  delay(4000);
}

```

Images: https://i.stack.imgur.com/mCpcI.jpg

# Answer
Can you measure how much current goes through the wire when grounded (A: 2 mA from measurements in comments) ? And the open circuit voltage between the controller's ground and the control wire? (A: 3.1V, from 2xAA)

If the current isn't more than the 40mA per pin/100mA per port, 200mA total, and the open circuit voltage of the controller pins is less than 5V, then you should be able to connect the Arduino's output pins and ground to your controller's wires and ground.

If the voltages and currents are higher, then you would need protection to prevent damaging your Arduino.

The controller and the Arduino should share a common ground, but without a circuit and without the controller's voltages and currents, it is hard to tell exactly what is wrong.

Edit: Since the controller's open circuit voltage and short-circuit currents (3.1 V, 2mA max) fit within the Arduino's capabilities, you can wire them directly to the pin outputs, and make sure the controller and the arduino share a common ground.

You need a fifth wire between the controller ground to the Arduino ground to make the logic levels actually communicate between the two devices.

You likely also need some 5V-\>3V level shifting to isolate the Arduino's output levels from the controller's inputs. Top of the line would be MOSFETS, but you could possibly use a voltage dividing resistor pair. See the hints in https://arduino.stackexchange.com/a/419/6628
> 0 votes

# Answer
We have to add 1k resistors and 2k resistors as 330 ohms instead and follow the link below..!
> -1 votes

---
Tags: arduino-uno, digital
---


title: 595 Shift Register Not Working Properly

text:
# Question
Title: 595 Shift Register Not Working Properly
I followed the tutorial on controlling 8 LEDs using a SIPO SN74HC595N shift register on both Adafruit and Last Minute Engineer. I used a Sparkfun Pro Micro (Arduino Leonardo equivalent).

The problem is the LEDs are not lighting up in the way that I'm expecting it do it. Both guides said each LED will light up one after another. After all 8 are lit, all of them will turn off. Here is my result. Other LEDs will either dim up or down as the target LED turn on. I used the code provided from the guide and only changed the pinout number. The resistor values are the same for each color so it can't be the resistor. Anyone have any idea what's going on here?

```
/*
Test code for 74HC595N SIPO shift register. Used with Pro Micro
*/

int latchPin = 16;
int clockPin = 15;
int dataPin = 14;
int outputEnablePin = 10;

byte leds = 0;    // Variable to hold the pattern of which LEDs are currently turned on or off

void setup()
{
  // Set all the pins of 74HC595 as OUTPUT
  pinMode(latchPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(outputEnablePin, OUTPUT);
  outputEnablePin = LOW;
}

/*
 * loop() - this function runs over and over again
 */
void loop()
{
  leds = 0; // Initially turns all the LEDs off, by giving the variable 'leds' the value 0
  updateShiftRegister();
  delay(500);
  for (int i = 0; i < 8; i++) // Turn all the LEDs ON one by one.
  {
    bitSet(leds, i);    // Set the bit that controls that LED in the variable 'leds'
    updateShiftRegister();
    delay(500);
  }
}

/*
 * updateShiftRegister() - This function sets the latchPin to low, then calls the Arduino function 'shiftOut' to shift out contents of variable 'leds' in the shift register before putting the 'latchPin' high again.
 */
void updateShiftRegister()
{
   digitalWrite(latchPin, LOW);
   shiftOut(dataPin, clockPin, LSBFIRST, leds);
   digitalWrite(latchPin, HIGH);
}

```

**Schematics:**

# Answer
> 1 votes
The dimming problem was found to be the shift register IC not connected to Ground (dumb me).

However, there is still problem with LED's on and off pattern. Sometimes two LEDs turn on at the same time and all previous LEDS turning off before the last or second last LED is turned on. It turns out Pin 10 (SRCLR Bar) needs to be pulled to high to solve that pattern discrepancy.

---
Tags: led, shift-register
---


# Question
Title: Input 4-digit number using 4*4 keypad and show in serial monitor
```
#include <Keypad.h>

int myNum[4];

const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};
byte rowPins[ROWS] = {5, 4, 3, 2}; //connect to the row pinouts of the keypad 8,7,6,5
byte colPins[COLS] = {9, 8, 7, 6}; //connect to the column pinouts of the keypad 4,3,2,1
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS );

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

void loop() {
  Serial.println("Enter four-digit num -");  // request for input
  for (int i = 0; i < 4;){
    if(keypad.getKey()!= NO_KEY) {
      myNum[i] = keypad.getKey();
      i = i+1;
    }
  }
  Serial.print("Entered number is = ");
  Serial.print(myNum[0]);
  Serial.print(myNum[1]);
  Serial.print(myNum[2]);
  Serial.println(myNum[3]);
  delay(500);
}

```

I want that when I press a 4-digit number on the keypad it should be shown in the serial monitor. This code gives 0000 when I press any key on keypad.

# Answer
`keypad.getKey()` is non-blocking as you can read here: it will return a value immediately, even if no key is pressed. You have a `for` loop which will increment `i` each time, and you also increment it yourself. So what's happening is that your code is immediately making four readings, all of which are no-key-pressed so it doesn't store them, and then printing whatever happens to be in the `myNum` buffer.

Instead, you need to wait each time until a key is pressed, and only then move to the next digit. There are of course many ways you could do this. I hope this is clear:

```
#include <Keypad.h>

int myNum[4];

const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};
byte rowPins[ROWS] = {5, 4, 3, 2}; //connect to the row pinouts of the keypad 8,7,6,5
byte colPins[COLS] = {9, 8, 7, 6}; //connect to the column pinouts of the keypad 4,3,2,1
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS );

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

void loop() {
  Serial.println("Enter four-digit num -");  // request for input

  for (int i = 0; i < 4; ++i){
    while((myNum[i] = keypad.getKey())==NO_KEY) {
      delay(1); // Just wait for a key
    }
    // Wait for the key to be released
    while(keypad.getKey() != NO_KEY) {
      delay(1);
    }

  }

  Serial.print("Entered number is = ");
  Serial.print(myNum[0]);
  Serial.print(myNum[1]);
  Serial.print(myNum[2]);
  Serial.println(myNum[3]);
  delay(500);
}

```
> 1 votes

# Answer
```
#include <Keypad.h>

char myNum[4];

const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};
byte rowPins[ROWS] = {5, 4, 3, 2}; //connect to the row pinouts of the keypad 8,7,6,5
byte colPins[COLS] = {9, 8, 7, 6}; //connect to the column pinouts of the keypad 4,3,2,1
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS );

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

void loop() {
  Serial.println("Enter four-digit num -");  // request for input

  for (char i = 0; i < 4; ++i){
    while((myNum[i] = keypad.getKey())==NO_KEY) {
      delay(1); // Just wait for a key
    }
    // Wait for the key to be released
    while(keypad.getKey() != NO_KEY) {
      delay(1);
    }

  }

  Serial.print("Entered number is = ");
  Serial.print(myNum[0]);
  Serial.print(myNum[1]);
  Serial.print(myNum[2]);
  Serial.println(myNum[3]);
  delay(500);
}

```
> 0 votes

---
Tags: arduino-mega
---


title: the boxservo works contrary to the code

text:
# Question
Title: the boxservo works contrary to the code
i want to make a uselessbox .i connected the circuit correctly,i checked every thing several times and every thing is in right place\[ based on descriptions and pattern\],but when i turn it on,the box servo closes the door and then handservo starts to turn off the switch ,the code says:\[the boxservo opens the door then handservo starts to turn off the switch,when the switch is off and handservo returned to its place then boxservo closes the door\]but my box works like this(the boxservo closes the door then handservo starts to turn off the switch,when the switch is off and handservo returned to its place,then boxservo opens the door).what should i do to solve this problem?Useless box wiring and code

this is the code that i have uploaded:

```
#include <Servo.h>

Servo handServo;
Servo boxServo;

int switchStatus=0, action=1, vot, randNumber=0;
const int ledPin = 13;
const int frontSwitchPin = 2;
const int handServoPin = 5;
const int boxServoPin = 6;

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

  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin,HIGH);

  handServo.attach(handServoPin);
  boxServo.attach(boxServoPin);
  handServo.write(180);
  boxServo.write(70);

  //randomSeed(analogRead(0));
}

void loop()
{
  switchStatus = digitalRead(frontSwitchPin);
  //action = random(1,16);

  if (switchStatus == LOW){

    if (action == 1)
    {
      Serial.println("Action 1");
      for (int i = 70; i <= 110; i++)
      {
        boxServo.write(i);
        delay(20);
      }
      for (int i = 180; i >= 35; i--)
      {
        handServo.write(i);
        delay(20);
      }
      delay(1000);
      handServo.write(26);
      delay(200);
      for (int i = 26; i <=180; i++)
      {
        handServo.write(i);
        delay(20);
      }
      for (int i = 110; i >= 70; i--)
      {
        boxServo.write(i);
        delay(20);
      }
      action++;
    }

    else if (action == 2)
    {
      Serial.println("Action 2");
      for (int i = 70; i <= 110; i++){
        boxServo.write(i);
        delay(6);
      }
      delay(550);
      handServo.write(26);
      delay(550);
      handServo.write(180);
      delay(550);
      boxServo.write(70);
      delay(1500);
      for (int i = 70; i <= 110; i++){
        boxServo.write(i);
        delay(6);
      }
      delay(3000);
      boxServo.write(70);
      action++;
    }

    else if (action == 3)
    {
      Serial.println("Action 3");
      for (int i = 70; i <= 110; i++){
        boxServo.write(i);
        delay(6);
      }
      delay(1000);
      boxServo.write(70);
      delay(2000);
      for (int i = 70; i <= 110; i++){
        boxServo.write(i);
        delay(6);
      }
      handServo.write(26);
      delay(550);
      handServo.write(180);
      delay(500);
      boxServo.write(70);
      action++;
    }

    else if (action == 4)
    {
      Serial.println("Action 4");
      for (int i = 70; i <= 110; i++)
      {
        boxServo.write(i);
        delay(20);
      }
      for (int i = 180; i >= 35; i--)
      {
        handServo.write(i);
        delay(20);
      }
      delay(2000);
      handServo.write(26);
      delay(200);
      handServo.write(180);
      delay(400);
      boxServo.write(70);
      action++;
    }

    else if (action == 5)
    {
      Serial.println("Action 5");
      for (int i = 70; i <= 110; i++){
        boxServo.write(i);
        delay(6);
      }
      delay(2000);
      handServo.write(65);
      delay(550);
      handServo.write(40);
      delay(200);
      handServo.write(65);
      delay(200);
      handServo.write(40);
      delay(200);
      handServo.write(65);
      delay(200);
      handServo.write(40);
      delay(200);
      handServo.write(65);
      delay(200);
      handServo.write(40);
      delay(200);
      handServo.write(65);
      delay(200);
      handServo.write(40);
      delay(200);
      handServo.write(65);
      delay(2000);
      handServo.write(26);
      delay(400);
      handServo.write(180);
      delay(400);
      boxServo.write(70);
      action++;
    }

    else if (action == 6)
    {
      Serial.println("Action 6");
      for (int i = 70; i <110; i++)
      {
        boxServo.write(i);
        delay(20);
      }
      delay(1000);
      for (int i = 0; i < 12; i++)
      {
        for (int j = 70; j <= 110; j++){
          boxServo.write(j);
          delay(6);
        }
        delay(200);
      }
      for (int i = 180; i >= 35; i--)
      {
        handServo.write(i);
        delay(30);
      }
      handServo.write(26);
      delay(400);
      handServo.write(180);
      delay(400);
      boxServo.write(70);
      delay(1500);
      for (int i = 70; i <= 110; i++){
        boxServo.write(i);
        delay(6);
      }
      delay(3000);
      boxServo.write(80);
      action++;
    }

    else if (action == 7)
    {
      Serial.println("Action 7");
      for (int i = 70; i <= 110; i++){
        boxServo.write(i);
        delay(6);
      }
      delay(400);
      handServo.write(26);
      delay(1000);
      for (int i = 0; i < 6; i++)
      {
        for (int j = 70; j <= 110; j++){
          boxServo.write(j);
          delay(6);
        }
        delay(200);
      }
      delay(500);
      handServo.write(180);
      delay(400);
      boxServo.write(70);
      action++;
    }

    else if (action == 8)
    {
      Serial.println("Action 8");
      for (int i = 70; i <= 110; i++){
        boxServo.write(i);
        delay(6);
      }
      handServo.write(26);
      delay(2000);
      for (int i = 0; i < 7; i++)
      {
        handServo.write(75);
        delay(100);
        handServo.write(40);
        delay(100);
      }
      delay(500);
      handServo.write(180);
      delay(1000);
      boxServo.write(70);
      action++;
    }

    else if (action == 9)
    {
      Serial.println("Action 9");
      for (int i = 70; i <= 105; i++){
        boxServo.write(i);
        delay(6);
      }
      delay(2000);
      boxServo.write(110);
      for (int i = 180; i >=35; i--)
      {
        handServo.write(i);
        delay(40);
      }
      delay(500);
      handServo.write(26);
      delay(200);
      for (int i = 26; i <=180; i++)
      {
        handServo.write(i);
        delay(40);
      }
      boxServo.write(70);
      delay(2000);
      boxServo.write(100);
      delay(3000);
      boxServo.write(70);
      action++;
    }

    else if (action == 10)
    {
      Serial.println("Action 10");
      for (int i = 70; i <= 105; i++)
      {
        boxServo.write(i);
        delay(100);
      }
      delay(1000);
      for (int i = 0; i < 10; i++)
      {
        for (int j = 70; j <= 100; j++){
          boxServo.write(j);
          delay(6);
      }
        delay(100);
      }
      boxServo.write(110);
      delay(100);
      handServo.write(26);
      delay(650);
      handServo.write(180);
      delay(400);
      boxServo.write(70);
      action++;
    }

    else if (action == 11)
    {
      Serial.println("Action 11");
      for (int i = 70; i <= 110; i++){
        boxServo.write(i);
        delay(6);
      }
      handServo.write(26);
      delay(2000);
      for (int i = 0; i < 3; i++)
      {
        handServo.write(65);
        delay(200);
        handServo.write(40);
        delay(200);
      }
      delay(1500);
      handServo.write(180);
      delay(400);
      boxServo.write(70);
      delay(1500);
      for (int i = 70; i <= 110; i++){
        boxServo.write(i);
        delay(6);
      }
      handServo.write(26);
      delay(3000);
      handServo.write(180);
      delay(400);
      boxServo.write(70);
      action++;
    }

    else if (action == 12)
    {
      Serial.println("Action 12");
      for (int i = 70; i <= 110; i++)
      {
        boxServo.write(i);
        delay(50);
      }
      delay(1000);
      for (int i = 180; i >= 26; i--)
      {
        handServo.write(i);
        delay(50);
      }
      delay(2000);
      handServo.write(26);
      delay(200);
      handServo.write(180);
      delay(400);
      boxServo.write(70);
      action++;
    }

    else if (action == 13)
    {
      Serial.println("Action 13");
      for (int i = 70; i <= 110; i++){
        boxServo.write(i);
        delay(6);
      }
      delay(2000);
      for (int i = 180; i >= 60; i--)
      {
        handServo.write(i);
        delay(40);
      }
      for (int i = 0; i < 3; i++)
      {
        handServo.write(60);
        delay(200);
        handServo.write(40);
        delay(800);
      }
      handServo.write(26);
      delay(2000);
      handServo.write(180);
      delay(500);
      boxServo.write(70);
      action++;
    }

    else if (action == 14)
    {
      Serial.println("Action 14");
      for (int i = 70; i <= 105; i++){
        boxServo.write(i);
        delay(6);
      }
      delay(4000);
      boxServo.write(110);
      handServo.write(26);
      delay(650);
      handServo.write(180);
      delay(500);
      boxServo.write(100);
      delay(4000);
      boxServo.write(70);
      action++;
    }

    else if (action == 15)
    {
      Serial.println("Action 15");
      for (int i = 70; i <= 105; i++){
        boxServo.write(i);
        delay(6);
      }
      delay(1000);
      for (int i = 0; i < 3; i++)
      {
        for (int j = 70; j <= 105; j++){
          boxServo.write(j);
          delay(50);
        }
        for (int j = 105; j >= 70; j--)
        {
          boxServo.write(j);
          delay(50);
        }
      }
      for (int j = 70; j <= 110; j++){
        boxServo.write(j);
        delay(50);
      }
      for (int i = 180; i >= 35; i--)
      {
        handServo.write(i);
        delay(40);
      }
      delay(1000);
      handServo.write(26);
      delay(400);
      handServo.write(180);
      delay(400);
      boxServo.write(70);
      action = 1;
    }

  }

}

```

# Answer
> 1 votes
You have probably installed the box servo backwards so that when it tries to open it actually closes and vice versa.

---
Tags: arduino-uno, programming, servo, project
---


# Question
Title: Digital to Analog converter with DAC5311, Any suggestion?
I made my DAC code with DAC5311 and Arduino Uno. I think it has no problem, but it doesn't work well. Just print 0.(I use an oscilloscope.) I don't know where has the problem. Please give me any suggestion.

```
#include <SPI.h>
#include <math.h>
#define pin_CS 10
#define pin_MOSI 11
#define pin_SCLK 13
#define max_VOLT 5

void setVoltage(float voltage){
  if (voltage < 0) voltage = 0;
  if (voltage > max_VOLT) voltage = max_VOLT;
  uint16_t temp = int(voltage * pow(2, 8) / max_VOLT);
  temp = temp << 6;
  uint8_t upper = temp >> 8;
  uint8_t lower = (temp & 0xff);
  digitalWrite(pin_CS, LOW);
  SPI.transfer(upper);
  SPI.transfer(lower);
  digitalWrite(pin_CS, HIGH);
}

void setup() {
  Serial.begin(9600);
  pinMode(pin_CS, OUTPUT);
  pinMode(pin_MOSI, OUTPUT);
  pinMode(pin_SCLK, OUTPUT);
  SPI.begin();
  SPI.setBitOrder(MSBFIRST);
  SPI.setDataMode(SPI_MODE0);
  digitalWrite(pin_CS, HIGH);
}

void loop() {
  setVoltage(5);
  delay(10);
}

```

# Answer
Classical +/- 1 problem

If you do this calculation by hand `uint16_t temp = int(voltage * pow(2, 8) / max_VOLT);`
you will get `temp=256` and this is a value you can not convert with a 8 bit DAC.

Try `uint16_t temp = int(voltage * (pow(2, 8)-1) / max_VOLT);` instead.

(or event better for a µC `uint16_t temp = (uint16_t) (voltage * (255 / max_VOLT));`)
> 3 votes

---
Tags: digital-analog-conversion
---


# Question
Title: How to use attachInterrupt() in ATtiny85 with Arduino IDE?
It's possible use external interrupts/attachInterrupt() with the ATtiny85 when I program with Arduino IDE?

If is possible, how many inputs (for external interrupts) the ATtiny85 have and which are they? Someone have an example code?

# Answer
Pin PB2 is the only pin that has a real external interrupt. This is `INT0`.

Whether you can use `attachInterrupt(0, ...)` or not is entirely down to whether it is implemented in the core that you are using.
> 2 votes

---
Tags: interrupt, pins, attiny85
---


# Question
Title: Http request in interrupt esp8266 not working
So i have this code that whenever i click a button a interrupt starts. In this interrupt i want to do a get request to a webserver.

The thing is seperate the code, the interrupt code works and without an interrupt the http request also works. But when i put this together it doesn't.

Does anybody have an idea why this doesn't work?

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

char ssid[] = "";
char pass[] = "";

int ledpin = 5; // D1(gpio5)
int button = 4; //D2(gpio4)
int buttonState=0;

ICACHE_RAM_ATTR void ISR() {
  static unsigned long last_interrupt_time = 0;
  unsigned long interrupt_time = millis();

  if (interrupt_time - last_interrupt_time > 200)
  {
      Serial.println("Drukknop ingedruk");
      Serial.println("Sending message to server");
       if (WiFi.status()==WL_CONNECTED)
      {
        HTTPClient http;
        String url="<httpurl>";
        http.begin(url);
        http.addHeader("Content-Type","text/plain");
        int httpCode=http.GET();
        Serial.println(httpCode);
        String payload=http.getString();
        Serial.println("While sending I received this from server : "+payload);
        http.end();
      }
      else
      {
        Serial.println("Internet Problem!");
      }
  }
  last_interrupt_time = interrupt_time;
}

void setup() {
  Serial.begin(115200);
  WiFi.begin(ssid,pass);

  while(WiFi.status() !=WL_CONNECTED)
  {
    delay(500);
    Serial.println("Waiting for connection");
  }

  Serial.println("Connected...");
  delay(1000);
  if (WiFi.status() ==WL_CONNECTED)
  {
    Serial.println("Wi-Fi Connected!");
  }
  delay(5000);
  Serial.println("ok");
  pinMode(button, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(button), ISR, RISING);

}
void loop() {

}

```

# Answer
> 1 votes
Doing something as complex as a HTTP request in an interrupt is a very very silly idea. Instead set a flag in the interrupt routine and examine that in the main `loop()` function to perform your HTTP request.

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


title: Check if the board is in sleep mode

text:
# Question
Title: Check if the board is in sleep mode
I'm using seep sleep mode with UNO with a simple sketch that turning on an LED and then goes to sleep. as far as the ATmega328p datasheet in sleep mode part showing the wake up sources and deactivated clock sources in deep sleep mode and the I/O clock becomes deactivate so we expect when the board goes to sleep the LED should become off because of no clock. but it doesn't happen and LED keeps ON in sleep mode. what is the problem?7 and how can we even find out that the board is on sleep mode or not?

# Answer
The IO doesn't require the clock to keep its current state. It only requires it to change state.

There is no real external signal provided by the chip to indicate if its in sleep mode or not. However you could monitor the current consumption of the chip and when it drops below a certain threshold you can assume that it is in sleep mode.
> 2 votes

# Answer
You could easily set the LED output LOW just before you call going\_to\_sleep(), and set it HIGH when going\_to\_sleep() returns. There would be two short periods where the LED signal would indicate sleeping but the processor is running:

1. between the LED going LOW and the processor actually entering sleep; and
2. between the processor waking and the LED going HIGH.

But at these times the processor could not respond to your external system anyway.
> 0 votes

---
Tags: arduino-uno, arduino-ide, sketch, electronics
---


# Question
Title: Arduino Nano use SPI pins as I/O pins? and still be able to do ISP?
I wonder if can use the Arduino Nano SPI-pins(MOSI,MISO & SCK) as I/O pins in a sketch? and still be able to program over ISP?

Of course I will physical disconnect the Arduino from any other hardware before programming.

# Answer
Yes, you can use SPI in your sketch just as you like. The programming over ISP is triggered by resetting the microcontroller. That means, that when trying to program over ISP your sketch (which configures the SPI hardware for use) doesn't run. The programming is starting at a stage, before the sketch runs, thus the sketch cannot interfere.

By the way: The same is correct for programming over Serial, though for a different reason. Programming over Serial is done by the bootloader, which runs before your sketch.
> 1 votes

---
Tags: arduino-nano, pins, isp
---


title: Calculating SpO2 using pulse sensor

text:
# Question
Title: Calculating SpO2 using pulse sensor
I was wondering is there a way to calculate SpO2 using a pulse sensor? I calculated BPM and stress before with pulse sensor and now I want to calculate SpO2.

Link to Pulse sensor manual

# Answer
For measuring oxygen saturation (SpO2) with a pulse sensor, you need to use the fact, that hemoglobin, that carries oxygen, will reflect in different light wave lengths, as hemoglobin, which doesn't carry oxygen. But that also means, that you need to use light in at least 2 different wavelengths. Common are one red (about 660nm)(though green may also work) and infrared (about 940nm). When lighted sequentially with both LEDs, you can measure the refection of both parts and calculate the ratio between them (SpO2).

But your sensor only has 1 LED, which is green. So you cannot measure SpO2 with this sensor. You need one fitting the above description.
> 2 votes

---
Tags: arduino-uno
---


# Question
Title: DC Motor doesn't turn and a beep sound is made, also there is a burning smell
I was trying to drive a single dc motor with L293D Shield and Arduino Uno

```
#include <AFMotor.h>
#include <SoftwareSerial.h>

AF_DCMotor motorLeft(3);
AF_DCMotor motorRight(2);

unsigned char opMode = 0;

void setup()
{

}

void loop()
{
motorLeft.setSpeed(30);
motorLeft.run(FORWARD);
delay(5000);
motorLeft.setSpeed(0);
motorLeft.run(RELEASE);
delay(5000);
}

```

When I turned the power on, a beep sound was made continously. As I was trying to figure out where the sound comes from, I smelled something burning and turned the power off.

I am giving 6V (Four 1.5V batteries in series) as external power. Burning smell doesn't come from batteries, that's for sure.

The smell comes from arduino or shield or both. But I think it is the the left LM293D driver.

What did I do wrong? Any idea?

# Answer
Alright, I finally realized that RPM value was too low. It has to be at least 150 for my case.
> 0 votes

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


# Question
Title: char to String conversion in Arduino program
I have started learning about Arduino and am well versed in Java and Python. In an Arduino program, I need a character input via Serial to be stored in a String variable. From my previous programming experience, I knew that a code like the one below would give an error as char can't be converted into String like this.

```
void loop() {
  if(Serial.available()) {
     String s=(char)Serial.read();
  }
}

```

As expected, the above code gives an error on compiling. But when I first defined `s` and then assigned its value in a separate step in `void loop()`, I got no error.

```
void loop() {
  if(Serial.available()) {
     String s;
     s=(char)Serial.read();
  }
}

```

The above code yields no error despite the fact that it is almost similar to the first code. What I suspect is that it has something to do with String being a class. Can one tell what is going on?

# Answer
> 1 votes
this isn't an arduino specific error what you're trying to do is declare and initialize the variable in one statement which is causing the problem. As you've figured it out already. Declaring the variable first

```
String s;

```

and initializing it another statement does the job for you

```
s=blabla

```

Hope this helps. PS, try posting the error that you get during build process next time :)

**EDIT**: I think this needs more explanation. Basically why you cant declare and initialize at the same time in this case is because Serial.read is a synchronous request. Declaring an object requires acquiring the space for it, running any constructors and whatsoever, and doing while Serial.read() is an IO blocking operation. You could declare and initialize a String class variable given it was a string constant but not with anything like get\_input or Serial.read

**EDIT 2**: Further here's what I've found for you.

http://www.cplusplus.com/reference/string/string/string/

Apparently the String class has a copy constructor which means when declaring the variable you initialize at the same time it uses the copy constructor, and which requires ADDRESS to a valid string(know that you can use a constant because C++ deals with all strings as the address to their first char). In your case the constructor raised an error because you pointed it to an undefined(Serial.read() ).

```
String mystring=Serial.read(); //error, uses copy constructor

```

However this would work

```
String mystring="hey juliet!" ; //uses the copy contructor which takes address to a char

```

Doing the same thing in two different lines works for the same reasons, it uses a different constructor

```
String mystring; //uses empty string constructor - okay so far
mystring=Serial.read(); // uses the overloaded = operator  --okay

```

# Answer
> 1 votes
You misunderstand `Serial.read()`: it does not return a `String` or sth. like a char array, but an integer, representing only the last byte in the input buffer that hasn't been read.

What you probably want to do is to interpret those incoming bytes as `char`s and accumulate those in a `String`.

E.g. like this:

```
String s="";
while(Serial.available()) {
  // as long as there are bytes in the buffer
  s+=(char)Serial.read(); // interpret int as char and append character to s
}

```

As using `String` can easily lead to crashes you should avoid dynamic memory allocation by using a fixed-size char arrays:

```
#define MAX_LEN 64
char s[MAX_LEN];
uint8_t i;
while (serial.available() && i<MAX_LEN) {
  s[i]=(char) Serial.read();
  i++;
}

```

Note: once you are that far you still have to handle, when you want the data to be ready to process (e.g. detecting a `\n` and setting a flag appropriately).

# Answer
> 0 votes
I don't have much experience with Arduino's `String` type, however, most people (including myself) don't advise to use it. Because the Arduino only has 1 KB of SRAM and the `String` type has its own hidden memory allocation, you might run out of memory without you know it, resulting in crashing/frozen programs without a clue what is happening.

Instead use character arrays (like `char str[10]`) where you know exactly what is reserved.

However, to answer your question, what I expect since `String` is a class, there is a (copy) constructor in that class that takes a `char` and converts it into a `String`.

# Answer
> 0 votes
This will fix the problem: `void loop() {
 if(Serial.available()) {
 String s=(char*)Serial.read();
 }
}` This is because in C: Strings are defined as an array of characters. You cannot assign a primitive to an array...

I guess the casting into pointer can be implicit as in your second example..

---
Tags: programming
---


# Question
Title: How to connect naked camera from mobile phone to Arduino Uno
Okay, guys. I have this 3 cameras(middle from the iPhone 6s, 2 at the side I found, and I think there are from modern phone). **I need some information how to connect Arduino Uno to them.** I know c/c++, assembler, but noob in microcontrollers, if this knowledge can come useful.

# Answer
> 3 votes
You need either a memory extension for your UNO - projects like Arducam did this way back 2016 and then used an OV2640 module. If you want to develop something yourself these are the steps (hurdles) to take:

* Get a datasheet of the camera
* Design a circuit including
    + plug for Camera and a
    + memory module (min 512Kb)
* Attach it to the UNO
* Write a library/function module (see datasheet for details) and
* bring it to life

My tip save ca. two years of your life and get for 6-8$ an ESP32cam
This will cost you enough of your time, but be much more rewarding

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


title: Issue with incrementing PWM over time

text:
# Question
Title: Issue with incrementing PWM over time
First post here. So I have an issue, which I have identified, but I'm not quite sure how to fix it. I'd really appreciate some input and suggestions. I realize that my "*pwmDelta*" is the problem, but I am not sure what to do to fix it.

I am trying to write a program that will increment the value of the pin 3 a set amount of time, in a somewhat linear fashion, *starting* at my low point, and *finishing* at my high point.

The issue is that my equation is incorrect and I can't output a partial bit value. Huge oversight on my part. If you read the data from the serial monitor with the code written as I have it, you'll see that it isn't coming even close to reaching my max value.

I need suggestions on how I can have the program figure out the delta in a way that I can send an integer value to the PWM output pin, yet still keep a somewhat linear increase over time. Would this even be possible?

```
int motor1 = 3;         //pin for PWM output to motor
float t = 0;            //Variable to keep Track of time
int tLim = 30;          //Time Limit for Ramp
float lowLim = 21;      //Low Limit, in Duty Cycle %
float highLim = 65;     //High Limit, in Duty Cycle %
float motorPWM = 53.55; //Starting Value of PWM, in Bits
float pwmDelta = ((255/100)*(highLim-lowLim))/(tLim); //Delta equation, to calculate how much to change PWM value each time it is incremented
float motorDelta;       //Variable to write value to Motor Output

void setup() {
  pinMode(motor1, OUTPUT);
  analogWrite(motor1, 53.55); //run motor at initial value for 20 seconds before beginnning ramp
  delay(20000);
  Serial.begin(9600);
}

void loop() {
  motorDelta = motorPWM + pwmDelta; //incrementing output value based on Delta Equation
  motorPWM = motorDelta; //Setting new incremented value equal to old value, so incrementing can continue

  if (t <= tLim) {  //Check if time is <= time limit
    analogWrite(motor1, (motorDelta)); //write incremented value to output pin
    delay(1000);  //wait 1 second, increment t, to keep track of time
    t++;
  }
  else {
    analogWrite(motor1, motorPWM = 165.75); //set pin to high value for 60 seconds, then set to 0
    delay(60000);
    analogWrite(motor1, motorPWM = 0);
  }
  Serial.print(motorDelta);
  Serial.println();
  Serial.print(t);
  Serial.println();
}

```

# Answer
```
float pwmDelta=((255/100)*(highLim-lowLim))/(tLim);

```

That line should be:

```
float pwmDelta=((255.0/100)*(highLim-lowLim))/(tLim);

```

Adding the .0 tells the compiler to do that math using floats and you get 2.55. Without it the math is done with int and the result is 1 which isn't what you want.

```
analogWrite(motor1, 53.55);

```

Just write 54. analogWrite only accepts integer values.

```
analogWrite(motor1, motorPWM=165.75);

```

You should really do that as two lines, an assgnment and then an analogWrite. This way leads to confusing code. Also, analogWrite only accepts integer values so your decimals are useless there as well.
> 2 votes

# Answer
You are trying to smoothly ramp up the PWM value from 21% to 65% over a period of 30 seconds at 1 second intervals, which does not work very well because the PWM value has to be a byte.

That means that the value written into the PWM register changes from 21\*255/100 to 65\*255/100, which is 53.55 to 165.75.

Use values of 53 and 166, which gives a difference of 113.

Your code is written to update the PWM value every 1000 ms, which produces 30 steps, most of which are not integers.

Instead, ramp up the PWM value in 113 steps. Each step will be an integer and each step will be 265486 μs in length.
> 0 votes

# Answer
The previous responses already showed the main issue with the program. Here I am providing a few suggestions that hopefully could still improve it:

* Instead of using `delay()`, you could manage the time with `millis()`. This will make the ramp smoother, and you will be able to add code to the loop if needed that will not be blocked by the delays.
* Storing the times in milliseconds and the PWM value in its natural unit (rather than percent) makes the code simpler.
* Remove redundant variables, such as `motorDelta`, which is the same as `motorPWM`.
* Consistent indentation and removal of superfluous parentheses help the readability.

Here is my attempt at implementing those suggestions:

```
const int motor1 = 3;  // pin for PWM output to motor
const unsigned long tLim = 30000;  // duration of the PWM ramp
const float PWM_unit = 255.0/100;  // convert percent to PWM scale
const float lowLim = PWM_unit * 21;
const float highLim = PWM_unit * 65;
const float PWM_rate = (highLim-lowLim) / tLim;

unsigned long start_time;  // start of the ramp
int previousPWM = 0;

void setup() {
    pinMode(motor1, OUTPUT);
    analogWrite(motor1, round(lowLim));
    delay(20000);
    Serial.begin(9600);
    Serial.println(" t   PWM");
    Serial.println("--------");
    start_time = millis();
}

void loop() {
    unsigned long t = millis() - start_time;

    if (t >= tLim) {  // we are done
        analogWrite(motor1, round(highLim));
        delay(60000);  // keep at highLim for 60 s
        analogWrite(motor1, 0);  // then stop
        exit(0);
    }

    int motorPWM = round(lowLim + t * PWM_rate);
    if (motorPWM != previousPWM) {
        analogWrite(motor1, motorPWM);
        Serial.print(t / 1000.0);
        Serial.print("  ");
        Serial.println(motorPWM);
        previousPWM = motorPWM;
    }
}

```
> 0 votes

# Answer
What's happening is that you've written a fraction in a way that the compiler treats it as integer math. C/C++ truncate fractions, so 255/100 is just 2 (and if any of the rest of those are integers, they cause truncation too). What you want to do is make some number in that calculation a decimal--it doesn't matter which one--or cast an input to a float with `(float) somevariable`.

As long as that's all on one line, all of the calculations involved (*excepting order of operations, so cast to float one of the variables being divided* if you have them in separate parenthesized terms) will be in floating point. Do note that if you set the value of an integer with this, it will only truncate **after** doing the math accurately, too, so it's more correct.

`float pwmDelta = ((255/100)*(highLim-lowLim))/(tLim);`

Should be:

`float pwmDelta = 2.55*(highLim-lowLim)/(float)tLim;` (This also makes it all one term.)
> 0 votes

---
Tags: arduino-uno, pwm, adc, digital-analog-conversion, calculation
---