title: Controling L298n with interrupts

text:
# Question
Title: Controling L298n with interrupts
I'm working on my first arduino project, Sumo Robot, therefore i dont know much about programming yet. We are supposed to use two IR sensors one on the front of the robot other on its back to avoid crossing the black line of the arena. I wrote this simple code to control the motors. But i have been asked to use interrupts to raise the efficiency of my code.

So do you guys have an idea of how i can use interrupts with the L298n motor driver to move my dc motors forward and backward.

Here is my code

```
int fIR=7;
int bIR=8;
int fIR_value;
int bIR_value;
const int trigPin = 9;
const int echoPin = 11;

long duration;
int distance;

int IN1 = 4;
int IN2 = 5;
int IN3 = 6;
int IN4 = 12;

void setup() {
  Serial.begin(9600);
  pinMode(fIR,INPUT);
  pinMode(fIR,INPUT);
  pinMode(trigPin,OUTPUT);
  pinMode(echoPin,INPUT);
  pinMode(IN1,OUTPUT);
  pinMode(IN2,OUTPUT);
  pinMode(IN3,OUTPUT);
  pinMode(IN4,OUTPUT);

}

void loop() {

  fIR_value = digitalRead(fIR);
  Serial.print("Front IR:");
  Serial.print(fIR_value);
  Serial.print(" , ");

  bIR_value = digitalRead(bIR);
  Serial.print("Back IR:");
  Serial.print(bIR_value);
  Serial.print(" , ");

  digitalWrite(trigPin, LOW);
  delayMicroseconds(10);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);
  distance = duration*0.034/2;
  Serial.print("Distance: ");
  Serial.println(distance);
  delay (500);

  if(distance<30&&fIR_value==HIGH&&bIR_value==LOW){
    STOP();
    delay(50);
    BACKWARD();
//    Serial.print("1");
  }
  else if(distance<30&&fIR_value==LOW&&bIR_value==HIGH){
    STOP();
    delay(50);
    FORWARD();
//    Serial.print("2");

  }
  else if(distance<30&&fIR_value==LOW&&bIR_value==LOW){
    STOP();
    delay(50);
    FORWARD();
//    Serial.print("3");

  }
    else if(distance>30&&fIR_value==LOW&&bIR_value==LOW){
    STOP();
    delay(50);
    ROTATE();
//    Serial.print("4");

  }
   else if(distance>30&&fIR_value==HIGH&&bIR_value==LOW){
    STOP();
    delay(50);
    BACKWARD();
//    Serial.print("5");

  }
   else if(distance>30&&fIR_value==LOW&&bIR_value==HIGH){
    STOP();
    delay(50);
    FORWARD();
//    Serial.print("6");

  }
}

void FORWARD(){

  digitalWrite(IN1,200);
  digitalWrite(IN2,0);
  digitalWrite(IN3,0);
  digitalWrite(IN4,200);
}
void BACKWARD(){

  digitalWrite(IN1,0);
  digitalWrite(IN2,200);
  digitalWrite(IN3,200);
  digitalWrite(IN4,0);
}
void ROTATE(){

  digitalWrite(IN1,200);
  digitalWrite(IN2,0);
  digitalWrite(IN3,200);
  digitalWrite(IN4,0);
}
void STOP(){

  digitalWrite(IN1,0);
  digitalWrite(IN2,0);
  digitalWrite(IN3,0);
  digitalWrite(IN4,0);
}

```

# Answer
As jsotola already suggested in the comments, using interrupts for driving the motors does not make sense. With a L298N you simply set the outputs and then leave them alone until you think they should stop.

Instead you could use interrupts for your sensors.

Though I would argue, that using interrupts would not be really necessary, when you implement your code the right way, means non-blocking. You use a lot of `delay()` calls. where the Arduino does not do anything, just twiddling thumbs. Instead you could use the principle from the `BlinkWithoutDelay` example, that comes with the Arduino IDE, to write the code non-blocking. In that case every bit of code would only do something, if it needs to, and otherwise return fast. That would make your code run way faster. You would also need to set a lower timeout for the `pulseIn()` function, as it's standard timeout is 1s (ultrasonic sensors like you are using one normally can only sense up to 3m, would would correspond to 20ms max pulse duration, if I'm doing the math correctly).

If using interrupts is a mandatory part of your excercise, you can decide, where to use interrupts:

* The simplest way would be for the **IR sensors**. You could use the `attachInterrupt()` function to set up an Interrupt Service Routine (ISR) for the corresponding pin. If you want the interrupt to trigger, when the IR sensors go HIGH, you can use `RISING`, otherwise you can use `FALLING`. Keep in mind, that ISRs should be as small and fast as possible. You cannot use `delay()` there. Normally one would only set simple (1 byte) variables in the ISR, and then react with longer actions in the main code by checking these variables. You have you set every variable, that can be changed in an ISR, as volatile:

```
volatile byte flag;

```
* For the ultrasonic sensor, you have more than one way to go. I will outline 2 ways. For both of them you need to either directly manipulate the Special Function Registers of the microcontroller, or find a library, that does that for you (don't know, if such libraries exist, but you can search for them):

1. You could use the Pin Change Interrupt. It triggers everytime, when a pin from a full pin port (group of up to 8 pins) changes it's state. You can mask away unused pins, so that they will not influence the interrupt. In the ISR you can check the state of the pin. If it is high, the start of the pulse just happened. Save a timestamp of that moment with the `micros()` function. The next ISR (where the pin will be LOW) will mark the end of the pulse. Now you can calculate the time difference between the timestamp and the current `micros()` value. You should use a 1-byte variable as flag, to trigger the processing the the pulse duration in the main function (or, if you want to directly use the time difference variable, you need to turn of the interrupt, while you are using the variable).
    2. If you want to show off, you could use a hardware Timer in Input Capture mode (this is the more complex, then the other possibilities). The timer is a counter, that is connected to the system clock (through a prescaler, where you can change the count frequency in a coarse way). The timer starts and when the Input Capture pin ICP1 (in case of Timer1) changes it's state, the current value of the timer will be saved in an extra register and an interrupt is fired. This timer value is like a timestamp. If you record the timestamps for the rising and the falling edge of the pulse, you can take the difference and calculate the time difference/distance from this. This part works similar to the first way above. The notes about interrupts also apply here.
> 1 votes

---
Tags: arduino-uno
---


# Question
Title: My Arduino code is showing unidentified reference for 3 of my variables, I don't know how to fix it
Here's the code up to the error.

```
const int R = 12;
const int G = 10;
const int Y = 8;

const int PBR = 13;
const int PBG = 11;
const int PBY = 9;
const int pinNum = 3;
const int speaker = 2;

int LED = 0;
int gameStage = 0;

const int winNum = 2;
int gamePoint[winNum];
int rounding = 0;

unsigned long lastTime = 0;
unsigned long pause = 1000;

void ledState(int ledNum);
void clue(int rounding);
void begin_game();
void play();
void winning_sound();
void win();
void lose();
void lose_sound();
boolean inputWait(int buttonNum);

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

pinMode(R, OUTPUT);
pinMode(G, OUTPUT);
pinMode(Y, OUTPUT);
pinMode(PB1, INPUT);
pinMode(PB2, INPUT);
pinMode(PB3, INPUT);
pinMode(speaker, OUTPUT);

randomSeed(analogRead(0));
}

void loop() {

if (gameStage == 0)
{
int PBvalue1 = digitalRead(PB1);
int PBvalue2 = digitalRead(PB2);
int PBvalue3 = digitalRead(PB3);
  if (PBvalue1 && PBvalue2 && PBvalue3 == 0)
  {
    begin_game();
  }
  else
  {
    Serial.println("button Pressed");
    ledState(-1);
    rounding = 0;
    delay(1500);
    gameStage = 1;
  }
}
if (gameStage == 1)
{
  **play();** Error
}

if (gameStage == 2)
{
  delay(750);
  winning_sound();
  **win();
  win();
  win();
  win();** Error
  delay(1500);
  gameStage = 0;
}

if (gameStage = 3)
{
delay(750);
lose_sound();
**lose();
lose();
lose();** Error
delay(1500);
gameStage = 0;
}

}

```

# Answer
Lines 5,6,7 you use PBR, PBG and PBY,

Lines 39,40 and 41 you use PB1, PB2 and PB3 Again in your void loop() you reference PB1, PB2 and PB3
> 1 votes

# Answer
When I tried to compile it, I got (after editing `**Error**`):

```
 In function `loop':

/sketch_jan15b.ino:55: undefined reference to `begin_game()'

/sketch_jan15b.ino:60: undefined reference to `ledState(int)'

/sketch_jan15b.ino:68: undefined reference to `play()'

/sketch_jan15b.ino:74: undefined reference to `winning_sound()'

/sketch_jan15b.ino:75: undefined reference to `win()'

/sketch_jan15b.ino:76: undefined reference to `win()'

/sketch_jan15b.ino:77: undefined reference to `win()'

```

These are not variables, but functions which have been declared but not defined.

Changing these:

```
void ledState(int ledNum);
void clue(int rounding);
void begin_game();
void play();
void winning_sound();
void win();
void lose();
void lose_sound();
boolean inputWait(int buttonNum);

```

to read:

```
void ledState(int ledNum){}
void clue(int rounding){}
void begin_game(){}
void play(){}
void winning_sound(){}
void win(){}
void lose(){}
void lose_sound(){}
boolean inputWait(int buttonNum){}

```

Allowed the code to compile successfully.
> 0 votes

---
Tags: arduino-uno
---


# Question
Title: FlexyStepper: set current position leads to reach the old target
I'm using the FlexyStepper library.Unfortunately there's no way to write an issue to the author so I'm going to ask my question here.

The documentation says about the `setCurrentPosition*()` functions:

> set current position of the motor in millimeter, this does not move the motor

But I see a different behavior. Looking at the code, it seems it just update the *current* position, leaving unchanged the *target* position. This leads to an expected movement of the motor. Example:

1. set the target position to, say: 1000
2. the motor reach that position
3. set the current position to, say: 1500
4. now the motor come back to 1000

Instead, I want the *current* position from now is 1500, but because it has already reached the target, it shouldn't move further.

Of course a workaround is to set both current position and target to the same value.

I wonder if I'm wrong about the documentation or this might be considered a bug.

# Answer
> 1 votes
The point of `setCurrentPosition()` is to calibrate the stepper. It would normally be used in association with a limit switch of some form.

If you set the motor to go to 1000 and then tell it that the motor is actually at 1500 then of course it will then try and go back to 1000 - you have told it that is where you want it, but you also told it that's not where it is.

The normal usage would be:

1. Step the motor constantly in one direction until it hits a limit switch or similar
2. Set the current position to whatever that actual position is
3. Start going to actual positions that are relative to that reference point.

For example

* Move the motor anti-clockwise
* Motor triggers limit switch
* Stop moving the motor
* Set the current position to 0
* Start using the motor normally

---
Tags: stepper, stepper-motor
---


# Question
Title: Can the ESP-1 use SPI to communicate with sensors?
I wonder if I can use SPI to communicate between ESP-1 ESP8266 module and SPI sensors and other slaves.

If so, do I need to install a library?

# Answer
ESP-01 was designed as WiFi network adapter, not as a controller board. The are 4 pins on esp-01. RX (io 3), TX (io 1), io 0 and io 2.

SPI requires 3 pins: clock, MISO, MOSI plus one pin for every device connected to the bus. So you could in theory use one SPI device on this 4 pins. The esp8266 Arduino SPI library works only with hardware SPI on esp8266 pins io 12, 13, 14 so you would have to use some software SPI implementation for esp8266.

To connect sensors, actuators or display to the esp-01, I2C is a feasible option. It requires only two digital pins and the esp8266 Arduino Wire library can work on any pair of io pins.

To use esp8266 as MCU with Arduino, there are many development boards with all usable pins broken out (9 pins) and USB chip for simple connection to computer and flashing (Wemos, NodeMCU). Or you can use an esp8266 module with more or all pins of the esp8266 (esp-07, esp-12).
> 1 votes

---
Tags: esp8266, spi
---


title: ESP32 documentaiont for "time.h"

text:
# Question
Title: ESP32 documentaiont for "time.h"
I am working from the example sketch in that installed with the ESP32 Dev Module into the Arduino IDE. It includes `<WiFi.h>` and `"time.h"`. I have a number of questions about how to use the clock that is set up with `configTime` using NTP. I am trying to find the documentation, but I'm having difficulty identifying exactly who is providing me the `"time.h"` header file, and of course, there are a lot of different `time.h` header files out there so googling is difficult.

Where can I find the documentation for this particular header?

---

Example questions:

* Can the time be set manually without a WiFi connection?
* Can the timezone be changed without connecting to NTP again?
* Can I get the time as a Unix Time Stamp? (Yes)
* Can I arrange for a function callback at a certain time? (I'm aware I can use the timer library for this but I'm hoping for something like a callback at 4:20p every Saturday)

# Answer
`time.h` is provided by the compiler (more specifically the C library in use in the compiler).

I believe the xtensa-esp32 compiler uses *newlib* as the C library. If that is the case, the documentation is here: https://sourceware.org/newlib/libc.html#Timefns
> 2 votes

---
Tags: esp32, time, documentation
---


title: Arduino Temperature Sensor

text:
# Question
Title: Arduino Temperature Sensor
We are doing a project and we need to build a thermo sensor and read the voltage and the temperature but we also have to have the temperature correspond to LEDs that will give a blue for cold green for mild and red for hot we are using a DS18b20 thermo sensor.

How should we write the code or where could we find code that would work for this purpose?

We both have a very surface level understanding of code at the moment, however our time constraints have made learning it difficult.

# Answer
This forum isn't great for detailed solutions to vague problems. If you don't have much experience with programming, you'll have a lot to figure out. It will take you a while (realistically probably a couple of weeks if you work at it every day, and have a knack for it, assuming you're starting from scratch.)

The first step is to define your problem. It sounds like you want to build a project that uses colored LEDs to indicate the measured temperature in different ranges.

So lets say you want:

```
Temp <10°C light Blue LED
Temp 10°C - 30°C light green LED
temp >30°C light red LED.

```

Break the problem into bite-sized pieces and solve them one at a time.

Pick an Arduino model. Install the IDE. Run a sketch that will blink the built-in LED. Then do a google search on "Arduino Blink without delay" and rewrite your blink code to not use the `delay()` function. Forget the `delay()` function exists and never use it again, since it will usually get in the way of what you need to do.

Then figure out how to wire separate LEDs (including current limiting resistors) to 3 separate pins. Make your code blink all 3 LEDs at the same time by toggling the appropriate pins' output states.

Modify your app to blink first one LED, the 2nd, and then the third. Now get tricky and modify your app to blink the first LED on and off once a second, the next LED once every 1/3 of a second, and the fourth LED to blink once every 1/4 second, all at the same time. (That will force you to really understand how to do timing without delay.)

Now look up a sample project that uses your temp sensor. (Try **this one I found**, for example) Run that and get it to send the temp to your serial port once every few seconds. (again not using `delay()`.)

Now write a loop that reads the temp sensor, decides which range the temp is in, and lights the appropriate LED based on those ranges. Note that you may only be able to read the temp every 2 seconds or so (the DHT22 and DHT11 temp sensors I've used have that limitation.)
> 1 votes

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


# Question
Title: Adafruit Circuit Playground Express fails to upload
When uploading code to the Adafruit Circuit Playground Express, I have found that most of the time it fails to upload saying that the port is busy. There seems to be no logical reason behind this, as it uploads perfectly to an Arduino Uno (Yes, I did switch the board types). What am I doing wrong? Here is the error:

```
processing.app.debug.RunnerException
    at cc.arduino.packages.uploaders.SerialUploader.uploadUsingPreferences(SerialUploader.java:152)
    at cc.arduino.UploaderUtils.upload(UploaderUtils.java:77)
    at processing.app.SketchController.upload(SketchController.java:732)
    at processing.app.SketchController.exportApplet(SketchController.java:703)
    at processing.app.Editor$UploadHandler.run(Editor.java:2075)
    at java.lang.Thread.run(Thread.java:748)
Caused by: processing.app.SerialException: Error touching serial port '/dev/ttyACM1'.
    at processing.app.Serial.touchForCDCReset(Serial.java:107)
    at cc.arduino.packages.uploaders.SerialUploader.uploadUsingPreferences(SerialUploader.java:136)
    ... 5 more
Caused by: jssc.SerialPortException: Port name - /dev/ttyACM1; Method name - openPort(); Exception type - Port busy.
    at jssc.SerialPort.openPort(SerialPort.java:164)
    at processing.app.Serial.touchForCDCReset(Serial.java:101)
    ... 6 more

```

Operating system: kubuntu linux 64 bit

**EDIT:** Never mind. In the end I used `chmod a-x /usr/sbin/ModemManager` to remove execute permissions from every user, and that worked without any noticeable repercussions to my system. For anyone who wants to do the same, make note of the original permissions, so you can change it back if you have to.

# Answer
> 1 votes
The actual error part of that stack trace is:

```
Port name - /dev/ttyACM1; Method name - openPort(); Exception type - Port busy.

```

You have something else using `/dev/ttyACM1`. If you don't yourself have something open, such as a serial terminal or the Arduino serial monitor, then the most likely culpret is `modemmanager`.

---
Tags: adafruit
---


title: Recommended way to fork a library

text:
# Question
Title: Recommended way to fork a library
I want to extend a library, available on github to add some features I need. Of course I will made available the new source code as well. Because it's the first time I do this, I'm not sure how to do.

My idea:

1. fork the original repository
2. create a new branch
3. make the changes
4. commit them locally
5. push the new branch on another (mine) repository (of course, to avoid messing up the original one)

Is it correct? How to test the library while developing it? I mean, in which folder I have to clone the repo?

# Answer
> 6 votes
Almost.

1. Fork the library to your account
2. Check out your fork
3. Edit as needed
4. Commit locally
5. Push back to your fork

Your fork is yours to do with as you wish. Github makes it easy, should you wish, to then pass those changes back up to the original repository (make a "pull request"). But you don't have to do that (and probably don't want to).

You *can* make a new branch if you like, but that's pointless - your fork is, in effect, a branch itself (well, it's an entire new tree really).

---
Tags: library
---


# Question
Title: Why does Arduino IDE take so long to open?
I have Arduino IDE, version 1.8.10 (Windows 10 x64, 8GB RAM, i5-7200 @2.5GHz) on a network drive mapped to D:, on a 100Mbit wired network and fast file server.

If I navigate to the network shared folder and launch 'arduino.exe', it takes at least 2 minutes for the IDE to appear.

This seems totally unreasonable considering the entire arduino.exe file is only 395kB. Seems more likely the IDE is waiting for something until a timeout occurs, before finally loading up the IDE.

What can be causing this and how can I diagnose it?

As an aside, it seems the compilation process takes longer than it should too, even for programs that use no external libraries and are very short.

# Answer
> 4 votes
The simple answer is "libraries".

Every time you start the application, all files inside your library folder are parsed.

And this is not done over your OS, but over the Java-Virtual Machine.

So it is not just slow, it is ultra-slow! Since your antivirus will probably also check each file.

Once, all files was read (maybe 1/2 of the time spent by your Arduino start), all your sketch folders are parsed.

At the end Windows devices and Arduino specific libraries are loaded.

On my Arduino IDE (is installed locally), on each starts, the Arduino IDE checks about 300.000 files. I need up to 20 seconds to load everything, before I can use the IDE.

## What can you do?

### Base

* do not waste the library folder with unused libraries
* NEVER put some documentation or non-Arduino files in your sketch folder, as they are all parsed by the IDE
* disable the Antivirus for the folders:
    + Arduino
    + libraries
    + sketch

### Advanced

If you open always the same project, you can for example edit the "preferences.txt" file.

If you remove some parameters from the preferences.txt, you will be able to lauch your IDE much faster. I created an application that statrs your Arduino IDE with personalized settings:
https://github.com/Adrianotiger/ArduinoIDE\_Launcher

This application can remove some preferences like:

* boardsmanager
* last.\* settings
* recent sketches

when the Arduino starts, so it will be launched faster. But if you set the preference `sketchbook.path`, you can start your Arduino IDE 3-4 times faster. Just place the folder with your project libraries and you can start the IDE much faster.

---
Tags: arduino-ide, performance
---


# Question
Title: What is the correct way to interpret the built-in Analog-to-Digital Converter output?
When using the built-in analog to digital converter of the Arduino Uno Rev 3's Atmega328P with a reference voltage of 5V, what is the appropriate function to interpret the output? There is conflicting information on the Arduino website and in the datasheet for the Atmega328P (Arduino Uno Rev 3's chipset).

A lot of code examples on the internet indicate that the appropriate conversion factor is 5V/1023 (including the Arduino website: `float voltage= sensorValue * (5.0 / 1023.0);`).

Per the Atmega328P's datasheet, it indicates the conversion factor is 5V/102**4**:

If Vin and Vref are 5V, then the ADC reading would need to be 1024 in order to have a true reading of 5V, which is not possible since 1023 is the max output of the ADC. The closest reading to 5V we can get from this equation is ~4.9951 (5V\*1023/1024).

With the Arduino example's conversion factor of 5V/1023, we get 5V for an ADC output of 1023.

Additionally, since the information from both sources is in conflict, it got me thinking a little more: The ADC is inherently sampling, and I am not sure if the ADC rounds up/down to the nearest value, so perhaps the closest approximation of Vin is an equation like the following that splits the difference:

`Vin = (ADC+(ADC+1))/2 * 1024/Vref`

Using the above equation, an ADC reading of 0 with Vref=5V would give `Vin = (0 + (0+1))/2 *1024/5V = ~0.00244`. This equation never gives a reading of 5V or 0V, but rather a value that splits the difference between samples.

Perhaps I am splitting hairs since the absolute accuracy of the ADC is "±2 LSB absolute accuracy", but I would still like to know which is the best equation to convert an output from the ADC into a voltage measurement.

# Answer
> 3 votes
> the Atmega328P's datasheet, it indicates the conversion factor is 5V/1024 \[...\]

Indeed. And the datasheet is *the only authoritative source*. All the other sources are second-guessing.

> If Vin and Vref are 5V, then the ADC reading would need to be 1024 in order to have a true reading of 5V

You can't get a true reading of 5 V. As per the datasheet (emphasis mine): “*0x000 represents analog ground, and 0x3FF represents the selected reference voltage **minus one LSB***”.

Any input voltage larger that the maximum representable voltage will read as 0x3ff (i.e. 1023), just like any negative voltage (within the forward voltage of the protection diode) will read as zero. Thus, reading either 0 or 1023 should be interpreted as a saturation of the ADC, meaning the actual voltage is unknown.

> The ADC is inherently sampling, and I am not sure if the ADC rounds up/down to the nearest value

In principle it should round to the nearest value. The transition in the reading from 0 to 1 should ideally happen at Vref/2048. C.f., again, the datasheet, subsection “ADC Accuracy Definitions”: “*Offset: The deviation of the first transition (0x000 to 0x001) compared to the ideal transition (**at 0.5 LSB**).*

A little bit further in the page it is stated that the ideal position of the last transition (1022 to 1023) is “*at 1.5 LSB below maximum*”.

> Perhaps I am splitting hairs since the absolute accuracy of the ADC is "±2 LSB absolute accuracy"

Indeed. If you really care you should probably calibrate your ADC. See Response of the Arduino ADC.

**Edit**: in a comment you mention that the factor 1024 could conceivably be “a persistent typo that it appears in multiple AVR chipset datasheets”. It may be an error, but certainly not a typo, as the datasheet contains multiple independent statements that confirm the factor 1024.

# Answer
> 3 votes
As others have said, the difference between 1023 and 1024 is quite small.

However, the fact is that your input range for the ADC is 0 to 1023. (That's 1024 steps, but since it starts at 0, it won't go up to 1024)

You'll get 0 at the minimum input, and **1023** at the maximum value.

If you're using a 5.0V reference voltage and no voltage dividers, that means you will get 1023 at 5V (ignoring measurement error.) If you want your output value to be the VOLTAGE measured, you would want `Vin / 1023.0 * 5.0`. That would give you a value of 5.0 at the max input of 1023 (representing 5.0 volts) and 0 at 0 volts input.

## Edit:

Since my posting, I read the threads on this, and there is a raging debate on the subject. I am now less clear that there is "right" way to do this.

The issue is that the ADC value doesn't give you a certain reading, it indicates a range. When you get a value of 1024, the ADC is tellling you that the measured voltage is in the top 1/1024th of voltages, from about 4.995V to 5V (or above, for that matter.)

The steps are actually in 1024ths. That argues that you should divide the measured value by 1024, and then return a range of possible voltages:

```
value = analoglRead(pin);
float lower_value = value / 1024.0 * 5.0;
float upper_value = (value + 1) / 1024.0 * 5.0;

```

For an analog reading of 0, that would give you a range of 0.0v. to 0.0048828125v.

For an analog value of 1023, that would give you a range of 4.9951171875v to 5.0v

# Answer
> 0 votes
*After reading through various arguments for use of different transfer functions, this is my summary:*

In order to achieve the manufacturer-stated absolute accuracy of ±2 LSB, you should use the manufacturer's equations and published guidelines on usage to ensure that accuracy (e.g. ensuring appropriate ADC clock speed / sampling time and implementing noise reduction techniques).

It may be possible to achieve better results using another transfer function by calibrating specific to each individual circuit. If you go this route, all of the responsibility of ensuring accurate calibration across the range of expected operating conditions (including offset/gain drifts due to environmental factors) are your responsibility to characterize and account for when developing the transfer function. This is where the transfer function `Vin = 5V/1023 * ADC` fits in. This transfer function may in fact be a better representation of the actual outputs for a specific chip. However, use of this transfer function shifts responsibility onto its user to verify that it actually produces better results.

*A couple of important notes:*

* *Manufacturer's claims are not always accurate. However, they are likely based on a large statistical sample size and if the manufacturer's published statements are wrong, this potentially opens the manufacturer up to lawsuits depending on the impact of an incorrect published specification. For this reason, I tend to trust manufacturer datasheets from large chip makers until proven otherwise.*
* *The question assumed a perfect 5V reference for simplicity of discussion, however the actual value of a real voltage reference is almost impossibly a true 5V and has some degree of noise affecting its stability which should also be considered when attempting to read a true voltage value. Ideally, if you are trying to read a sensor value and can create a circuit in which the voltage reference cancels out of the final measurement, that will help with accuracy of the sensor reading.*

---
Tags: arduino-uno, arduino-mega, atmega328, analogread
---


# Question
Title: Black boxes are appearing on the second row of my LCD
the black boxes on the LCD are only on both rows and appear only when I attach the heart rate sensor to my body and blink with a delay of about 2 seconds and my contrast and wiring are perfect, the backlight of my LCD is on...

but when I attach the heart rate sensor they repeat for four or five seconds and the black boxes too would disappear leaving behind only the backlight on...  but then why do the black boxes appear??? please help me out this is the code, schematics, and a picture of how it looks like.

```
    #include <LiquidCrystal.h>
#define IN1  8
#define IN2  9
#define IN3  10
#define IN4  7
int Steps = 4096; //4096 or 768
int cstep = 10;
const int rs = 7, en = 8, d4 = 3, d5 = 4, d6 = 5, d7 = 6;
const int buzzer = 2;
LiquidCrystal lcd(7, 8, 3, 4, 5, 6);

int pulsePin = A3;                 // Pulse Sensor purple wire connected to analog pin A0
int blinkPin = 13;                // pin to blink led at each beat
// Volatile Variables, used in the interrupt service routine!
volatile int BPM;                   // int that holds raw Analog in 0. updated every 2mS
volatile int Signal;                // holds the incoming raw data
volatile int IBI = 600;             // int that holds the time interval between beats! Must be seeded!
volatile boolean Pulse = false;     // "True" when User's live heartbeat is detected. "False" when not a "live beat".
volatile boolean QS = false;        // becomes true when Arduoino finds a beat.

static boolean serialVisual = true;   // Set to 'false' by Default.  Re-set to 'true' to see Arduino Serial Monitor ASCII Visual Pulse

volatile int rate[10];                      // array to hold last ten IBI values
volatile unsigned long sampleCounter = 0;          // used to determine pulse timing
volatile unsigned long lastBeatTime = 0;           // used to find IBI
volatile int P = 512;                      // used to find peak in pulse wave, seeded
volatile int T = 512;                     // used to find trough in pulse wave, seeded
volatile int thresh = 525;                // used to find instant moment of heart beat, seeded
volatile int amp = 100;                   // used to hold amplitude of pulse waveform, seeded
volatile boolean firstBeat = true;        // used to seed rate array so we startup with reasonable BPM
volatile boolean secondBeat = false;      // used to seed rate array so we startup with reasonable BPM

void setup()
{
   pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);
  pinMode(IN3, OUTPUT);
  pinMode(IN4, OUTPUT);
   pinMode(buzzer,OUTPUT);
  pinMode(blinkPin,OUTPUT);         // pin that will blink to your heartbeat!
  Serial.begin(115200);             // we agree to talk fast!
  interruptSetup();                 // sets up to read Pulse Sensor signal every 2mS
                                    // IF YOU ARE POWERING The Pulse Sensor AT VOLTAGE LESS THAN THE BOARD VOLTAGE,
                                    // UN-COMMENT THE NEXT LINE AND APPLY THAT VOLTAGE TO THE A-REF PIN
                                    //   analogReference(EXTERNAL);
 lcd.begin(16, 2);
 lcd.clear();
}

//  Where the Magic Happens
void loop()
{
   serialOutput();
    lcd.print("DEVICE-STATE");
     lcd.setCursor(1,1);
     lcd.print("UPDATING... ");
     lcd.setCursor(5,1);
     delay(3000);
     lcd.clear();
  if (QS == true) // A Heartbeat Was Found
    {
      // BPM and IBI have been Determined
      // Quantified Self "QS" true when arduino finds a heartbeat
      serialOutputWhenBeatHappens(); // A Beat Happened, Output that to serial.
      QS = false; // reset the Quantified Self flag for next time
      state();
      buzer();
      inject();
    }

  delay(20); //  take a break
}

void interruptSetup()
{
  // Initializes Timer2 to throw an interrupt every 2mS.
  TCCR2A = 0x02;     // DISABLE PWM ON DIGITAL PINS 3 AND 11, AND GO INTO CTC MODE
  TCCR2B = 0x06;     // DON'T FORCE COMPARE, 256 PRESCALER
  OCR2A = 0X7C;      // SET THE TOP OF THE COUNT TO 124 FOR 500Hz SAMPLE RATE
  TIMSK2 = 0x02;     // ENABLE INTERRUPT ON MATCH BETWEEN TIMER2 AND OCR2A
  sei();             // MAKE SURE GLOBAL INTERRUPTS ARE ENABLED
}

void serialOutput()
{   // Decide How To Output Serial.
 if (serialVisual == true)
  {
     arduinoSerialMonitorVisual('-', Signal);   // goes to function that makes Serial Monitor Visualizer
  }
 else
  {
      sendDataToSerial('S', Signal);     // goes to sendDataToSerial function
   }
}

//Heart Attack Preventer

void serialOutputWhenBeatHappens()
{
 if (serialVisual == true) //  Code to Make the Serial Monitor Visualizer Work
   {
     Serial.print(" Heart-Beat Found ");  //ASCII Art Madness
     Serial.print("BPM: ");
     Serial.println(BPM);
     lcd.print("Heart-Beat Found ");
     lcd.setCursor(1,1);
     lcd.print("BPM: ");
     lcd.setCursor(5,1);
     lcd.print(BPM);
     delay(3000);
     lcd.clear();
   }
 else
   {
     sendDataToSerial('B',BPM);   // send heart rate with a 'B' prefix
     sendDataToSerial('Q',IBI);   // send time between beats with a 'Q' prefix
   }
}

void arduinoSerialMonitorVisual(char symbol, int data )
{
  const int sensorMin = 0;      // sensor minimum, discovered through experiment
  const int sensorMax = 1024;    // sensor maximum, discovered through experiment
  int sensorReading = data; // map the sensor range to a range of 12 options:
  int range = map(sensorReading, sensorMin, sensorMax, 0, 11);
  // do something different depending on the
  // range value:
}

void sendDataToSerial(char symbol, int data )
{
   Serial.print(symbol);
   Serial.println(data);
}

ISR(TIMER2_COMPA_vect) //triggered when Timer2 counts to 124
{
  cli();                                      // disable interrupts while we do this
  Signal = analogRead(pulsePin);              // read the Pulse Sensor
  sampleCounter += 2;                         // keep track of the time in mS with this variable
  int N = sampleCounter - lastBeatTime;       // monitor the time since the last beat to avoid noise
                                              //  find the peak and trough of the pulse wave
  if(Signal < thresh && N > (IBI/5)*3) // avoid dichrotic noise by waiting 3/5 of last IBI
    {
      if (Signal < T) // T is the trough
      {
        T = Signal; // keep track of lowest point in pulse wave
      }
    }

  if(Signal > thresh && Signal > P)
    {          // thresh condition helps avoid noise
      P = Signal;                             // P is the peak
    }                                        // keep track of highest point in pulse wave

  //  NOW IT'S TIME TO LOOK FOR THE HEART BEAT
  // signal surges up in value every time there is a pulse
  if (N > 250)
  {                                   // avoid high frequency noise
    if ( (Signal > thresh) && (Pulse == false) && (N > (IBI/5)*3) )
      {
        Pulse = true;                               // set the Pulse flag when we think there is a pulse
        digitalWrite(blinkPin,HIGH);                // turn on pin 13 LED
        IBI = sampleCounter - lastBeatTime;         // measure time between beats in mS
        lastBeatTime = sampleCounter;               // keep track of time for next pulse

        if(secondBeat)
        {                        // if this is the second beat, if secondBeat == TRUE
          secondBeat = false;                  // clear secondBeat flag
          for(int i=0; i<=9; i++) // seed the running total to get a realisitic BPM at startup
          {
            rate[i] = IBI;
          }
        }

        if(firstBeat) // if it's the first time we found a beat, if firstBeat == TRUE
        {
          firstBeat = false;                   // clear firstBeat flag
          secondBeat = true;                   // set the second beat flag
          sei();                               // enable interrupts again
          return;                              // IBI value is unreliable so discard it
        }
      // keep a running total of the last 10 IBI values
      word runningTotal = 0;                  // clear the runningTotal variable

      for(int i=0; i<=8; i++)
        {                // shift data in the rate array
          rate[i] = rate[i+1];                  // and drop the oldest IBI value
          runningTotal += rate[i];              // add up the 9 oldest IBI values
        }

//Heart Attack Preventer
rate[9] = IBI;                          // add the latest IBI to the rate array
      runningTotal += rate[9];                // add the latest IBI to runningTotal
      runningTotal /= 10;                     // average the last 10 IBI values
      BPM = 60000/runningTotal;               // how many beats can fit into a minute? that's BPM!
      QS = true;                              // set Quantified Self flag
      // QS FLAG IS NOT CLEARED INSIDE THIS ISR
    }
  }

  if (Signal < thresh && Pulse == true)
    {   // when the values are going down, the beat is over
      digitalWrite(blinkPin,LOW);            // turn off pin 13 LED
      Pulse = false;                         // reset the Pulse flag so we can do it again
      amp = P - T;                           // get amplitude of the pulse wave
      thresh = amp/2 + T;                    // set thresh at 50% of the amplitude
      P = thresh;                            // reset these for next time
      T = thresh;
    }

  if (N > 2500)
    {                           // if 2.5 seconds go by without a beat
      thresh = 512;                          // set thresh default
      P = 512;                               // set P default
      T = 512;                               // set T default
      lastBeatTime = sampleCounter;          // bring the lastBeatTime up to date
      firstBeat = true;                      // set these to avoid noise
      secondBeat = false;                    // when we get the heartbeat back
    }

  sei();                                   // enable interrupts when youre done!
}// end isr
void buzer(){
  // dangerous situation or pressed button
  if (BPM < 60 )
   {
     lcd.print("hypotension");
     lcd.setCursor(1,1);
     lcd.print("BPM: ");
     lcd.setCursor(5,1);
     lcd.print(BPM);
     delay(3000);
     lcd.clear();
   digitalWrite(buzzer,HIGH);
    delay(500);
   digitalWrite(buzzer,LOW);
    delay(500);

}

}
void inject()
{
   if (BPM>60)
   {
     lcd.print("Hypertention");
     lcd.setCursor(1,1);
     lcd.print("BPM: ");
     lcd.setCursor(5,1);
     lcd.print(BPM);
     delay(5000);
     lcd.clear();
  for(int x=0;x<Steps;x++)
  {
   switch(cstep)
  {
   case 0:
     digitalWrite(IN1, LOW);
     digitalWrite(IN2, LOW);
     digitalWrite(IN3, LOW);
     digitalWrite(IN4, HIGH);
   break;
   case 1:
     digitalWrite(IN1, LOW);
     digitalWrite(IN2, LOW);
     digitalWrite(IN3, HIGH);
     digitalWrite(IN4, HIGH);
   break;
   case 2:
     digitalWrite(IN1, LOW);
     digitalWrite(IN2, LOW);
     digitalWrite(IN3, HIGH);
     digitalWrite(IN4, LOW);
   break;
   case 3:
     digitalWrite(IN1, LOW);
     digitalWrite(IN2, HIGH);
     digitalWrite(IN3, HIGH);
     digitalWrite(IN4, LOW);
   break;
   case 4:
     digitalWrite(IN1, LOW);
     digitalWrite(IN2, HIGH);
     digitalWrite(IN3, LOW);
     digitalWrite(IN4, LOW);
   break;
   case 5:
     digitalWrite(IN1, HIGH);
     digitalWrite(IN2, HIGH);
     digitalWrite(IN3, LOW);
     digitalWrite(IN4, LOW);
   break;
     case 6:
     digitalWrite(IN1, HIGH);
     digitalWrite(IN2, LOW);
     digitalWrite(IN3, LOW);
     digitalWrite(IN4, LOW);
   break;
   case 7:
     digitalWrite(IN1, HIGH);
     digitalWrite(IN2, LOW);
     digitalWrite(IN3, LOW);
     digitalWrite(IN4, HIGH);
   break;
   default:
     digitalWrite(IN1, LOW);
     digitalWrite(IN2, LOW);
     digitalWrite(IN3, LOW);
     digitalWrite(IN4, LOW);
   break;
  }

   cstep=cstep+1;
   if(cstep==8)
     {cstep=0;}

  delayMicroseconds(2500);

   }
}
}
void state()
{
  if (BPM > 60 & BPM < 74){
   lcd.print("VERY-GOOD");
     lcd.setCursor(1,1);
     lcd.print("BPM: ");
     lcd.setCursor(5,1);
     lcd.print(BPM);
     delay(3000);
     lcd.clear();
  }
}

```

# Answer
> 0 votes
I think it was because the charge of the battery was less and therefore the contrast of it was less and so I couldn't see the characters displayed...

Thanks to all those people who helped me with this problem and thanks to stack overflow

Now it is working as I used a different battery

---
Tags: lcd
---


# Question
Title: When connecting, client.connect() returns 0
I'm using an arduino UNO with ethernet shield. When following a few guides online for a school project I came across this issue. First code sample:

```

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

    EthernetClient client;

    byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
    IPAddress ip(192, 168, 1, 25);
    byte server[] = { 64, 233, 187, 99 }; // Google

    void setup() {
      Ethernet.begin(mac, ip);
      Serial.begin(9600);
      delay(1000);
      Serial.println(Ethernet.localIP());
    }

    void loop() {
      if (client.connect(server, 80)) {
        Serial.println("connected");
        client.println("GET /search?q=arduino HTTP/1.0");
        client.println();
      } else {
        Serial.println("connection failed");
        Serial.println(client.connect(server, 80));
      }
    }

```

This doesn't work, unfortunately. We successfully connect to our network, but `client.connect()` doesn't work and returns 0. Expected result:

> SUCCESS: 1
> TIMED\_OUT: -1
> INVALID\_SERVER: -2
> TRUNCATED: -3
> INVALID\_RESPONSE: -4

According to the documentation it shouldn't be able to return this. Why wouldn't this work? Thanks in advance.

# Answer
> 0 votes
The documentation is wrong. The `connect` function only returns 1 on success and 0 on fail. All examples have `if (client.connect(host, port)) {` (0 is false, 1 is true).

Try the WebClient example provided in the IDE Examples menu for the Ethernet library. It has better diagnostics of Ethernet link.

You can try the WebServer example. It doesn't need Internet connection.

You can try ping the IP address of the Ethernet shield.

The shield should be connected to a router or switch and the gateway IP address should point to a device routing the network traffic to Internet.

# Answer
> -1 votes
You need to provide more than just the IP address. The Arduino also needs to know the default router address in order to send packets to the right place.

Unfortunately there isn't a way of giving it that information without also giving it a DNS address, so you have to do that as well.

You need to have:

```
IPAddress gateway(192, 168, 1, 1);
IPAddress dns(8, 8, 8, 8);
IPAddress ip(192, 168, 1, 25);

```

And then in setup:

```
Ethernet.begin(mac, ip, dns, gateway);

```

Alternatively you can rely on DHCP to give you all the details, and just use:

```
Ethernet.begin(mac);

```

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


# Question
Title: ESP web server calling Javascript function
Is there a way to call Javascript functions from an ESP?

I don't want to call AJAX requests every few seconds; I want to update my values only when they change.

Can it by done?

# Answer
If you want server-push, you can use Server Sent Events or a Websocket instead of polling with XMLHttpRequest.

So yes, it can be done, and I have implemented both using a Nano 33 IoT at one end and Javascript in a browser on the other. Some example code is here: https://github.com/ocrdu/arduino-webinterface-sse and here: https://github.com/ocrdu/arduino-webinterface-websocket.

I don't know if there are convenient libraries for the ESPs to do this, though.
> 2 votes

# Answer
I assume that you misunderstand how JavaScript works. JS is executed on the client side and therefore the esp can easily serve JS code the same way it would provide any html content. Take a look at the Webserver examples and embed your JavaScript code into the html content that the examples use.

The important thing to note is that the esp does not execute JavaScript, from its perspective the content is just an ordinary string without functionality.

The easiest and fastest way to update values on a web interface is probably using a websocket: the esp is a websocket server (using link2004‘s websocket library) and the JavaScript binds to the esp‘s websocket as a client (this has nothing to do with the esp/arduino/C++, but you’ll find examples out there).
> 1 votes

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


title: Powering an rc car motor with arduino

text:
# Question
Title: Powering an rc car motor with arduino
I have a weird problem. When I power an rc car motor through the 5v or the 3.3V arduino's outputs everything goes fine, while powering it through digitalPins does not work. I'm testing digitalPins with a simple led Blink example. Leds work, the motor does not move. Shouldn't digitalWrite(pinNumber, HIGH) output 5volts? What is the difference between digitalWrite voltage and 5v board output voltage? It seems crazy to me that leds light up without problems but the motor remains motionless...

# Answer
Never ever power a motor or anything, that needs that much power, through a digital output pin. The maximum rating is 40mA, though you should not draw more than 20mA continuously from it. Also there is an overall limit of 100mA over all digital pins together. If you are drawing more from the pins, first the voltage will drop immediately, since the pin cannot provide what you ask for. Then you can easily destroy the pins output hardware or the whole Arduino. For an LED you normally use a current limiting resistor, so that it does not draw too much current from the pin.

For anything with more current demands, you need some kind of driver, which will take the big current load of the microcontroller. The easiest driver is a transistor or MOSFET (to switch the motor on and off or to have different speeds). If you want the motor to spin in both directions, you need an H-bridge driver (effectively 4 transistors/MOSFETs).

Note: I'm talking about simple DC motors here. Other types of motors need other types of drivers.
> 4 votes

---
Tags: led
---


# Question
Title: Does RFID-RC522 supoort tk4100 chip protocol ISO18000-2C 10 digital ID card?
I have ordered a starter kit and received RFID reader is

> RFID-RC522

module with one card and tag now I need more RFID card for my project and I can't find the supported card type for my project please can any one tell me supported card types and if this card supports my device this is the card type

> tk4100 chip protocol ISO18000-2C 10 digital ID number

# Answer
The MFRC522 on your kit is designed to communicate with ISO/IEC 14443 A/MIFARE and NTAG cards.

Search for `Mifare Classic` or `Mifare Ultralight` or `NTAG213`, `NTAG216` ... cards.
> 0 votes

---
Tags: rfid
---


# Question
Title: Accel Stepper help, stepper not going backwards
So my question is that I am trying to use a arduino library called Accel Stepper to control a stepper motor, I made code that makes the stepper motor move one rev clockwise and then one rev counter clockwise

however as i run the code, the motor has no problem going clockwise, however when it comes to reversing the shaft of the motor stays still and doesn't move while the whole motor itself vibrates, what could be my problem?

here is my code:

```
    // MultiStepper.pde
    // -*- mode: C++ -*-
    //
    // Shows how to multiple simultaneous steppers
    // Runs one stepper forwards and backwards, accelerating and decelerating
    // at the limits. Runs other steppers at the same time
    //
    // Copyright (C) 2009 Mike McCauley
    // $Id: MultiStepper.pde,v 1.1 2011/01/05 01:51:01 mikem Exp mikem $

    #include <AccelStepper.h>
    int user = 800;
    // Define some steppers and the pins the will use

    AccelStepper stepper2(AccelStepper::DRIVER, 9,8 );
    AccelStepper stepper3(AccelStepper::DRIVER, 4, 7);

    void setup()
    {

        stepper2.setMaxSpeed(1000);
        stepper2.setSpeed(300);

    }

    void loop()
    {
        // Change direction at the limits
      stepper2.moveTo(user);
      stepper2.setSpeed(300);
      stepper2.runSpeedToPosition();
      if (stepper2.distanceToGo() == 0){
        stepper2.moveTo(-stepper2.currentPosition());
        stepper2.setSpeed(300);
        stepper2.runSpeedToPosition();
      }

    }

```

# Answer
> 0 votes
Work through your code. When it gets to the target position, your loop looks like this:

```
void loop()
{
    // Change direction at the limits
  stepper2.moveTo(user);
  stepper2.setSpeed(300);
  stepper2.runSpeedToPosition();
    stepper2.moveTo(-stepper2.currentPosition());
    stepper2.setSpeed(300);
    stepper2.runSpeedToPosition();

}

```

So you say, move to position 'user', then move to position '-stepper2.currentPosition'. Then as the loop comes around you again say move to position 'user', and so on.

The loop will repeat hundreds if no thousands of times per second, so you are basically telling the stepper motor to change direction thousands of times per second which will be why the motor starts vibrating when it gets to the user position.

If, just for the sake of argument, you were to move the first three lines of code in the loop() function to the setup() function, what behaviour do you think you will observe?

# Answer
> 0 votes
to reverse the direction try passing negative speed value to speed

like

stepper2.setSpeed(-300);

---
Tags: library
---


# Question
Title: SD Library function doesnt work while using second SPI port with ESP32
i work on a group project with an ESP32. We have a lcd display and a sd card connected via the two SPI ports of the ESP32.

The card gets initialized with no problem using this code:

```
 bool EKG_recording::initialisation_sd() {

  SPIClass * hspi = new SPIClass(HSPI);

  if (!SD.begin(CS_Pin, *hspi))
  {
    Serial.println("No valid SD card!");
    return 0;
  }

  else if (SD.begin(CS_Pin, *hspi))
  {
    Serial.println("SD card initialized!");
    return 1;
  }
  else return 0;
}

```

One function i have a problem with is used to count every file on the SD card, simple enough right?

```
unsigned short EKG_recording::count_files_from_SD(File dir) {
  while (true)
  {
    File entry = dir.openNextFile();
    if (!entry)
    {
      // Serial.println("Anzahl der Daten");
      return counter;
    }
    counter++;
    entry.close();
  }
}

```

It once worked without a problem, then we integrated the two SPI ports and now i cant figure out why its not working. This part: `File entry = dir.openNextFile();` returns false on the first call even though i am 100% sure there are 3 files on the SD card.

I call the function like this :

`File root = SD.open("/");
EKG_recording_1.count_files_from_SD(root);`

But why? Any help is very appreciated.

This is the begin function of the display. Since i didnt write it, i know next to nothing about it.

```
    void EKG_display_control::begin()
{
  // Backgroundlight off
  pinMode(TFT_LED, OUTPUT);
  disable_display_backlight();

  // Initialise Display
  tft.begin(40000000);
  touch.begin();
  tft.setRotation(ROTATION);

  layout_start_screen();
}

```

# Answer
> 1 votes
Ok i found the solution. It was not too complicated. I just assumed the problem was in the code. This works well enough (dont ask me about the counter--)

```
  unsigned short EKG_recording::count_files_from_SD() {

  root = SD.open("/");
  root.rewindDirectory(); //Sets to beginning of directory

  while (true)
  {
    File entry = root.openNextFile();

    if(!entry){
      Serial.println("Anzahl der Daten");
      counter--;
      return counter;
    }
    counter++;
    entry.close();
  }
}

```

It was just because i used SD.open() always inside the class-functions, so every file root was bound to the class.

---
Tags: spi, esp32, sd
---


# Question
Title: Ethernet shield connected to local network, not to internet
Using the WebServer example file I have been able to confirm that my arduino is connected to my local network and I can open the page in my browser. However any attempt at contacting addresses outside my own network fails. For example this simple script:

```

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

    EthernetClient client;

    byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
    IPAddress ip(192, 168, 1, 25);
    IPAddress gateway(192, 168, 1, 1);
    IPAddress dns(8, 8, 8, 8);
    byte server[] = { 64, 233, 187, 99 }; // Google

    void setup() {
      Ethernet.begin(mac, ip, dns, gateway);
      Serial.begin(9600);
      delay(1000);
      Serial.println(Ethernet.localIP());
    }

    void loop() {
      if (client.connect(server, 80)) {
        Serial.println("connected");
        client.println("GET /search?q=arduino HTTP/1.0");
        client.println();
      } else {
        Serial.println("connection failed");
      }
    }

```

This consistently returns `connection failed`. The ethernet cable in the arduino has an active internet connection, albeit via a switch. My board is an arduino uno.

# Answer
> 1 votes
Find a server that doesn't automatically switch modes to https as google does. If you put 64.233.187.99/search?q=arduino%20HTTP/1.0 in your browser you'll see that it switches to https.

If make the same request via the wget terminal app it fails.

```
--2020-01-17 11:42:26--  http://64.233.187.99/search?q=arduino%20HTTP/1.0
Connecting to 64.233.187.99:80... connected.
HTTP request sent, awaiting response... 301 Moved Permanently
Location: http://www.google.com/search?q=arduino%20HTTP/1.0 [following]
--2020-01-17 11:42:26--  http://www.google.com/search?q=arduino%20HTTP/1.0
Resolving www.google.com... 172.217.4.132, 2607:f8b0:4007:80c::2004
Connecting to www.google.com|172.217.4.132|:80... connected.
HTTP request sent, awaiting response... 403 Forbidden
2020-01-17 11:42:28 ERROR 403: Forbidden.

```

There should also be an error returned to the client object which you can print out for debugging the conection.

Change your code to print out the return value of the client.connect call like so

```
void loop() {
      int result = client.connect(server, 80);
      if (x) {
        Serial.println("connected");
        client.println("GET /search?q=arduino HTTP/1.0");
        client.println();
      } else {
        Serial.println("connection failed");
        Serial.println(x);  // print out the error
      }
    }

```

One last thing, you set your dns server to 8.8.8.8 which should generally be set to your gateway / router of 192.168.1.1.

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


# Question
Title: How to control segments with SevSeg library
The SevSeg library by Dean Reading seems to have a keyword to control individual segments on SSD's. I am using four common cathode, single digit displays. Does anyone know how to program individual segments?

```
#include "SevSeg.h";

SevSeg sevseg;

void setup() {
  // put your setup code here, to run once:

  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_CATHODE; // See README.md for options
  bool updateWithDelays = false; // Default 'false' is Recommended
  bool leadingZeros = false; // Use 'true' if you'd like to keep the leading zeros
  bool disableDecPoint = false; // Use 'true' if your decimal point doesn't exist or isn't connected. Then, you only need to specify 7 segmentPins[]

  sevseg.begin(hardwareConfig, numDigits, digitPins, segmentPins,
    resistorsOnSegments,
    updateWithDelays, leadingZeros, disableDecPoint);

}

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

  sevseg.setSegments();
  //sevseg.setNumber(1234,0);
  //sevseg.setChars("");
  //sevseg.blank();
  sevseg.refreshDisplay();

}

```

# Answer
> 0 votes
You can't with that library. The author has not provided any public methods that will do the job.

There are private methods (`segmentOn` and `segmentOff`) that might be usable, but you would have to modify the library to be able to access them.

---
Tags: library, display
---


# Question
Title: Is there an alternative to strtok_r in extracting words from char?
The task, in char, I get some data that I have to parse into parts.

In this case, I use strtok\_r, which finds identifiers like

> "=", " ", "&"

**Code:**

```
char payload[70] = "GET /wifi?ssid=MyWiFi&pass=123456789 HTTP 11";
char *p;
char *i;

void setup() {
  Serial.begin(15200);
  Serial.println("Load");

  p = strtok_r(payload, "=", &i);
  // Get SSID
  p = strtok_r(NULL, "&", &i);
  Serial.println(p);

  p = strtok_r(NULL, "=", &i);
  // Get PASS
  p = strtok_r(NULL, " ", &i);
  Serial.println(p);
}

void loop() {}

```

**Result:**

> Load MyWiFi 123456789

This works, but as soon as I add the characters strtok\_r works on to the ssid = or pass = value, it stops working, outputting the cropped data.

These characters can be in the name of any WiFi network or the generated password.

Tell me, are there strtok\_r analogues, where instead of a single character I can insert a whole phrase?

For example, so that he finds the beginning of ssid by the tag "ssid=", and finishes before "pass=".

**Resolved.**

Thank you all for your help!

I studied both options from @Majenko and @user7761803. All of them came in handy in various parts of the code.

Perhaps someone will use the Regexp library to parse such data. Here is example:

```
    #include <Regexp.h>

    char payload[60] = "ssid=MyWifi&pass=ukLPm&I*uwlm HTTP";
    char ssid[25], pass[25];

    void setup() {
      ms.Target(payload);
      char match_result = ms.Match("ssid=(.*)&pass=(.*) H", 0);
      if(match_result == 1) {
       // Get SSID
       ssid = ms.GetCapture(regexp_var.buffer, 0);
       // Get PASS
       pass = ms.GetCapture(regexp_var.buffer, 1);
      }
    }

    void loop() {}

```

# Answer
The function you are looking for is `strstr()`, which takes two strings, and returns a pointer to where the second string appears in the first (or `NULL` if it doesn't appear).

You could use it something like this:

```
void setup() {

    Serial.begin(15200);
    Serial.println("Load");

    char *p = strstr(payload, "ssid=");
    char *q = strstr(payload, "pass=");
    char *r = strstr(payload, " HTTP");

    char *ssid = NULL;
    char *pass = NULL;

    if (p == NULL || q == NULL || r == NULL) {
        // One or other (or both) missing - what to do?
    } else {
        *r = '\0';  // Terminate the last string

        // If this really is an HTTP query string, we don't know
        // if ssid or pass will be first
        if (p < q) {    // Terminate the first string
            *(q - 1) = '\0';
        } else {
            *(p - 1) = '\0';
        }

        ssid = p + 5;
        pass = q + 5;

        Serial.println(ssid);
        Serial.println(pass);
    }
}

```

Note, however, that your `payload` string looks like an HTTP query string.

These are *defined* so that they are split at the `&` characters, and if a `&` needs to appear in one of the values, it should be *percent encoded* (where the `&` would appear as `%26`, and would need to be decoded afterwards).

However, that wasn't your question...
> 3 votes

# Answer
The normal way of parsing such complex strings in any language is to use *Regular Expressions*.

Normally these are pretty heavy-weight to use, but thankfully Nick Gammon has written an Arduino implementation of regexp.
> 1 votes

---
Tags: arduino-uno, esp32
---


# Question
Title: Could someone explain this weird looking code, used to setup timers?
While looking at sketches other people have written, I occasionally come across code that looks somewhat like this:

```
TCCR1A = 0;
TCCR1B = 0;

TCNT1 = 34286;
TCCR1B |= (1 << CS12);
TIMSK1 |= (1 << TOIE1);

```

All I know is that is has something to with timing/timers (I think). How can I decipher—and create—code like this? What are `TCCR1A`, `TCCR1B`, `TCNT1`, `CS12`, `TIMSK1`, and `TOIE1`?

# Answer
This isn't weird looking. It's what normal MCU code actually looks like.

What you have here is an example of the concept of *memory-mapped peripherals*. Basically, the MCU hardware has special locations in the SRAM address space of the MCU assigned to it. If you write to these addresses, the bits of the byte written to address *n* control the behaviour of peripheral *m*.

Basically, certain banks of memory literally have little wires running from the SRAM cell to the hardware. If you write a "1" to this bit in that byte, it sets this SRAM cell to a logical high, which then turns on some portion of the hardware.

If you look into the headers for the MCU, there are great big tables of keyword\<-\>address mappings. This is how things like `TCCR1B` etc... are resolved at compile time.

This memory-mapping mechanism is extremely broadly used in MCUs. The ATmega MCU in the arduino use it, as do PIC, ARM, MSP430, STM32 and STM8 MCU series, as well as lots of MCUs I'm not immediately familiar with.

---

*Arduino* code is the weird stuff, with functions that access the MCU control registers indirectly. While this is somewhat "nicer" looking, it's also much slower, and uses a lot more program space.

The mysterious constants are all described in great detail in the ATmega328P datasheet, which you really should read if you're interested in doing anything more then occationally toggling pins on an arduino.

Select excerpts from the datasheet linked above:

So, for example, `TIMSK1 |= (1 << TOIE1);` sets the bit `TOIE1` in `TIMSK1`. This is achieved by shifting binary 1 (`0b00000001`) to the left by `TOIE1` bits, with `TOIE1` being defined in a header file as 0. This is then bitwise ORed into the current value of `TIMSK1`, which effectively set this one bit high.

Looking at the documentation for bit 0 of `TIMSK1`, we can see it is described as

> When this bit is written to one, and the I-flag in the Status Register is set (interrupts globally enabled), the Timer/Counter1 Overflow interrupt is enabled. The corresponding Interrupt Vector (See ”Interrupts” on page 57) is executed when the TOV1 Flag, located in TIFR1, is set.

All the other lines should be interpreted in the same manner.

---

Some notes:

You may also see things like `TIMSK1 |= _BV(TOIE1);`. `_BV()` is a commonly used macro originally from the AVR libc implementation. `_BV(TOIE1)` is functionally identical to `(1 << TOIE1)`, with the benefit of better readability.

Also, you may also see lines such as: `TIMSK1 &= ~(1 << TOIE1);` or `TIMSK1 &= ~_BV(TOIE1);`. This has the opposite function of `TIMSK1 |= _BV(TOIE1);`, in that it *unsets* the bit `TOIE1` in `TIMSK1`. This is achieved by taking the bit-mask produced by `_BV(TOIE1)`, performing a bitwise NOT operation on it (`~`), and then ANDing `TIMSK1` by this NOTed value (which is 0b11111110).

Note that in all these cases, the value of things like `(1 << TOIE1)` or `_BV(TOIE1)` are fully resolved at *compile time*, so they functionally reduce to a simple constant, and therefore take no execution time to compute at runtime.

---

Properly written code will *generally* have comments inline with the code that detail what the registers being assigned to do. Here is a fairly simple soft-SPI routine I wrote recently:

```
uint8_t transactByteADC(uint8_t outByte)
{
    // Transfers one byte to the ADC, and receives one byte at the same time
    // does nothing with the chip-select
    // MSB first, data clocked on the rising edge

    uint8_t loopCnt;
    uint8_t retDat = 0;

    for (loopCnt = 0; loopCnt < 8; loopCnt++)
    {
        if (outByte & 0x80)         // if current bit is high
            PORTC |= _BV(ADC_MOSI);     // set data line
        else
            PORTC &= ~(_BV(ADC_MOSI));  // else unset it

        outByte <<= 1;              // and shift the output data over for the next iteration
        retDat <<= 1;               // shift over the data read back

        PORTC |= _BV(ADC_SCK);          // Set the clock high

        if (PINC & _BV(ADC_MISO))       // sample the input line
            retDat |= 0x01;         // and set the bit in the retval if the input is high

        PORTC &= ~(_BV(ADC_SCK));       // set clock low
    }
    return retDat;
}

```

`PORTC` is the register that controls the value of output pins within `PORTC` of the ATmega328P. `PINC` is the register where the *input* values of `PORTC` are available. Fundamentally, things like this are what happen internally when you use the `digitalWrite` or `digitalRead` functions. However, there is a look-up operation that converts the arduino "pin numbers" into actual hardware pin numbers, which takes somewhere in the realm of 50 clock cycles. As you can probably guess, if you're trying to go fast, wasting 50 clock cycles on an operation that should only require 1 is a bit ridiculous.

The above function probably takes somewhere in the realm of 100-200 clock cycles to transfer 8 bits. This entails 24 pin-writes, and 8 reads. This is many, many times faster then using the `digital{stuff}` functions.
> 15 votes

# Answer
`TCCR1A` is timer/counter 1 control register A

`TCCR1B` is timer/counter 1 control register B

`TCNT1` is timer/counter 1's counter value

`CS12` is the 3rd clock select bit for timer/counter 1

`TIMSK1` is timer/counter 1's interrupt mask register

`TOIE1` is the timer/counter 1 overflow interrupt enable

So, the code enables timer/counter 1 at 62.5 kHz and sets the value to 34286. Then it enable the overflow interrupt so when it reaches 65535, it will trigger the interrupt function, most likely labelled as `ISR(timer0_overflow_vect)`
> 3 votes

# Answer
CS12 has a value of 2 since it represents bit 2 of the TCCR1B register.

(1 \<\< CS12) takes the value 1 (0b00000001) and shifts it left 2 times to get (0b00000100). The order of operations dictates that things in () happen first, so this is done before the "|=" is evaluated.

(1 \<\< CS10) takes the value 1 (0b00000001) and shifts it left 0 times to get (0b00000001). The order of operations dictates that things in () happen first, so this is done before the "|=" is evaluated.

So now we get TCCR1B |= 0b00000101, which is the same as TCCR1B = TCCR1B | 0b00000101.

Since "|" is "OR", all the bits other than CS12 in TCCR1B are unaffected.
> 1 votes

---
Tags: timers, programming
---


title: How to get char array's length

text:
# Question
Title: How to get char array's length
I use a LCD display to display a not known size of text ( changes over time ). I wish to display it at the center of LCD ( 2X16 ).

I declare:

```
  char t[16];
  char h[16];
  sprintf(t, "%.1f%cC %.0f%%", temperature,223, humidity);

```

Now, since I want to add additional data on a specific line and center it, I need to know it size. When using:

```
sizeof(t)/(sizeof(t[0])

```

I get `16` which is the size determined and not its actual size.

How can I get the exact number of chars **used**?

# Answer
> 7 votes
The function I think you are looking for is `strlen` \- STRing LENgth.

It counts the number of characters in a string up until it finds the "NULL" end of string marker.

```
Serial.println(strlen(t));

```

---
Tags: array, strlen
---


title: Esp8266 Vin pin

text:
# Question
Title: Esp8266 Vin pin
I've read that Vin pin is directly connected to usb cable in esp8266 (which is 5V). I wonder if I can power a relay 5V and a servo motor Sg90 with this pin? And is there any danger of doing that ?

# Answer
> 1 votes
The GPIO pins on the ESP8266 (including the ones with built-in NodeMCU) are 3.3v tolerant.

First, if there is ever any feedback from the 5v+ from the relay coming back down the signal wire, it'll likely cook the ESP.

Also, if it's a 5v relay, 3.3v from the ESP most likely wouldn't be enough to trigger the unit anyhow.

You'll either need to power the relay from an external power supply (or the Vin pin depending on the mA the relay requires), and then use a voltage converter (eg. logic level converter) so you can have 5v on the relay side (I'm speaking of the signal pin here), and 3.3v on the ESP side, or purchase a relay that will operate on 3.3v.

# Answer
> 6 votes
(Answering in more detail, as this is the top search hit for "ESP8266 Vin", at least for me)

**TL;DR**: `Vin` is NOT directly connected to USB power. There is a protection diode between USB+/VU and `Vin`, which has a limited current capacity. If your board provides `VU`, that one *is* directly connected to USB power. As long as you only *power* 1-2 tiny devices, it should be OK. (*controlling* will need additional components, or it will fry your ESP)

---

Since you talk about 'Vin' and '5V', I'm going to assume you have a devboard, not a 'naked' ESP8266. If your "esp8266" has a USB-connector and flash/reset buttons, then its a devboard-version. If it is only a fingernail-sized metal cover with a 1mm edge with solderpads, then its 'naked'.

The `Vin` pin is a power ***in**put* for the onboard regulator. On all common devboards, there is a protection diode between the USB+ wire, and `Vin`. Some devboards also provide a `VU`-pin, which is directly connected to the USB+ wire without anything in-between.

The 3.3V regulator converts any input voltage (5V-19V) connected to `Vin` into the 3.3V needed by the ESP chip and the `3V3`-pins. The regulator has capacity (barely) for the ESP and a (large) handful of leds, not much more.

---

There is **always danger** when connecting mechanical/magnetic 'power'-devices (relays, servos and motors) in the same circuit with 'sensitive' microcontrollers/logic gates. 'power' devices are noisy and cause feedback which must be filtered, blocked and absorbed so it will not fry 'small' electronics. (even a toothbrush motor is 'power', compared to microchips). 'Power' devices are also hungry, causing voltage drops when activated. These drops can cause glitches, bugs and even resets in logic-level electronics.

This not stop many people from trying it anyway, and it will *often* work, for a while, until it someday 'mysteriously' stops working because the chip finally gave out under the repeated abuse.

(side note: as other have mentioned: You also cannot *control* magnetic/mechanical devices directly from the signal pins. Microcontroller outputs are too weak. Trying anyway can destroy your microcontroller with the feedback.)

---

A detailed background explanation for powering ESP devboards, including wiring schematics and explanations, can be found here: https://henrysbench.capnfatz.com/henrys-bench/arduino-projects-tips-and-more/powering-the-esp-12e-nodemcu-development-board/

# Answer
> 1 votes
Relays, motors, and other inductive loads release a surge of reverse current when you remove power from them. You have to connect a suitably sized “flyback diode” across the coil, wired backwards from the normal current flow direction to protect the other devices on the circuit from that reverse current or they will likely be damaged.

Relays and motors also draw a large in-rush of current when they are first connected, which can cause the supply voltage to droop.

You can buy relays that are made to be controlled by logic levels. They take a low power 5V or 3.3V logic level input, plus a separate power supply, and use the logic input to switch the relay on and off safely. The relay modules I’m using have optical isolation for the logic lines for extra protection.

---
Tags: esp8266, programming, arduino-ide, relay, hardware
---


# Question
Title: Will bootloader communicate via TX0 / RX0
I'm fairly new to Arduino programming but have a good deal of experience with low-level programming early processors, having originally cut my teeth on Z80, 8088, etc. I'm looking at developing a sizeable project using a Mega 2560. The project includes quite a lot of off-board logic, leds, and an RPi. Thus I don't want to overload the 2560 voltage regulator and really want to use common rail 5v power with a switch-mode supply. However, I also need debugging / console access, so this gives me the immediate problem of direct 5v driving whilst the board is being driven with 5v from the USB port, which is a no - no. The solution appeared to be fairly simple - use a CH340 - based USB to serial converter and connect it to RX0, TX0 and Reset (DTR output connected via a blocking capacitor) but with its 5v output disconnected. With this setup, the Arduino communicates quite happily with the IDE-based serial monitor (the sketch was downloaded via the on-board usb port), but on trying to download a new sketch via this route, AVRDude fails with a timeout. At the commencement of the download the processor is being reset, but the bootloader doesn't appear to hansdshake with AVRDude (properly). Is this a known feature or have I missed something?

# Answer
> 1 votes
Problem solved. The standalone CH340-based converter for whatever reason isn't man-enough to reliably pull down the RX0 line when connected to the Mega 2560 (also with a CH340 converter on board). I've seen suggestions posted in various places that this can be a problem with respect to DTR (though I don't have a problem with it). My solution is to insert a 7417 open-collector non-inverting buffer between the output of the stand-alone converter and the RX0 input on the 2560 board. I've not been able to find a schematic for the Mega 2560 board to determine its pull-up resistor size but imagine it must be relatively small. Thanks to those who made suggestions.

---
Tags: usb, bootloader, atmega2560
---


# Question
Title: Can I put a T-mobile sim card into the SIM800L Module?
I am trying to connect my SIM800L module to my arduino, but am confused what kinds of sim cards work. My phone currently is an IPhone XS, and I would like to take my tmobile sim card from there and put it into the module. I talked to a tmobile rep and they said my card could handle 2G devices. Would this work? Thanks!

# Answer
> 2 votes
It might work but you'd be better off getting a 2G dedicated card. Hologram.io has a developer card that is $5 and free 1MB / month or something.

---
Tags: gsm
---


# Question
Title: How many PIR Motion Sensors can I connect to my Arduino-Uno R3?
I am doing a school project where I intend to measure the cafeteria line with motion sensors and the send that information with a WiFi module to a server. This is my first time using Arduino and I am not sure how many motion sensors does it support.

# Answer
Most PIR sensors provide a simple relay output. That means they are nothing more than a switch as far as the Arduino is concerned.

You can connect hundreds of switches to an Arduino. With judicious use of diodes and a matrix arrangement you can hundreds with not many IO pins. For example an 8x8 matrix of switches gives you 64 PIR sensors with just 16 IO pins. For *n* pins you can have *(n/2)²* switches with a balanced (*n/2* by *n/2*) matrix.
> 2 votes

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


title: Get image from Fingerprint module

text:
# Question
Title: Get image from Fingerprint module
I want to get the image from the fingerprint module (https://makeradvisor.com/tools/fingerprint-sensor-module/) as a result of scanning. It is enough to have a single frame image. it would be good if the computer can get image the output image from the serial port (as in linescan camera example: https://www.youtube.com/watch?v=welv4w8B88g https://www.tindie.com/products/ap\_tech/tsl1401cl-linescan-camera/)

I am open to your suggestions if it can be done in another module.

# Answer
> 2 votes
Since all of these cheap fingerprint readers are similar you can find a compatible datasheet and just find the commands and descriptions there. However, I couldn't find a datasheet that would include a good description of the protocol. So the other option is to look at the protocot through the software SFGDemo which is apparently capable of getting an image of a fingerprint. Or to use this python package which apparently also can download the image.

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


title: Weather API Arduino

text:
# Question
Title: Weather API Arduino
```
#include <SPI.h>
#include <Ethernet.h>

// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] = {my mac };
char serverName[] = "api.weather.gov";

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

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

  // start the Ethernet connection:
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // no point in carrying on, so do nothing forevermore:
    while(true);
  }
  // give the Ethernet shield a second to initialize:
  delay(1000);
  Serial.println("connecting...");

  // if you get a connection, report back via serial:
  int ret = client.connect(serverName,443);
  if (ret==1) {
    Serial.println("connected");
    // Make a HTTP request:
    client.println("GET /stations/KGSO/observations/latest");
    client.println("accept: application/geo+json,*/*");
    client.println("user-agent: arduino, mymail@asdf.com");
    client.println("host: api.weather.gov");
    client.println();
  }
  else {
    // kf you didn't get a connection to the server:
    Serial.println("connection failed");
    Serial.println(ret);
    Serial.println(client.status());
  }
}

void loop()
{
  // if there are incoming bytes available
  // from the server, read them and print them:

  if (client.available()) {
    Serial.print("\ngotsome\n");
    char c = client.read();
    Serial.print(c);
  }

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

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

```

When I run this I get:

connecting... connected

disconnecting.

Why don't I get data? I thought it was about the header info. But I looked at https://www.weather.gov/documentation/services-web-api#/ and it doesn't say it needs much.

# Answer
The Ethernet library doesn't support secure connection (so called SSL, but TLS now). To connect to a secure HTTP transport HTTPS the secure connection is necessary. The AVR MCU don't have the computing power to compute the security keys. And for less popular 32bit MCU nobody created a 'SSL' implementation for Ethernet library yet.

esp8266, esp32, MKR1010, Uno WiFi, Nano 33 IoT can do HTTPS, but all only over WiFi as far as I know.
> 0 votes

---
Tags: arduino-uno
---


# Question
Title: Multiple serial monitors with the same arduino mega
I’ve got mega 2560. In my project serial port is used for communicating with PC. However, I’d like to see debug info in serial monitor. Mega has a few hardware Serial ports. How to use one of them got extra serial monitor?

# Answer
> 2 votes
Use an USB to TTL Serial adapter. Wire it to one of the RX/TX pin pairs and in code use the corresponding Serial object Serial1, Serial2 or Serial3. Don't forget to wire Ground.

You can use some terminal program or Serial Monitor in Arduino IDE to communicate over the adapter. You can open a second instance of the Arduino IDE by starting it with the Desktop or menu shortcut. In this instance you can select a different port then the sketch upload port.

# Answer
> 0 votes
You need to connect one (or more) to your PC. To do that you would use a USB to TTL UART adaptor, like an FT232 board.

That will give you a new COM port that you can open with your terminal program of choice, though opening the Arduino "serial monitor" multiple times might be somewhat difficult.

---
Tags: serial
---


# Question
Title: Why is this RISING interrupt repeatedly triggering?
I've set up an ISR to trigger on the `RISING` edge of pin #2, but I find that if pin 2 is held high, the ISR triggers repeatedly.

Here's a trace of the voltage measured right at the pin:

I can see a little bit of noise, but it shouldn't be enough to trigger multiple pulses. I've tried both `INPUT` and `INPUT_PULLUP` modes for the pin; behavior is the same.

```
constexpr byte kClockPin = 2;
constexpr byte kReadWritePin = 3;
constexpr byte kLedPin = 13;
constexpr int kNumAddressPins = 16;
constexpr byte kAddressPins[] = {/* MSB */52, 50, 48, 46, 44, 42, 40, 38, 36, 34, 32, 30, 28, 26, 24, 22};
constexpr int kNumDataPins = 8;
constexpr byte kDataPins[] = {/* MSB */45, 43, 41, 39, 37, 35, 33, 31};

volatile bool dirty = false;
volatile uint8_t data = 0;
volatile uint16_t address = 0;
volatile bool read = false;

void setup() {
  // put your setup code here, to run once:
  pinMode(kClockPin, INPUT_PULLUP);
  pinMode(kReadWritePin, INPUT);
  for (byte pin : kAddressPins) {
    pinMode(pin, INPUT);
  }
  for (byte pin : kDataPins) {
    pinMode(pin, INPUT);
  }
  pinMode(kLedPin, OUTPUT);
  Serial.begin(9600);
  attachInterrupt(digitalPinToInterrupt(kClockPin), OnClock, RISING);
}

void loop() {
  // digitalWrite(kLedPin, digitalRead(kClockPin));
  if (!dirty) return;
  char output[15];
  sprintf(output, "%04x %c %02x", address, read ? 'r' : 'w', data);
  Serial.println(output);
  dirty = false;
  // digitalWrite(kLedPin, digitalRead(kClockPin));
}

void OnClock() {
  read = digitalRead(kReadWritePin);
  data = 0;
  for (byte pin : kDataPins) {
    data = (data << 1) + (digitalRead(pin) ? 1 : 0);
  }
  address = 0;
  for (byte pin : kAddressPins) {
    address = (address << 1) + (digitalRead(pin) ? 1 : 0);
  }
  dirty = true;
}

```

# Answer
> 5 votes
Turns out the short answer is that I'm still not great at using an oscilloscope.

Longer version is that the noise was *very* visible at smaller time scales. A filter capacitor had come disconnected from the breadboard in a way that was hard to see, and that was causing a whole bunch of noise. Replacing it fixed the problem.

---
Tags: arduino-mega
---


# Question
Title: Can you make Arduino Uno send information through a WiFi module to a server?
A lot of tutorials are about how to control Arduino through WiFi, but I need my Arduino to send information about motion sensor activity to a server. Is that possible?

# Answer
> Can you make Arduino Uno send information through a WiFi module to a server?

Yes, I can.

The simplest way is through an HTTP "GET" request. Every time you request a web page (and there are plenty of examples of that) you are sending data to the server to tell it both what web page to get (`/foo/bar.php`) and what data to submit to that web page (`?baz=4`).

It's then up to you to craft that GET request, such as:

```
GET /foo/bar.php?baz=4 HTTP/1.1
Host: example.com
Content-length: 0

```

and write the PHP web page (or whatever language you prefer to write web pages in) to do something meaningful with the "baz = 4" parameter.
> 2 votes

---
Tags: arduino-uno, sensors, web-server
---


# Question
Title: How to add another condition in the loop?
I am using mpu6050 for counting the twitch movement. The algorithm is counting the peak/twitch whenever it goes above the threshold value. Now, I want to add that the algorithm count twitch only when it goes above threshold value and all the twitch within 90s are counted as one twitch movement. Kindly help me with this. Also try to integrate this in my code.

**Here is the code:**

```
#include "I2Cdev.h"
#include "MPU6050.h"

#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
    #include "Wire.h"
#endif

MPU6050 accelgyro;

int16_t ax, ay, az;
float threshhold=5000.0;
float conmove=4;
const int sampletime=90000;

float xval[100]={0};
float yval[100]={0};
float zval[100]={0};
float xavg;
float yavg;
float zavg;

int twitch,flag=0;
MPU6050 mpu6050;

int16_t tr;          // raw temperature data register value
char buffer[7];      // temporary string buffer; used with dtostrf() function
#define OUTPUT_READABLE_ACCELGYRO

#define LED_PIN 13
bool blinkState = false;

void setup() {

    // join I2C bus (I2Cdev library doesn't do this automatically)
    #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
        Wire.begin();
    #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
        Fastwire::setup(400, true);
    #endif

    Serial.begin(115200);

    // initialize device
    Serial.println("Initializing I2C devices...");
    accelgyro.initialize();
    mpu6050.initialize();  // initialize MPU6050 sensor module

    // verify connection
    Serial.println("Testing device connections...");
    Serial.println(accelgyro.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");

    pinMode(LED_PIN, OUTPUT);
    calibrate();
    delay(5000);
}

void loop() {

    accelgyro.getAcceleration(&ax, &ay, &az);
    tr = mpu6050.getTemperature();

    #ifdef OUTPUT_READABLE_ACCELGYRO
    +
        // display tab-separated accel/gyro x/y/z values
        Serial.print("a/g:\t");
        Serial.print(ax); Serial.print("\t");
        Serial.print(ay); Serial.print("\t");
        Serial.print(az);
    #endif

    #ifdef OUTPUT_BINARY_ACCELGYRO
        Serial.write((uint8_t)(ax >> 8)); Serial.write((uint8_t)(ax & 0xFF));
        Serial.write((uint8_t)(ay >> 8)); Serial.write((uint8_t)(ay & 0xFF));
        Serial.write((uint8_t)(az >> 8)); Serial.write((uint8_t)(az & 0xFF));
    #endif

    // blink LED to indicate activity
    blinkState = !blinkState;
    digitalWrite(LED_PIN, blinkState);
    int acc=0;
    float totvect[100]={0};
    float totave[100]={0};
    float xaccl[100]={0};
    float yaccl[100]={0};
    float zaccl[100]={0};

    for (int i=0;i<100;i++)
    {
        xaccl[i]=float(ax);
        delay(1);
        yaccl[i]=float(ay);
        delay(1);

        zaccl[i]=float(az);
        delay(1);

        totvect[i] = sqrt(((xaccl[i]-xavg)* (xaccl[i]-xavg))+ ((yaccl[i] - yavg)*(yaccl[i] - yavg)) + ((zval[i] - zavg)*(zval[i] - zavg)));
        totave[i] = (totvect[i] + totvect[i-1]) / 2 ;
        //acc=acc+totave[i];
        Serial.println(totave[i]);
        Serial.print("T = ");  Serial.print(dtostrf(tr/340.0+36.53, 5, 1, buffer));  Serial.println(" °C");

        // delay(200);

        //cal twitch
        if (totave[i]>threshhold && flag==0)
        {
            twitch=twitch+1;
            flag=1;
        }
        else if (totave[i] > threshhold && flag==1 )
        {
            //do nothing
        }
        if (totave[i] <threshhold  && flag==1 )
        {flag=0;}

        Serial.println('\n');
        Serial.print("twitch=");
        Serial.println(twitch);
    }

    //float tim=acc/100;
    //Serial.println(tim);
    delay(1000);
    // stepcal(totave);
}

void calibrate()
{
    digitalWrite(13,HIGH);
    accelgyro.getAcceleration(&ax, &ay, &az);

    float sum=0;
    float sum1=0;
    float sum2=0;

    for (int i=0;i<100;i++)
    {
        xval[i]=float(ax);

        sum=xval[i]+sum;
    }
    delay(100);
    xavg=sum/100.0;

    Serial.println(xavg);

    for (int j=0;j<100;j++)
    {
        yval[j]=float(ay);

        sum1=yval[j]+sum1;
    }
    yavg=sum1/100.0;

    Serial.println(yavg);
    delay(100);
    for (int i=0;i<100;i++)
    {
        zval[i]=float(az);

        sum2=zval[i]+sum2;
    }
    zavg=sum2/100.0;
    delay(100);
    Serial.println(zavg);

    digitalWrite(13,LOW);
}

```

# Answer
You can do this with the `millis()` function. It returns the number of milliseconds since startup and can be used as a simple clock. Take the if statement, where you increment `twitch`:

```
if (totave[i]>threshhold && flag==0)
{
  if(millis()-last_twitch_timestamp > 90000){
    twitch=twitch+1;
    flag=1;
    last_twitch_timestamp = millis();
  }
}

```

This will check, if at least 90 seconds (90000ms) have passed since the last registered twitch (time difference between the current time and the timestamp of the last twitch). If yes, it will register another twitch and reset the timestamp to the current time (return value of `millis()`). This deactivates twitch registering for 90s after each twitch.

For this to work, you need to define the `last_twitch_timestamp` variable at global scope:

```
unsigned long last_twitch_timestamp = 90000;

```

I initialize the timestamp to 90000, so that the very first twitch can be registered. If you initialize it to zero, you would need to wait 90s, until the first twitch can be registered.

---

Btw: The following delays don't make any sense. You can remove them:

```
xaccl[i]=float(ax);
delay(1);
yaccl[i]=float(ay);
delay(1);

zaccl[i]=float(az);
delay(1);

```

And you should really really keep all lines indented correctly. The Arduino IDE has an autoformat feature to make it simpler for you.
> 0 votes

---
Tags: arduino-uno, mpu6050
---


# Question
Title: Latest news about alternative Arduino IDEs
I simply hate the default Arduino "IDE". On Windows I use Visual Studio Code with the related plugin.

Now I have a Ubuntu machine and I'm looking for the definitive IDE. Questions:

1. I'm not sure whether to use VSC I need to install the default IDE as well
2. is there something better?

By the way, I also have QtCreator, PHPStorm, MPLAB X, STM32Cube (Eclipse based).

# Answer
I use the Arduino IDE to 'build' everything.

However, in case of a bigger project, I use a 'decent' code editor (Visual Studio in my case) to edit, and the Arduino IDE to build.

Also, because I prefer testing all non-Arduino related code on the PC (not on the Arduino), the Visual Studio (C++) project uses some stub classes I created (specifically for my project), and I can run the application on my PC.

When some part is finished, I can build the same code in Arduino IDE, but without the stubs (because these are acquired from Arduino.h and related Arduino files).

What IDE is best to 'edit' code is very subjective I think. But in the above way I can see many classes/files at a glance on the left side (and not in the top like Arduino IDE where only like 5 tabs fit on a screen), and to test lots of code on the PC already before sending it to an Arduino.

The GitHub repository can be found here: https://github.com/michelkeijzers/Mestra

Project inside is DmxLightShow.
> 1 votes

# Answer
Arduino creators toughed of you. Personally I use Geany, but you can use eclipse, but I find the Arduino plugin rather hostile, especially when it comes to editing default libraries (to add printf) and pointlessly complex serial monitor settings default above the NANO's range. Although its missing testing feature without upload
Although most other editors would be quite happy with arduinos file too, but you have to always create new project with native IDE. You will find use external editor feature in Arduino-ide's settings in which case every time file is saved it gets immediately updated in Arduino's IDE, so you can use it for your tasting as a sub-window.
> 0 votes

---
Tags: arduino-ide, ide, linux, visualstudio
---


# Question
Title: How to get more than the 16 Analog INs on a Arduino Mega for using like 24 piezo sensors
i bought an Arduino Mega2560 and flashed it with usbmidi. So now it comes up as a midi device.

I need more than those 16 analog ins to be able to put all my 24 piezo sensors into it to receive midi signals from it. I still have no idea how i have to put the piezo pieces into the arduino but also no clue as how to get more than those 16 analog slots. Any way to use the digital inputs as well or do i need some extension shield or so? I'm a total beginner with arduino...

# Answer
You can customize a controllino on their page
https://www.controllino.biz/controllino-myplc/
I just looked at it and it seems you can get 24 analog outputs.

Don't know what the cost is though.
> 1 votes

# Answer
You need one (or more) external ADC (analog digital converters).

For example the ADS1115, the link shows an Adafruit model and how to use it.

In a DIP format (to be used on breadboards/prototype boards) it will be hard to find a 16 channel ADC, but you can add multiple I2C (or other) 4 channel ADCs to one Arduino Mega.
> 0 votes

---
Tags: arduino-mega, midi, multiplexer
---


title: Set slide potentiometer values

text:
# Question
Title: Set slide potentiometer values
I am using the Grove - Slide Potentiometer (http://wiki.seeedstudio.com/Grove-Slide\_Potentiometer). How can I set the potValue so that at maximum it will 128?

```
int potPin= A0;
int readValue;
int potValue;

void setup() {
  pinMode(potPin, INPUT);
  Serial.begin(9600);
}

void loop() {
 readValue = analogRead(potPin);
 potValue = (255./500.) * readValue;
 Serial.print("You are writing a value of ");
 Serial.println(potValue);
}

```

# Answer
You can use the `map` function, see https://www.arduino.cc/reference/en/language/functions/math/map/.

Example: If your pot meter gives values from 100 to 1000 and you want to map that range to a range of 0 to 128 you can easily write:

```
potValue = map(readValue, 100, 1000, 0, 128);

```

High likely, in your case and if the potentiometer is 'perfect' it returns values from 0 to 1023 and you can write:

```
potValue = map(readValue, 0, 1023, 0, 128);

```
> 2 votes

# Answer
analogRead() returns 0x0000 to 0x03ff

If the max data 0x03ff is shifted to the right by 3 bits (or divide by 8), then 0x03ff becomes 0x007f, or 127.

I think this will do it:

```
desiredMax = analogRead(A0) >> 3; // divide 1023 max by 8, becomes 127 max

```
> 3 votes

---
Tags: programming, potentiometer
---


# Question
Title: Servo can be moved only in steps of couple degree
I have Feetech FS5323M servo, with Sweep example code from Arduino site, it works fine, it rotates from 0 to 180 degree and back as expected.

The problem comes when I try to set servo position. I've added a simple `servo.write(90);` in setup, to reset servo position, but it didn't work (`writeMicroseconds(1500);` also failed).

After digging a little bit, I've discovered that I can rotate the servo only by a couple of degrees from its current physical position.

If the servo is at 140 degrees, I can move it back and forth only up to 7 degrees, value bigger than this will result in servo staying at its current position. So if I want to move it to 180 degrees I have to make a loop and go to this position in steps of 1-7 degrees (with delay = 15 * degree).

I attached external 2A power to the circuit and connected the grounds. It didn't solve the problem. The circuit is very simple, just servo connected to pin 3, without anything else. I also tried to add a 300uF capacitor between power and ground.

**Edit 1:** I've tested pin 9 and 10 and the same happens. Sadly I have no way to test it on any other board because I have only one, same goes for the servo. I uploaded sweep example with the step size of 10, the servo didn't move or even twitched. I tried it both with a delay of 15 as well as 150.

**Edit 2:** I've tested the program with only one `servo.write(90);` statement, but the issue hasn't been resolved. I tried it in setup and later in loop, in both programs there was only one `write` statement.

# Answer
> The problem comes when I try to set servo position. I've added a simple servo.write(90); in setup, to reset servo position, but it didn't work

Understand that the method "setup()" in the Arduino paradigm is only run once after power up or reset. Any code in "setup()" which positions the servo will immediately get over written by the code that positions the servo in the "loop()" method. Likely this happens so quickly that the servo will not even react to the line "servo.write(90);".
> 0 votes

# Answer
Your servo should be powered separately from the Arduino as it draws 150mA just running and its stall current is well over an amp, according to the specs on this page. If you're powering it from the Arduino, it is quite likely that it drags the Arduino's supply voltage down enough to shut down the processor, but you may be getting away with it for very short moves.
> 0 votes

---
Tags: servo
---


# Question
Title: Daisy chaining of multiple blocs of 4x(8x8) MAX7219 matrix
Thanks for your presentation https://arduino.stackexchange.com/tags/max7219/info. You say that multiple MAX7219 8x8 blocs can easily be daisy-chained and you show an example of at least 12 blocs displaying "Testing12345". Trying several programs I found for Arduino, I never succeeded to chain more than 8 blocs with 8x8 matrix (either 8 individual blocs or 2 groups of 4 as on your image). So I'ld be very happy if you send me examples of programs managing more than 8 blocs for fixed or scrolling displays. Many thanks in advance.

# Answer
> 0 votes
Try using @Majenko 's MAX libary https://github.com/MajicDesigns/MD\_MAX72XX . It allows you to specify how many modules are to be addressed.

# Answer
> 1 votes
All is OK changing the proposed statement

# define HARDWARE\_TYPE MD\_MAX72XX::PAROLA\_HW

to

# define HARDWARE\_TYPE MD\_MAX72XX::FC16\_HW

---
Tags: arduino-uno, max7219
---