# Question
Title: Leonardo keypresses not working with OBS
I am using an Arduino Leonardo to have hotkeys for OBS but they don't work when the OBS Studio window is not focused.

I have the Leonardo press Ctrl + Alt + Shift + F7 when I press a button connected to the Leonardo. On OBS I have Ctrl + Alt + Shift + F7 switch to a slide. When I have the OBS window focused and I press the button it works fine. But when I have another application focused it does not work. The strange thing is, is that when I press (on my keyboard) Ctrl + Alt + Shift + F7, it will switch to the slide, but when I press the button it does not work.

I am running OBS as an Administrator btw.

My code for the Leonardo is below

```
int pinA = 8;

void setup() {
    pinMode(pinA, INPUT);
}

void loop(){
digitalWrite(pinA, HIGH);
readPinA = digitalRead(pinA);
if (readPinA == 0){
    Serial.print("A\n");
    Keyboard.press(KEY_RIGHT_CTRL);
    Keyboard.press(KEY_RIGHT_ALT);
    Keyboard.press(KEY_RIGHT_SHIFT);
    Keyboard.press(KEY_F7);
    Keyboard.releaseAll();
    delay(250);
    }
}

```

# Answer
*Warning: the below is all supposition.*

When the OBS window is focused the OS can send keyboard events to the window. That means that it gets "The button has been pressed" messages. These are generated when the "press" events are sent from the Leonardo.

When the OBS window *isn't* focused it can't be sent those messages - so it has to manually poll the state of the keyboard to see what buttons are pressed at any one time. It can't be doing this *all* the time, so it does it periodically (but still pretty fast).

The knock-on effect is, though, that when not focused it can only see buttons that have been pressed for at least enough time for it to poll the state.

If you add a delay into your routine between the last "press" and the "release all" commands that is longer than the period between polling (no idea what that is - you'll have to experiment, but starting at around 50ms to 100ms should be adequate) you should give OBS enough time to see that the buttons are pressed before you then release them.
> 1 votes

---
Tags: arduino-leonardo
---


title: What is this potentiometer for?

text:
# Question
Title: What is this potentiometer for?
I am working on an anemometer project using Arduino. I don't know barely anything from Arduino and I am following this tutorial.

I have some doubts on the making part. This is what I have to make:

and this is the code:

```
//anemómetro con LCD
#include <LiquidCrystal.h>

LiquidCrystal lcd(7, 8, 9, 10, 11, 12);

float veloc1 = 0; // entrada A0
int tiempo = 0;
int cnt = 0;
float v1 = 0;
float v2 = 0;

void setup() {
  lcd.begin(16, 2); // Fijamos el numero de caracteres y filas
  lcd.begin(16, 2); // Fijamos el numero de caracteres y filas
  lcd.print("Anemometro EC"); // Aqui va el mensaje
  analogReference(INTERNAL);// pone como referencia interna 1.1V
}

void loop() {
  v1 = (analogRead(0)); // lectura de sensor a0
  veloc1 = (v1 * 0.190); // 0,190 corresponde a la pendiente de la curva aca deben poner el numero que calcularon
  lcd.setCursor(0, 1); // Ponte en la line 1, posicion 0
  lcd.print(veloc1); //muestra la velocidad del viento en el LCD
  lcd.setCursor(4, 1); // ponte en linea 1, posicion 5
  lcd.print("Km / h");
  lcd.setCursor(9, 1);
  lcd.print("Max");
  if (veloc1 > v2)v2 = veloc1, lcd.print (v2, 1); // muestra la velocidad maxima que alcanzo
  delay(1000);
}

```
1. What is the potentiometer doing here? Why is it necessary?
2. My lcd screen doesn't show anything. Does anyone knows why??

Thanks in advance.

# Answer
> 2 votes
> What is the potentiometer doing here? Why is it necessary?

It's there to control the "offset voltage" of the LCD, which is what controls the contrast of the display.

> My lcd screen doesn't show anything. Does anyone knows why??

Maybe you wired it wrong. Maybe you didn't put the potentiometer in the circuit because you didn't understand what it is for. Maybe you just need to adjust the contrast by turning said potentiometer. It's hard for us to tell. By showing us what you *intended* to build and then telling us that what you *actually* built doesn't work, there is nothing we can tell you. There must be some difference between what you intended to build and what you did build, but we can't see what you built, so we can't have any clue.

---
Tags: potentiometer, project
---


# Question
Title: 7segment display on Multi Function shield - Arduino Uno
I’ve bought this shield. I’m looking for a way to display decimal point, without using any a designated library. Most examples as this one shows only 0-9.

**EDIT1** update link Link

# Answer
> 1 votes
So if you click your 2nd link, it includes sample code for various sections of the multi-function shield.

One of them is titled "segment display".

If you look at that code, line 7 defines the bit patterns for each of the digits from 0 to 9:

```
const byte SEGMENT_MAP[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0X80,0X90};

```

If you map them out in binary, you get:

```
0xC0,   1100 0000   0
0xF9,   1111 1001   1
0xA4,   1010 0100   2
0xB0,   1011 0000   3
0x99,   1001 1001   4
0x92,   1001 0010   5
0x82,   1000 0010   6
0xF8,   1111 1000   7
0X80,   1000 0000   8
0X90    1001 0000   9

```

A 0 character has all the segments lit except the middle "cross-bar". An 8 character has ALL of the segments lit. But the bit pattern for 8 is `1000 0000`. That suggests that a 0 bit means a segment is lit, and 1 means it is off. Since the highest order bit of all of those characters is 1 (off) it suggests that the high-order bit is the decimal place bit. (It's the only bit that never changes.)

So if you replace

```
const byte SEGMENT_MAP[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0X80,0X90};

```

with

```
const byte SEGMENT_MAP[] = {0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0X00,0X10};

```

You should get all the digits drawn with their corresponding decimal place lit.

I'd try that first to verify that I'm correct.

I'd then suggest writing code that reads the segments value for each digit, decides if you want a decimal place at that position, and if so, doing a bitwise AND (`&` in C/C++) on the value with 0X7F to clear the decimal bit for that character. (Remember it looks like a 0 means a given LED segment should be lit.

You could modify the function WriteNumberToSegment() to take a "lightDot" parameter, and have it change the bit if you pass TRUE (1):

```
void WriteNumberToSegment(byte Segment, byte Value, bool lightDot)
{
    digitalWrite(LATCH_DIO,LOW);
    bool bits = SEGMENT_MAP[Value]);
    if (lightDot) {
       bits &= 0x7F; //To light the decimal for this digit, clear the 0x80 bit
    }
    shiftOut(DATA_DIO, CLK_DIO, MSBFIRST, bits);
    shiftOut(DATA_DIO, CLK_DIO, MSBFIRST, SEGMENT_SELECT[Segment] );
    digitalWrite(LATCH_DIO,HIGH);
}

```

(I don't remember for sure if `bool` is a valid type in Arduino C/C++. If not, just replace `bool` with `uint8` in the above.)

---
Tags: arduino-uno, shields
---


# Question
Title: Lighting LED with Arduino Uno from PC keyboard
I tried to turn on a LED with my PC keyboard and an Arduino Uno with the letter A.
I get the message

> exit status 1
> 'keypressed' was not declared in this scope

My code:

```
int led1 = 10;

void setup()
{

pinMode(led1, OUTPUT);
}
void loop()
{

 if(keypressed == 'a'){
               digitalWrite(led1, HIGH);
               delay(500);
}
}

```

What is the problem?

# Answer
> 2 votes
Firstly, you can't just make up the term "keypressed" because the programming language is unable to understand it (unless you assign it as a variable but it's purpose then would just be to store and retrieve values). Secondly the arduino itself is unable to detect keystrokes from the computer by itself. It needs a program on the computer to be able to detect keystrokes from the keyboard then send it to the arduino.

So how would one do this?

Assuming you use Windows, learn Python (A not-so-hard programming language on the computer), then look up the msvcrt library and from there learn how to get key strokes (this only works if you are currently selecting the running program). Then in arduino and python, learn how to use serial. For Python, you need to download this library and learn how to use it. For Arduino it's already in there you just have to learn how to use it. Then you can do the rest and make it turn on your LED.

I hope this helps.

# Answer
> 0 votes
Here you declared keypressed as a variable, so you need to assign an input to it using

'keypressed = serial.read()' without quotes before if statement in void loop. Note make make use of serial monitor for input and also assign 'serial.begin(9600)' without quotes in void setup function before pinmode statement.

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


# Question
Title: Arduino Uno and FastLED WS2812B Glitching
I’m using an Arduino Uno and a fastLed WS2812B. I have the leds set up correctly. Every 2 seconds, the lights pause of about a second and display seemingly random colors.

Does anyone know what's wrong?

My code:

```
#include <FastLED.h>

#define LED_PIN   7
#define NUM_LEDS  10

CRGB leds[NUM_LEDS];

void setup() {
  FastLED.addLeds<WS2812, LED_PIN, GRB>(leds, NUM_LEDS);

}

void loop() {
  for (int i = 0; i < NUM_LEDS; i++){
    leds[i] = CRGB(0,0,255);
    FastLED.show();
    delay(100);
  }
  for (int i = 0; i < NUM_LEDS; i++){
    leds[i] = CRGB(255,0,0);
    FastLED.show();
    delay(100);
  }
}

```

# Answer
I have run the code on the Arduino simulator online. If it is working in the Arduino Simulator **chances are less that it has to do something with the code itself**.

Hence, also as the root cause was found to be about sharing the ground @Majenko

This is also one example of solving the problem step by step. validating one section after the other. using the simulator you can verify that the code is working fine. later, proceed to verify the hardware. I hope this helps.

You can verify the FastLED code here (you can modify the parameters)
> -1 votes

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


# Question
Title: Communication between ESP01 Arduino NANO and using External Interrupt in Arduino NANO for other than communication program same time
I have done communication between ESP01 and Arduino NANO (ATMEGA328 based). ESP pins used are GPIO-0 and GPIO2. In NANO, used D2 and D3. This program working Ok. Now I want to add external interrupt in my Arduino NANO program while continuing communication with ESP01. But I cannot use D2 and D3 because it was used by communication program. Now Arduino NANO's limit is it has only two interrupt pins which are D2 and D3. So if I use this for external interrupt program, I lose communication with ESP01. Can anybody help me to use my both task at the same time: Task1- External interrupt in Arduino Nano, Task2- Communication with ESP01. Your reply will help me to solve this issue. Thanks in advance.

# Answer
> 2 votes
D2 and D3 Pins on Arduino nano support external Interrupt. Hence, you have to use one of those for the interrupt.

Since you are using `softwareSerial()` you can easily remap it to other digital pins of the Nano.

Pins from `D4-D12`can be used for communication. You just have to change the parameters in the `softwareserial()` as below:

```
SoftwareSerial mySerial(4, 5); // RX, TX;;for example

```

---
Tags: arduino-nano
---


# Question
Title: parallel communication simulation problem
Hi I am trying to send data(1 byte) from one arduino to another using parallel communication(a bus of 8 connections) and not using any library. However, the problem is the data gets corrupt all the time and what I am supposed to receive at receiver arduino is not what I send. The protocol that I made up is similar to uart protocol. There is ES pin and when it is low, transmission is started and when it is high, the transmission is ended. I think the problem could be related to wires that I use to connect two arduinos. There could be some noise induced that could flip bits in wires or the code is problematic. I am posting my code. Maybe you can help me get through this and help me to resolve my problem.

Sender code:

```
#define ES 8 //enable sampling
#define B0 0 //Bus 0
#define B1 1
#define B2 2
#define B3 3
#define B4 4
#define B5 5
#define B6 6
#define B7 7
const char dataToBeSent = 'C';
bool data_bit;

void setup() {
  pinMode(ES,OUTPUT);
  pinMode(B0,OUTPUT);
  pinMode(B1,OUTPUT);
  pinMode(B2,OUTPUT);
  pinMode(B3,OUTPUT);
  pinMode(B4,OUTPUT);
  pinMode(B5,OUTPUT);
  pinMode(B6,OUTPUT);
  pinMode(B7,OUTPUT);
  digitalWrite(ES,HIGH);
  delay(3000);
}
void loop() {

 digitalWrite(ES,LOW); //transmission is started
 delay(10);

 for(int i = 0 ; i<8 ; i++){
    data_bit = dataToBeSent & (0x80 >> i);
    digitalWrite(i,data_bit);
 }
  delay(10);
  digitalWrite(ES,HIGH); //end transmission
  while(true){}
}

```

Receiver code:

```
#define ES 8 //enable sampling
#define B0 0 //Bus 0
#define B1 1
#define B2 2
#define B3 3
#define B4 4
#define B5 5
#define B6 6
#define B7 7

char rx_data;
byte rx_byte= 0;
bool rx_pin;

void setup() {
  Serial.begin(9600);
  pinMode(ES,INPUT);
  pinMode(B0,INPUT);
  pinMode(B1,INPUT);
  pinMode(B2,INPUT);
  pinMode(B3,INPUT);
  pinMode(B4,INPUT);
  pinMode(B5,INPUT);
  pinMode(B6,INPUT);
  pinMode(B7,INPUT);
  delay(1000);

}

void loop() {

  byte rx_byte= 0;

  while(digitalRead(ES) == HIGH){}
  delay(15);

  for(int i = 0 ; i<8 ; i++){
    rx_pin = digitalRead(i);
    Serial.print(rx_pin);
    if(rx_pin == 1){
      rx_byte |= (0x80 >> i);
    }
  }

 rx_data = rx_byte ;

 Serial.print("Received data: ");
 Serial.println(rx_data);

 delay(15);

 while(digitalRead(ES)== HIGH){}

}

```

# Answer
> 0 votes
You problem is that you are only using one phase of your "ES" clock, when in fact you should be using two.

In the first phase, where ES is high, is where you set the IO pins to represent your transmitted byte. Only once that is done can you then progress to the second phase, where ES is low, to indicate to the receiver that "I have set up my outputs, it's now time for you to read them".

So your transmitted code would flow like:

1. Set ES HIGH
2. Set output pins to represent the byte
3. Set ES LOW
4. Delay
5. Set ES HIGH

If you look at any timing diagrams for any protocol there will be places where the data is being written to the bus, and places where the data is considered stable and able to be read by the receiver. It's the job of the clock signal to indicate where these points in the protocol - to *synchronise* the receiver.

For example, here is the Centronics (parallel port) protocol:

The data changes while nStrobe is HIGH, and only when that data is "settled" is nStrobe brought LOW to tell the receiver it can read the data. Once nStrobe is taken HIGH again the data is changed to the next byte to transmit.

---
Tags: communication
---


# Question
Title: Using Two Arduino to Lower Power Consumption
I am planning to build a water quality sensor with ph, temperature, and dissolved oxygen, conductivity. The power consumption looks like it will be very high especially due to the signal isolator, I'm estimating about 250mA. I'm going to place it in a remote area so I need it to be as power-efficient as possible.

I was thinking would this work?

What if I use two Arduino to control the power? The first Arduino will control the power supply to second Arduino, which has the sensor installed, using a timer(RTC) to turn off the power for 30 minutes and on for 30 seconds for it to read the sensor data.

Can this work? What would the circuit look like?

For the isolator, I was thinking to use Tentacle Shield and in the documentation, it says that the isolator itself uses about 150mA plus the sensor circuit. https://www.whiteboxes.ch/docs/tentacle/t1/#/

Thanks for the help.

# Answer
> 2 votes
I would do as follows:

Software:

* Arduino is in sleep mode
* every x seconds (x depending on your needs), wake up then switch on and read one sensor after the other and transmit the results or whatever you want to do.
* then go back to sleep

Hardware:

* as you have 4 sensors, you can connect their outputs to the arduino analog inputs (or digital...)
* you will need 4 electronic switches, preferably Mosfets, connected to 4 digital outputs to switch the power of each sensor independently

This should reduce the consumption to the minimum.

Once your system is running, you may also think about using only the AVR microchip, not the complete Arduino, e.g. If you don't need the USB connection. In addition, you can further reduce consumption by clocking the AVR chip to a lower clock, if not using Arduino.

# Answer
> 2 votes
In fact, for a project like this, you should use two Arduinos, one as SLAVE and the other as MASTER.

You mentioned 4 sensors for measuring water quality, but you will have more modules such as RTC and MicroSD to store the data. So, I think you should use Slave to colect the data from sensors using the Tentacle Shield, and the other Arduino as Master, to MANAGE other modules and the SLAVE.

For this, you can setup the communication between using I2C protocol. For my Major Qualifying Project, I presented a full prototype for *Remote Surface Water Parameter Plataform Sensor*, using both Arduino Uno (SLAVE) and Mega (MASTER). For power supply, I have used 12V 8A motorcycle battery.

All the data captured by the sensors, were stored locally by SDModulo and sent by a SIM module to a RaspberryPi server.

For low power consumption, you should DeepSleep mode for the Arduinos. You can setup this mode using the RTC module. Arduino LowPowerDeepSleep.

For the circuit, I think you will be fine if you use the Tentacle Shield. It's already done.

# Answer
> 0 votes
Actually, you can just run 1 Arduino and use it for

* All needed measurements
* Control power supply to sensors (power off when unneeded)
* Additional: use low-power modes of MCU installed in Arduino

**Upd:** About 2nd option: You can use electric relay or transistor to control power supply to sensor. Often sensors have several connections: ground (-), Vin(+) and some signal connections. So between power supply and Vin(+) of sensor you can put electric relay. Control pin of electric relay connect to any free pin on Arduino. Therefore, Arduino can enable and disable power supply to sensor just by settings 1 or 0 to that pin. I recommend you to use electric relay, because it is easier, but if you want to try transistor, you can refer to this question & answers: https://electronics.stackexchange.com/questions/95089/switching-9v-using-a-npn-transistor-and-an-arduino

About 3rd option: Arduinos are based on some MCU (often AVR, not always). These MCUs have several low-power modes. You can directly control power mode of MCU to achieve better power-efficiency.

So, you can do 1st and 2nd options, and try to do the 3rd one:

* Investigate which MCU installed in your Arduino
* Investigate which power modes it supports
* Implement power management according to datasheet of this MCU

For example, if you have Arduino Mega 2560, then it is based on ATmega2560 MCU, find datasheet (https://ww1.microchip.com/downloads/en/devicedoc/atmel-2549-8-bit-avr-microcontroller-atmega640-1280-1281-2560-2561\_datasheet.pdf) and there find info about power/sleep modes (page 50) and ways to "wake up" from these modes.

Also you can read about it here: https://microchipdeveloper.com/8avr:avrsleep

Also you can try to find some handy libraries for Arduino, for example "Low-Power" and just use them without diving into MCUs, datasheets, etc

---
Tags: arduino-ide, power
---


# Question
Title: Arduino respond to input from HT12D data output
Is there a way to connect a data output pin from an HT12D to an Arduino or ESP8266-12e input pin, then sense when the data pin is activated so I can have the Arduino or ESP8266-12e do something like turn on an output pin?

# Answer
I am afraid I could not understand your question properly. But maybe, the answer is YES, if ...

First of all, OUTPUT pins, cannot be turned ON and turned OFF, however, you can start or stop READING that particular OUTPUT PIN based on another INPUT pin value.

If you want to connect HT12D decoder to any arduino or ESP, you must be aware to use same voltage level between IO PINS, a good approach is to use a I2C bi-directional level shifter.

```
if(INPUT_PIN_VALUE >= SOME_VALUE)
{
   digitalRead(PIN)
}

```
> 1 votes

# Answer
Disclaimer: In this answer I'm using ESP and Arduino interchangeably, as if they were the same. They are in context this question, but not in general.

First: According to the datasheet of the HT12D, the supply voltage can be between 2.4V and 12V, so you could just provide it with the 3.3V of your ESP. That way the output pins will also run on 3.3V. Then you can simply run a wire each from an output of the chip to a digital input pin of the Arduino.

Though you then should also provide your receiver chip with 3.3V. If that is not possible, you can provide the HT12D with 5V and use simple voltage dividers on each output to break the voltage down to 3.3V. That places restrictions on the transmission speed, but I don't think, that this is relevant here, as the outputs are more meant as momentary state outputs, not data transmission outputs. In that case you connect the output of the voltage dividers to one digital input pin on the Arduino each.

**How to read the data:**

The chip will read the data from the receiver on its Din pin. When it has found a valid transmission for the used address (which is configured through the address pins), then it will pull the VT pin to HIGH and output the new data on the pins. The datasheet says:

> The HT12D, on the other hand, provides 4latch type data pins whose data remain unchanged until new data are received.

Let's imagine, that you have send the pattern `HIGH, LOW, HIGH, LOW`. The HT12D will see this as valid data and set it's outputs to this pattern. The VT pin is pulled high to show, that new valid data arrived. Now you can read this pattern into the Arduino via multiple `digitalRead()` calls, one for each output pin of the HT12D.

The surrounding code depends on your needs. For example you could just read the pins continuously again and again, every time just outputting corresponding on the data. For example like this:

```
void loop(){
    if(digitalRead(HT12D_pin1)) digitalWrite(LED_pin, HIGH);
}

```

Or even easier:

```
void loop(){
     digitalWrite(LED_pin, digitalRead(HT12D_pin1));
}

```

Or you could also read the VT pin of the HT12D and only do something, if it is HIGH. That way you only act, if there is valid data received.

---

For more info you really need to improve your question.
> 0 votes

---
Tags: esp8266, arduino-pro-mini, rf
---


# Question
Title: Programming Arduino Uno R3 to trigger a relay once every 24 hours
I programmed an Arduino Uno R3 to trigger a relay once every 24 hours from the moment it is powered on.

I calculated milliseconds and used the function `delay()`.

24 hours * 60 minutes each hour * 60 second every minute * 1000 milliseconds every second

so I used :

```
delay(86400000)

```

for 86 million and 400 thousands milliseconds.

Currently, I'm still testing it...

Will this work? If not, is there a better built-in function/library or even external library to do it?

The relay trigger doesn't have to be very accurate at the very exact time each day.

I don't need it to be very accurate, it can shift few minutes every few months or so, thats okay with me.

But how about after few months or years of use ? Will it shift the timing much?

I read somewhere about using `millis()` function and others use an RTC (Real Time Clock) module.

I don't want to use anRTC module, I am looking for a programmatical solution.

OR will my previous method using `delay()` work for such a very high number of milliseconds?

# Answer
> 4 votes
Yes, the delay() will work, as will other methods based on the millis() counter. However, delay() will make it impossible to do something else in the meantime.

Look up Blink without delay for an example of how to accomplish such a delay while being able to do other things in your code while waiting.

**Casting**

When dealing with large numbers such as your 24-hour delay, make sure to explicitly cast those numbers as `unsigned long`, or expressing them with the "UL" extension (like for example `86400000UL`). This explicitly tells C++ to expect an "unsigned long" (which in Arduino Uno terms is a 32-bit unsigned number).

In your case (with such an obviously large number), the compiler will automatically choose the right type. In other cases (for example, if you change the expression to `24*60*60*1000`), the compiler will not automatically generate an unsigned long and you need to force it by changing the first part of the expression to an unsigned long: `24UL*60*60*1000` or, alternatively `(unsigned long) 24*60*60*1000`.

**Accuracy**

The accuracy of the timing will be dependent on the type of oscillator on your particular Arduino board. Many Arduinos or their clones use a Ceramic Oscillator that generally have an accuracy of about 0.1 to 0.5%, meaning a possible deviation of 43 seconds per day and as such maybe too inaccurate for your purposes. If your Arduino has a Crystal oscillator, it will be much more accurate (to something like 150ppm, meaning a maximum deviation of about 1 second per day under normal conditions).

# Answer
> 3 votes
`delay()` takes an unsigned long; I think what you do will work.

When in doubt, you could always do something like this:

```
for (int hours = 0; hours < 24; hours++) {
  for (int mins = 0; mins < 60; mins++) {
    for (int secs = 0; secs < 60; secs++) {
      delay(1000);
    }
  }
}

```

It will be wildly inaccurate though, because the clock is inaccurate and will also drift with temperature, made worse because a resonator is used instead of a crystal.

You will get nowhere near an accuracy of a few minutes per month this way, whatever "delaying" method you use; the hardware isn't up to it.

# Answer
> 1 votes
You could try enclosing the Uno in a temperature controlled "oven", say a plastic enclosure with a very low power heater (even a suitable resistor might do) and thermo sensor in with it. It should reduce some of the variation in the crystal frequency.

---
Tags: arduino-uno, programming, arduino-ide, library, timers
---


# Question
Title: Sparkfun OBDII - Arduino Uno Stuck at 832RPM-13Kmh
I'm working on a hobby project with Sparkfun OBDII UART + Arduino Uno + 16x2 LCD Screen, i'm trying to read my car's RPM-Speed-Coolant Temprature-Oxy Sensor on runtime.

Product Page

Wired OBDII to Arduino as: OBD TX -\> ARDUINO RX OBD RX-\> ARDUINO TX OBD GND -\> ARDUINO GND

As far as i understand OBDII board does all the job and it's just communicating with arduino through serial, they provided an example here : Hookup Guide

I don't have sparkfun serial lcd, so i've changed codes according to my lcd as follow;

```
#include <SoftwareSerial.h>
#include "DFRobot_RGBLCD.h"
const int colorR = 255;
const int colorG = 0;
const int colorB = 0;
DFRobot_RGBLCD lcd(16,2);  //16 characters and 2 lines of show
char rxData[20];
char rxIndex=0;
int vehicleSpeed=0;
int vehicleRPM=0;
void setup()
{
lcd.init();
lcd.setRGB(colorR, colorG, colorB);
Serial.begin(9600);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Hiz: ");
lcd.setCursor(0,1);
lcd.print("Devir: ");
delay(1500);
Serial.println("ATZ");
delay(2000);
Serial.flush();
}

void loop()
{
Serial.println("010D");
getResponse();
getResponse();
vehicleSpeed = strtol(&rxData[6],0,16);
lcd.setCursor(4,0);
lcd.print(vehicleSpeed);
lcd.print(" km/h");
delay(100);
Serial.flush();
Serial.println("010C");
getResponse();
getResponse();
vehicleRPM = ((strtol(&rxData[6],0,16)*256)+strtol(&rxData[9],0,16))/4;
lcd.setCursor(6,1);
lcd.print(vehicleRPM);
delay(100);
}
void getResponse(void){
  char inChar=0;
  while(inChar != '\r'){
    if(Serial.available() > 0){
      if(Serial.peek() == '\r'){
        inChar=Serial.read();
        rxData[rxIndex]='\0';
        rxIndex=0;
      }
      else{
        inChar = Serial.read();
        rxData[rxIndex++]=inChar;
      }
    }
  }
}

```

with above code i believe arduino receives last rpm and speed record before i shut down the engine which is 832RPM - 13 Kmh (at this point i'm not sure if arduino receive speed value correctly because when i shut down the engine i was parked the car and speed was 0kmh), in normal case when i start the car rpm and speed value should have changed but even after started the car the value stands still,it's not changing.

I bought waveshare's USB FTDI(TTL) adapter to figure it out is this board communicate with car or pc properly, connected usb ttl as; OBD TX -\> TTL RX OBD RX-\> TTL TX OBD GND -\> TTL GND

connected to OBDII port of my car, opened tera term, connected to COM20 (ttl defined as com20 on the pc) and run below commands as suggested in their manual;

```
ATZ -- resetted card successfully
ATRV -- returned 12.4 V as it should be, which is my battery voltage
ATSP0 -- auto find and select car's protocol it returned OK
010C -- RPM of the car it returned 41 0C 00 00 (engine wasn't started)
010C -- RPM of the car it returned 41 0C 10 F4 (engine started--idle RPM arround 1.000 rpm)
010D -- speed of the car it returned 41 00 00
010D -- speed of the car it returned 41 00 00 both value is the same because the car is not moving :)

```

According to above outcome the board is fine and communicating with car or pc or arduino without any problem.

But when i try with arduino when i connect the board to my car and turn my ignition to battery mode it reads rpm as 832 and speed as 13 and don't update those values even i start the engine.

What am i doing wrong?

# Answer
> 1 votes
after 1 week of try i finally solved it :)

As you guys know UNO has 1 i/o serial port, and Sparkfun's OBDII board doesn't work on same i/o serial port (at least i couldn't be able to), with uno when you send a command through serial to obd board you need to wait minimum 3 seconds to send another command or car's can-bus thinks that you canceled the first command returns STOPPED error, but with MEGA it works perfectly because mega has 3 i/o serial ports. You simply define Serial(TX)-Serial1(RX) and it works perfectly with 75ms delay.

Here is the working code.

```
//Set up ring buffer
char rxData[20];
char rxIndex = 0;
int rpmstored = 0;

    void setup()
    {
      Serial.begin(9600); // prints to serial monitor
      Serial1.begin(9600); //Hardware serial connection to the obdii uart
      OBD_init(); //initiates obd link
      delay(3000);
    }

    void loop()
{
rpmstored = getRPM();
//int mph = (int)((getSPEED() * 10000L + 5) / 16090); //convert to mph
//  Serial.print (mph);
Serial.print("S:");
Serial.print (getSPEED());
Serial.print (",");
Serial.print("R:");
Serial.println (getRPM());
//Serial.print (",");
//Serial.print("W:");
//Serial.print (getWATERTEMP());
//Serial.print (",");
//Serial.print("O:");
//Serial.print (getOILTEMP());
//Serial.print (",");
//Serial.print("F:");
//Serial.print (getFUEL());
//Serial.print (",");
//Serial.print("V:");
//Serial.println (getVOLT());
delay(100);
Serial.flush();
    }

    void OBD_init(void)
    {
      //Wait for a little while before sending the reset command to the OBD-II-UART
      delay(2000);
      //Reset the OBD-II-UART
      Serial1.print("ATZ\r");
      //Wait for a bit before starting to send commands after the reset.
      delay(2);
      OBD_read();
      Serial1.print("ATE0\r");
      OBD_read();
      //Serial1.flush();
    }

    int getRPM(void)
    {
      //Query the OBD-II-UART for the Vehicle rpm
      Serial1.flush();
      Serial1.print("010C\r");
      OBD_read();

      return ((strtol(&rxData[6], 0, 16) * 256) + strtol(&rxData[9], 0, 16)) / 4;
    }

    int getSPEED(void)
    {
      //Query the OBD-II-UART for the vehicle speed
      Serial1.flush();
      Serial1.print("010D\r");
      OBD_read();

      return strtol(&rxData[6], 0, 16);
    }

    int getOILTEMP(void)
    {
      //Query the OBD-II-UART for the vehicle speed
      Serial1.flush();
      Serial1.print("015C\r");
      OBD_read();

      return strtol(&rxData[6], 0, 16);
    }

    int getFUEL(void)
    {
      //Query the OBD-II-UART for the vehicle speed
      Serial1.flush();
      Serial1.print("012F\r");
      OBD_read();

      return strtol(&rxData[6], 0, 16);
    }

    int getVOLT(void)
    {
      //Query the OBD-II-UART for the vehicle speed
      Serial1.flush();
      Serial1.print("0142\r");
      OBD_read();

      return strtol(&rxData[6], 0, 16);
    }

    int getWATERTEMP(void)
    {
      //Query the OBD-II-UART for the Engine Coolant Temp
      Serial1.flush();
      Serial1.print("0105\r");
      OBD_read();

      return strtol(&rxData[6], 0, 16) - 40;
    }

    void OBD_read(void)
    {
      char c;
      do {
        if (Serial1.available() > 0)
        {
          c = Serial1.read();
          if ((c != '>') && (c != '\r') && (c != '\n')) //Keep these out of our buffer
          {
            rxData[rxIndex++] = c; //Add whatever we receive to the buffer
          }
        }
      } while (c != '>'); //The ELM327 ends its response with this char so when we get it we exit out.
      rxData[rxIndex++] = '\0';//Converts the array into a string
      rxIndex = 0; //Set this to 0 so next time we call the read we get a "clean buffer"

    }

```

I only need RPM & Speed that's why i comnented out other parameters but tested all and works perfectly.

---
Tags: arduino-uno
---


# Question
Title: circuit breaker/fuse necessary for IoT home monitor?
In most 12v CCTV power supplies, each power cable is behind a glass fuse. I haven't seen fuses or circuit breakers used when distributing 5v power used in IoT projects. Is there a reason overcurrent protection is not needed in these projects?

edit: I'm thinking specifically about fire safety. e.g. the risk of a short circuit overheating 22awg wire run through the house?

# Answer
> 1 votes
> Is there a reason overcurrent protection is not needed in these projects?

You're comparing apples and oranges.

The two systems are completely different and have different concerns.

Case in point:

* You want to burgle somewhere with CCTV installed. You can creep up on one camera unobserved.
* You know a little about electronics and figure if you cut the feed to the camera you can short out the power and blow the whole system, thus letting you wander in unobserved.

But there's fuses on each feed, so all you do is disable the *one* camera and everything else is fine, catching you red handed.

Go directly to jail. Do not pass go. Do not collect £200.

Now... do you really care that much if all your home temperature sensors lose power because of a fault in one? Probably not. And the chances of there being a fault other than from human negligence is slim. Sure, you *could* add fuses, but why add the expense? It's really not needed for such a non-critical system.

---

> edit: I'm thinking specifically about fire safety. e.g. the risk of a short circuit overheating 22awg wire run through the house?

22AWG wire has a resistance of about 53Ω per km. Say you have a loop of cable 20m long (10m there and 10m back again) and it shorted out at the far end. That's round about 1Ω.

At 5V you'd be drawing 5A of current.

If you have a really powerful power supply then it would try and supply that, and the wire would warm up - giving off about 25W of heat *over the entire length*. You might feel a bit of warmth from it.

Of course, most people would be using a smaller power supply than that for simple IoT things, so the power supply would just go "No. You're not having that!" and would die, or its internal fuse would blow. Or it would drop the voltage and get hot itself.

The chance of being able to start a fire from 5V over 22AWG from a normal power supply is pretty much zero. You're more likely going to start a fire from using a low quality power supply that itself melts and catches fire (i.e., a counterfeit Chinese phone charger).

With a very powerful power supply (tens of amps or more) and a short circuit close to the source (so low resistance) the wire will melt. Just that. It'll melt. Once melted there's no circuit, so nothing else happens. There's your fuse right there.

Once a wire has melted it doesn't continue to burn. And you don't get arcs at low voltages. It takes a lot of work to start a fire from low voltages. A lot of work and a lot of current.

---
Tags: iot, safety, fuses
---


title: Powering an esp32cam by a battery

text:
# Question
Title: Powering an esp32cam by a battery
I have an esp32cam that I've programmed and powered via an FTDI connected to a computer's USB. Now that this stage is over, I'd like to run it portably, using some sort of battery.

The esp32cam has a 5V input (also a 3.3V input which word is should be avoided because it causes brownout). I'm wondering if it's possible to power it (for a short period) using a 7.3V, 9V or 12.3V battery. All the datasheets I've seen seem to specify the input range is 5V, but, for the esp32 (non-cam version), unregulated 5V-12V seems to permissible. Is this true for the esp32cam? Also, what is the right way to search for this?

# Answer
The official ESP32-CAM has a AMS1117 voltage regulator that creates the 3.3V for the ESP.

The AMS1117 has an Absolute Maximum Input Voltage of 15V. It has a Dropout Voltage of 1.1-1.3V.

So you should stay above 4.6V to be on the safe side.

Since it's a linear voltage regulator, using a higher voltage battery has no advantage, as the "excess voltage" is converted to heat. It could even damage the regulator if too much heat is created.

You should pick the battery with the lowest voltage that still produces 4.6V when almost empty. So you could use the 7.3V battery you indicated. I'm assuming this is a 2-cell Li-ion battery, that has a voltage of 8.4V when full, and around 6V when empty. Which nicely fits your requirements.
> 3 votes

---
Tags: esp32, battery
---


# Question
Title: Play sound on top of background music using arduino uno tmrpcm library
We designed a big piano with 15 buttons on it. Every button has a proximity sensor. Whenever users interact with the sensor a specific sound plays for that button. My code is working fine for this purpose but now I want to add background music. Our piano button sound should play on top of that background music. I am using tmrpcm library, and I already added a bg music but when I interact with the sensor, bg music stops and starts from the beginning right after the piano button sound stops. Is there a way to play a sound without interrupting a bg music. Any help will be appreciated.

# Answer
> 1 votes
Assuming you are using an Arduino Uno, You didn't say. As there are many Arduino platforms these days.

As the tmrpcm library is using the PWM (Pulse Width Modulator) HW (Hard Ware) to recreate the sound waves from the WAV file on the SDCard, the PWM is not available for creating the sounds from your piano application (you didn't say what piano application you were using). That said, it is not impossible to re-write both applications to SUM the two wave forms together mathematically before resampling the SUM and writing that sample value to the PWM HW to simulate the SUM of the two wave forms. However, this is likely not trivial and it is also likely the Arduino Uno processor (an Atmel ATmega328P) will not be powerful enough (perform the math fast enough) to keep up with normal sound playback.

It would likely be much simpler to use 2 Arduino Uno boards and sum the sound from the sound file application and the piano application using analog techniques external from the Arduno Uno boards.

---
Tags: arduino-uno, tmrpcm
---


title: WS2812B Power Supply

text:
# Question
Title: WS2812B Power Supply
I have a WS2812b addressable RGB led ribbon that is 5m (150 RGB leds). I purchased a 5v 10amp power supply to power it; however, whenever I try to use it to power the LED strip the leds start flashing colors like crazy. Is there a reason I would be seeing this behavior or is this a sign of a bad power supply?

The setup is very simple, the data line is coming from an Arduino Uno, the voltage and ground are from the power supply. The program is just one of the sample ones with FastLED library and works "fine" when just powered by the arudino's 5V pin.

Thank you

# Answer
The strip and the Arduino need to share the same ground connection. They are communicating through voltage and voltage is always a difference between two points. The power supply sets the supply voltage as the difference between + and ground. The chips in the strip will then try to measure the voltage on the data line relative to their ground. When the grounds are not connected, the Arduinos output pin is floating somewhere else, depending on external factors. By connecting the grounds, both devices (Arduino and strip) use the same ground value to measure voltages. Only this enables communication between the devices.
> 1 votes

---
Tags: arduino-uno, current, ws2812
---


# Question
Title: ISO C++ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to member function
This question comes on the heels of this question

In the last question I learned how to use an initializer list to solve my issue, but working with `ros::Subscriber` is requiring a different solution.

I'm dealing with a callback in this scenario. If I leave the callback as a standalone function then the program runs but I have no access to class members and methods inside the function which defeats the purpose. Here is my standalone callback:

```
void setPRYCallback( const std_msgs::Empty& toggle_msg) {}

```

Once I move this into my class is when I encounter the error.

*steps to implementing into class*

```
// add member variable for callback
protected:
  void setPRYCallback( const std_msgs::Empty& );

...

// ass method
void ROSController::setPRYCallback( const std_msgs::Empty& toggle_msg) {}

...

// set initializer list
ROSController::ROSController() : sub("setPRY", &setPRYCallback )

```

How do I thwart this error while keeping my callback as a class method?

**Program with Standalone Function Callback** *(program runs)*

```
#include <ros.h> // https://github.com/ros-drivers/rosserial/blob/jade-devel/rosserial_arduino/src/ros_lib/ros.h
#include <std_msgs/Empty.h>

class ROSController {
  protected:
    ros::Subscriber<std_msgs::Empty> sub;
    ros::NodeHandle _nh;
  public:
    void loop();
    ROSController();
};

void setPRYCallback( const std_msgs::Empty& toggle_msg) {}

ROSController::ROSController()  {
  this->_nh.initNode();
  this->_nh.subscribe(sub);
}

void ROSController::loop() {
  this->_nh.spinOnce();
  delay(1000);
}

```

**Program with Method Callback** *(program fails)*

```
#include <ros.h> // https://github.com/ros-drivers/rosserial/blob/jade-devel/rosserial_arduino/src/ros_lib/ros.h
#include <std_msgs/Empty.h>

class ROSController {
  protected:
    ros::Subscriber<std_msgs::Empty> sub;
    ros::NodeHandle _nh;
    void setPRYCallback( const std_msgs::Empty& );
  public:
    void loop();
    ROSController();
};

void ROSController::setPRYCallback( const std_msgs::Empty& toggle_msg) {}

ROSController::ROSController() : sub("setPRY", &setPRYCallback )  {
  this->_nh.initNode();
  this->_nh.subscribe(sub);
}

void ROSController::loop() {
  this->_nh.spinOnce();
  delay(1000);
}

```

*arduino mega*

# Answer
When you move the setPRUCallback function into your class you change the prototype (well, C++ changes the prototype) from:

```
void setPRYCallback( const std_msgs::Empty& toggle_msg) {}

```

to:

```
void setPRYCallback( ROSController *this, const std_msgs::Empty& toggle_msg) {}

```

That is now not what the callback registering function expects, and so it breaks.

By making the method `static` it removes that `*this` parameter, but also means that the function can only access static data within your class (variables also marked `static`) and there is only one copy of the function (and `static` variables) shared between all instances of the class (maybe not what you want).
> 2 votes

# Answer
If you define instance as a global value, how about to set callback with using lambda expression as variable of constructor.

```
#include <ros.h>
#include <std_msgs/Empty.h>

class ROSController {
  protected:
    ros::Subscriber<std_msgs::Empty> sub;
    ros::NodeHandle nh;
  public:
    ROSController(void (*staticPRYCallback)(const std_msgs::Empty& msg));
    void begin();
    void loop();
    void setPRYCallback( const std_msgs::Empty& );
};

void ROSController::setPRYCallback(const std_msgs::Empty& toggle_msg) {}

ROSController::ROSController(void (*staticPRYCallback)(const std_msgs::Empty& msg))
  : sub("setPRY", staticPRYCallback )  {
}

void ROSController::begin() {
  nh.initNode();
  nh.subscribe(sub);
}

void ROSController::loop() {
  nh.spinOnce();
}

ROSController rosController([](const std_msgs::Empty& msg){
  rosController.setPRYCallback(msg);
});

void setup() {
  rosController.begin();
}

void loop() {
  rosController.loop();
  delay(1000);
}

```

Reference (A post of my blog in Japanese)
https://asukiaaa.blogspot.com/2020/09/define-cpp-callback-for-class-value-with-using-lambda-as-a-variable.html
> 2 votes

---
Tags: arduino-mega, c++
---


# Question
Title: Trouble programming custom ATMEGA2560 board
I need some help. I copied the heart of MEGA2560 design into a new project. I have the new PCBs with blank MCUs and now I need to get things programmed. (I have an existing project that runs on a MEGA2560)

I was able to get the MEGA16U2 programmed using the procedure here: https://www.arduino.cc/en/Hacking/DFUProgramming8U2, (I loaded "Arduino-usbserial-atmega16u2-Mega2560-Rev3.hex") and it shows up in the Arduino IDE.

I got the ATMEGA2560 bootloader loaded using the Arduino-as-ISP instructions here: https://www.arduino.cc/en/Tutorial/ArduinoISP

But, now when I try to program my board with the with Arduino IDE (through the USB connection of the MEGA16U2), I just get:

```
avrdude: stk500v2_ReceiveMessage(): timeout

```

The full output of the IDE is:

```
Sketch uses 30056 bytes (11%) of program storage space. Maximum is 253952 bytes.
Global variables use 1280 bytes (15%) of dynamic memory, leaving 6912 bytes for local variables. Maximum is 8192 bytes.
/home/xxxxx/.arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17/bin/avrdude -C/home/xxxxx/.arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17/etc/avrdude.conf -v -patmega2560 -cwiring -P/dev/ttyACM0 -b115200 -D -Uflash:w:/tmp/arduino_build_464802/yyyyy.ino.hex:i

avrdude: Version 6.3-20190619
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2014 Joerg Wunsch

         System wide configuration file is "/home/xxxxx/.arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17/etc/avrdude.conf"
         User configuration file is "/home/xxxxx/.avrduderc"
         User configuration file does not exist or is not a regular file, skipping

         Using Port                    : /dev/ttyACM0
         Using Programmer              : wiring
         Overriding Baud Rate          : 115200
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_getsync(): timeout communicating with programmer

avrdude done.  Thank you.

An error occurred while uploading the sketch

```

I can see the RX led of the MEGA16U2 flashing, and the data at the RX pin of the ATMEGA2560 IC, indicating that data is getting to the MCU from the IDE, but there is no corresponding TX activity.

The IDE and USB cable can program an Elegoo MEGA2560 clone with no problem.

Is this a baud rate problem? A protocol problem? What should be my next debugging step?

Thanks!

---

EDIT: Per Nick Gammon's comment, I have run his chip detector script. Here is the output:

```

Atmega chip detector.
Written by Nick Gammon.
Version 1.20
Compiled on Sep  5 2020 at 07:17:55 with Arduino IDE 10812.
Attempting to enter ICSP programming mode ...
Entered programming mode OK.
Signature = 0x1E 0x98 0x01
Processor = ATmega2560
Flash memory size = 262144 bytes.
LFuse = 0xFF
HFuse = 0xD8
EFuse = 0xFD
Lock byte = 0xCF
Clock calibration = 0x88
Bootloader in use: Yes
EEPROM preserved through erase: No
Watchdog timer always on: No
Bootloader is 8192 bytes starting at 3E000

Bootloader:

3E000: 0x0D 0x94 0x89 0xF1 0x0D 0x94 0xB2 0xF1 0x0D 0x94 0xB2 0xF1 0x0D 0x94 0xB2 0xF1

<....snipped for length....>

3FFF0: 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF

MD5 sum of bootloader = 0xD9 0xE6 0x6B 0x4E 0xD1 0xA6 0x11 0x2C 0x61 0x8F 0x9B 0xD5 0x5D 0x24 0xE2 0x13
Bootloader MD5 sum not known.

First 256 bytes of program memory:

00: 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
10: 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
20: 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
30: 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
40: 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
50: 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
60: 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
70: 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
80: 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
90: 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
A0: 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
B0: 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
C0: 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
D0: 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
E0: 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
F0: 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF

Programming mode off.

```

# Answer
> 1 votes
As per the comments your output shows that the chip is working "normally" in that it reacts to the chip detector sketch. Thus the bulk of the design/implementation is OK.

Referring to Engbedded Atmel AVR® Fuse Calculator your fuse settings means the processor is expecting an external crystal oscillator. The bootloader expects (I think) a 16 MHz crystal (with appropriate capacitors). If you have not provided this then the bootloader will be running at the wrong baud rate (so to speak) — or not at all — and not react to attempts to download it by serial programming.

If you have a different frequency crystal then you may be able to work around this by adjusting the baud rate in the boards.txt file by an appropriate scaling factor.

The chip detector sketch worked because that uses ICSP programming, which provides its own clock.

---
Tags: arduino-mega, arduino-ide, hardware
---


# Question
Title: Connecting multiple MAX30100/30102 via I2C
I want to connect multiple (up to 4) MAX30100 or MAX30102 oximeter sensors to an Arduino via I2c. But I could not find a solution to change/assign the I2C address.

implementing-pulse-oximeter-using-max30100

datasheet MAX30100

# Answer
> 3 votes
LTC4316 is what you need. I haven't used it yet, but I know it from a project that did: mocap. It is an I2C translator IC.

Of course, if you need those ICs to be far away from each other, use a uC (or a separate Arduino) with all of those, and connect them with a different protocol!

# Answer
> 1 votes
Is there any other way of solving this issue? I do not want to increase Hardware dependency.

I found out this article - which lets you use multiple i2c devices with the same address by employing different data lines: https://bitbanksoftware.blogspot.com/2019/01/controlling-lots-of-oled-displays-with.html

The Github source: https://github.com/bitbank2/Multi\_BitBang

To my knowledge, I, either have to implement this library my own way or us the TCA9548APW chip as described by @Duncan C in the above answer

# Answer
> 0 votes
Nyos's suggestion of an I2C address translator is the ticket. I hadn't heard of these chips before, so I started searching. I found that the one they recommended may be being phased out. It also looks like it's surface-mounted. I found a TI data sheet that lists a DIP package chip TCA9548APW that lets you map up to 8 I2C devices to different addresses. You might want to check those out as an alternative.

---
Tags: sensors, i2c
---


title: Arduino offline commands

text:
# Question
Title: Arduino offline commands
I wanted to know if there is a way for my arduino to keep the last command I sent to it before I disconnected it from my computer. Thanks.

# Answer
> 2 votes
Arduino always store the last sketch you have uploaded. Even if you disconnect your board and then replug it then it follow the same commands that you gave earlier.

---
Tags: arduino-uno
---


# Question
Title: How to implement a tilt compensated compass?
So i was trying to implement a tilt compensated compass, using HMC5883L and MPU6050. The problem i am facing is, there are 2 equations for tilt compensation

**Tilt Compensated X:** X,Y,Z are compass output (raw output)

`new_X = X*cos(pitch) + Y*sin(roll)*sin(pitch) – Z*cos(roll)*sin(pitch)`

**Tilt Compensated Y:**

`new Y = Y*cos(roll) + Z*sin(roll)`

**Final Heading :** `Azimuth = atan2(Y, X) * RAD_TO_DEG`

The angles which i am getting from the mpu are gyro-drift corrected angles which are coming through a kalman filter. Those angles are fed to these above equations and after `atan2` i get the tilt compensated heading. But the issue/observation here is, when i rotate the body(on which the compass and mpu are) along the Z axis (YAW axis) the heading doesn't change(sort of locked on), but changes when i tilt the body in X/Y. I searched for thorough references, but wasn't able to find any!
Here is my code snippet (uses *compass* part form adafruit library):

```
double HEADING(double r, double p){
  sensors_event_t event;
  mag.getEvent(&event);
  r = r * (PI/180);
  p = p * (PI/180);
  double x = (event.magnetic.x)*cos(p) + (event.magnetic.y)*sin(r)*sin(p) - (event.magnetic.z)*cos(r)*sin(p);
  double y = (event.magnetic.y)*cos(r) + (event.magnetic.z)*sin(r);

  float heading = atan2(y,x);

  float declinationAngle = 0.366667 * (PI/180);// (0°22')positve declination
  heading += declinationAngle;

  if(heading < 0)
    heading += 2*PI;

  if(heading > 2*PI)
    heading -= 2*PI;

  heading = heading * 180/PI;

  return heading;
}

```

**The HMC5883L data acquisition I wrote :**

```
// i just need a direction reference not actual heading, just to keep my drone
// steady on yaw axis with reference to that direction reference but it shall be Tilt compensated
#include<Wire.h>

#define MAG 0x1E

#define R 0
#define P 1
#define Y 2

float mag_raw[3],h;
float CMP_DEC = 0.36667 * (PI/180);

void setup(){
  Serial.begin(115200);
  Wire.begin();
  Wire.setClock(400000);

  Wire.beginTransmission(MAG);
  Wire.write(0x02);
  Wire.write(0x00);
  Wire.endTransmission(true);

}

void loop(){
  Wire.beginTransmission(MAG);
  Wire.write(0x03);
  Wire.endTransmission(false);
  Wire.requestFrom(MAG,6,true);

  mag_raw[R] = Wire.read() << 8 | Wire.read();
  mag_raw[P] = Wire.read() << 8 | Wire.read();
  mag_raw[Y] = Wire.read() << 8 | Wire.read();

  h = atan2(mag_raw[P],mag_raw[R]);

//  h += CMP_DEC;

  if(h < 0) h+= (2*PI);
  if(h > (2*PI)) h -= (2*PI);
  h *= (180/PI);

//  Serial.print("X : ");
//  Serial.print(mag_raw[R]);
//  Serial.print(" Y : ");
//  Serial.print(mag_raw[P]);
//  Serial.print(" Z : ");
//  Serial.print(mag_raw[Y]);

  Serial.print(" H : ");
  Serial.println(h);

}

```

Some guidance will be very helpful!

# Answer
Inspecting your code, it does not appear you are compensating the raw magnetometer values for soft and hard iron effects. These terms roughly refer to adjusting the range and magnitude of each of the individual magnetometers (X, Y and Z). Some magnetometer manufactures allow writing these compensation values into the chip. Even then the developer and user will still need to perform some form of calibration as the magnetometer can not predict under what conditions the magnetometer will be used. Here is another explanation using matrices of hard and soft iron compensation.

Once the compass produces expected results on a flat surface parallel to the surface of the earth (in a place on earth where the magnetic lines roughly align with true north). Consider adding tilt compensation. Accelerometers usually do not need to be compensated as extensively as magnetometers.

This can be done using trigonometric math and Euler angles. However, as with physical gambles, this can lead to a situation similar to gimbal lock. Where the trigonometric math goes to infinity.

To avoid a gimbal lock like situation, most tilt compensated compasses use quaternions. Quaternions use imaginary numbers and matrix math to describe 3 dimensional rotation.
> 1 votes

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


title: Read two HX711 load cell amps

text:
# Question
Title: Read two HX711 load cell amps
I need to read two values from hx711 load cells connected to strain guages. Ive found the code below that reads one guage, but being self taught and with little experience I have no idea how to adapt it to work with two, is anyone able to help?
I need two individual readings not a combined one Thanks in advance, and credit to sparkfun who wrote this code.

```
#include "HX711.h"

#define calibration_factor -7050.0 //This value is obtained using the SparkFun_HX711_Calibration sketch

#define DOUT  3
#define CLK  2

HX711 scale;

void setup() {
  Serial.begin(9600);
  Serial.println("HX711 scale demo");

  scale.begin(DOUT, CLK);
  scale.set_scale(calibration_factor); //This value is obtained by using the SparkFun_HX711_Calibration sketch
  scale.tare(); //Assuming there is no weight on the scale at start up, reset the scale to 0

  Serial.println("Readings:");
}

void loop() {
  Serial.print("Reading: ");
  Serial.print(scale.get_units(), 1); //scale.get_units() returns a float
  Serial.print(" lbs"); //You can change this to kg but you'll need to refactor the calibration_factor
  Serial.println();
}

```

# Answer
> 1 votes
The line:

```
HX711 scale;

```

is called the "instantiation of the object". It creates a new object called `scale` which is an instance of the HX711 class. It is this "object" that is your interface to the HX711 physical device.

To use two of them you first need to have two objects - one for each HX711. You can name them whatever you like. For example:

```
HX711 scale1;
HX711 scale2;

```

The line:

```
scale.begin(DOUT, CLK);

```

is where it tells the HX711 object which pins the HX711 chip is connected to. In this case `DOUT` and `CLK` which you have defined as 3 and 2 respectively. You could just as well have written:

```
scale.begin(3, 2);

```

Each object has to be "begun", so you would need a begin for each object you instantiate:

```
scale1.begin(3, 2); // DOUT = 3, CLK = 2
scale2.begin(5, 4); // DOUT = 5, CLK = 4

```

Now for every operation that you did on `scale` you would instead do on your two new objects:

```
scale1.set_scale(calibration_factor);
scale2.set_scale(calibration_factor);

```

etc.

And when you want to take a measurement you just select which object to read from:

```
Serial.print(scale1.get_units(), 1);

```

or

```
Serial.print(scale2.get_units(), 1);

```

You can add a third by creating and using `scale3` in exactly the same way as `scale1` and `scale2`.

---
Tags: arduino-mega
---


# Question
Title: How to break out the due power supply and USB connectors?
I am planning a build with my own enclosure for the arduino due. As an alternative i would like to bypass the power jack and usb port that are factory soldered onto the board, in order to use jacks mounted on the enclosure, along with a power switch.

I've looked at the info regarding the boards pin configuration at https://www.arduino.cc/en/pmwiki.php?n=Main/arduinoBoardDue, and would appreciate if someone could confirm or correct this:

1. Can i use an external 9V adapter through a jack connected to the Vin and GND pins, respectively?
2. According to This question, you can't connect an alternative programming USB port to Serial 0 TX/RX pins (Mega board). If this applies to the due as well, what do i need to break out the programming USB port?

Edit: Perhaps one of these puppies is the least complicated solution?

# Answer
so 1 - yes. the VIN pin has a common trace with the barrel jack, you can verify with a multimeter in continuity/beep mode. ive actually put power out through the barrel jack on a mega.

2- i cant find a clear schematic for the due at the moment, but on the mega the rx/tx pins are also common with the usb pins, thus they are not usable while plugged into usb
> 1 votes

---
Tags: arduino-due
---


# Question
Title: I get an error saying, "exit status 1 expected initializer before 'void'."
I will be wiring a switch to the Arduino that controls the voltage. When the I turn the switch it can adjust the voltage from 0 to 5. The overall task is to print the output voltage. The print is to be a multiplication table of the voltage.

I created this code:

```
void setup()

void loop(){

  int (n,i,j,result);

  printf("enter N Value");

  scanf ("%d", &n);

  for (i=1; i<=n; i++);

  {
    for (j=1; j<=n;j++);

    {
      result= (i*j);

      printf("%d", result);

    }
    printf("\n");

  }
  return 0;

}

```

But i get the error exit status 1 expected initializer before 'void' when I try to verify it. what does it mean. How do you fix it?

# Answer
Functions must have a body. So instead of:

```
void setup()

```

You need:

```
void setup()
  {
  // do nothing
  }

```

---

You have other issues, for example this is not C++:

```
  int (n,i,j,result);

```

That should be:

```
  int n,i,j,result;

```

Also you are returning 0, when void functions don't return a value.

Also, here:

```
  printf("enter N Value");

  scanf ("%d", &n);

```

Where is this value coming from? There isn't a keyboard on the Arduino.

See: scanf

> The C library function int scanf(const char \*format, ...) reads formatted input from stdin.

The Arduino is a microprocessor. It doesn't have stdin.
> 3 votes

---
Tags: arduino-mega, c++, code-review, error
---


# Question
Title: About maximum length of matrix can be use for matrix invertsion on atmega32
what is the maximum length for matrix can be used for matrix inversion on atmega32,for example,can we implement matrix inversion for 15x15 matrix on atmega32? And if it can be done on atmega32..does this will make the atmega32 to be slower? I want to implement kalamn filter 15 states for euler angles estimation...the data of the matrix will be floating point..

# Answer
Floats in the Arduino IDE are normally 4 bytes. So you can work out with a calculator that your matrix will take at least 15 x 15 x 4 bytes (900 bytes). That is out of a total of 2048 bytes of RAM on the Atmega32.

That may seem to be enough RAM, but other things, like the libraries, will also take RAM. I did an answer to a question about RAM a while back. Even a very simple sketch (in this case) took 346 bytes.

Also, your library, or whatever-it-is you are using for matrix inversion, may require RAM for variables, etc.

My suggestion would be to make your code invert a very small matrix (eg. 1 x 1) and see how much RAM that uses. Then you can extrapolate out fairly simply to how much would be needed for a larger matrix.
> 1 votes

---
Tags: arduino-uno, arduino-mega, avr, atmel, atmega
---


# Question
Title: How to get variable from callback function?
There is a library davetcc / IoAbstraction. The only library working as expected with my rotary encoder. The problem that on rotation I can only see serial output with position data, but I cannot get these data as some variable value.

There is the swithch initialization and function definition in main.cpp `switches.addSwitch(spinwheelClickPin, onSpinwheelClicked);`

```
void onSpinwheelClicked(uint8_t pin, bool heldDown) {
  Serial.print("Button pressed ");
  Serial.println(heldDown ? "Held" : "Pressed");
}

```

The definition from `SwitchInput.cpp`

```
bool SwitchInput::addSwitch(pinid_t pin, KeyCallbackFn callback,uint8_t repeat, bool invertLogic) {
    if(internalAddSwitch(pin, invertLogic)) {
        KeyboardItem item(pin, callback, repeat, invertLogic);
        return keys.add(item);
    }

    return false;
}

```

There is the callback function type definition from `SwitchInput.h`

```
typedef void(*KeyCallbackFn)(pinid_t key, bool heldDown);

```

I canon just change void to bool. So how can I get this `heldDown` variable value?

Sorry if the question is stupid.

# Answer
Callback functions are usually `void` and don't return real data, because they are called by some type of event handling system, like the mentioned library. As this is calling the callback function, not you, it does not make much sense to return data from it. To get that return value, you would need to change the library for every bit of data, that you want. Thus return values of callback functions are either `void` or some message to the event handling system (for example to make the event system send down the event to the next possible handler).

But you can use global variables to get the data from the callback. Define a global variable for the value, that you want to extract, and inside the callback function set that variable. Then at other places in your code you can use that global variable.

The library, that you linked, seems to handle the event in the main code and not in interrupts. So you are safe to just use the global variables as you like.

Though to be complete: When interrupts are involved and you change global variables inside an interrupt service routine, you need to be very careful. Single byte variables are not problem, but with multi-byte variables you can get scrambled data, as the interrupt might occur in the middle of processing that variable. Then you need to introduce a critical section, where interrupts are disabled for a very short time.
> 3 votes

---
Tags: interrupt, functions, callbacks
---


title: LCD Custom Character

text:
# Question
Title: LCD Custom Character
I am experimenting the `write((byte)num)` function, and I stumble upon a pre-made custom character. Usually it's on above `((byte)200)` or and below `((byte)10000)`. If anyone else know this, where could I find the list for a specific character?

# Answer
Hi Welcome to Arduino StackExchange

You can build your own LCD characters if you spend some time with the datasheet and user manuals available

Arduino has a dedicated function **here**

```
#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

byte smiley[8] = {
  B00000,
  B10001,
  B00000,
  B00000,
  B10001,
  B01110,
  B00000,
};

void setup() {
  lcd.createChar(0, smiley);
  lcd.begin(16, 2);
  lcd.write(byte(0));
}

void loop() {}

```

here is one **example**: from our tool here

From the **datasheet**:

here is one example where a Heart symbol is created using the built-in Arduino LCD library:

You can play here at our LCD1602 simulator to get a hang of it. Please leave a message or comment if you have any questions :)
> 1 votes

---
Tags: lcd
---


# Question
Title: printing data from gps on Serial1 and sensors into Serial
I am having some trouble using my gps (on Serial1) with my other sensors.

They both work great independently but when I use them in the same code, it's either the gps or the sensors that get to write on the Serial monitor.

For my gps I am using TinyGPS++, but I have a feeling that's not what's causing this problem here.

To simplify the code I'll be replacing what the sensors are supposed to write with this:

```
Serial.println("Hello there");

```

Here is the code

```
  if (Serial1.available() > 0) {
    gps.encode(Serial1.read());
    if (gps.location.isUpdated()){
      Serial.println("Satellite Count:");
      Serial.println(gps.satellites.value());
      Serial.println("Latitude:");
      Serial.println(gps.location.lat(), 6);
      Serial.println("Longitude:");
      Serial.println(gps.location.lng(), 6);
      Serial.println("Speed KT:");
      Serial.println(gps.speed.knots());
      Serial.println("Altitude Feet:");
      Serial.println(gps.altitude.feet());
      Serial.println("");
    }
  }
  Serial.println("Hello there");

```

I get this

```
Hello there
Hello there
Hello there
Hello there
Hello there
Hello there
Hello there
Hello there
Hello there
Hello there
Hello there
Hello there
Hello there
Hello there

```

If the line is removed, I get this

```
Satellite Count:
5
Latitude:
xx.xxxxx
Longitude:
-xx.xxxxxx
Speed KT:
0.19
Altitude Feet:
331.69

```

Thank you

# Answer
> 1 votes
This looks like another case of serial spam. I recommend changing to a frame-based approach and controlling that rate with checks to millis.

That limits the spam. Alternative is to limit it outright to 1:

```
//a static global:
static int isaidHELLO = 0;

//later in the loop
if (Serial1.available() > 0) {
    gps.encode(Serial1.read());
    if (gps.location.isUpdated()){
      Serial.println("Satellite Count:");
      Serial.println(gps.satellites.value());
      Serial.println("Latitude:");
      Serial.println(gps.location.lat(), 6);
      Serial.println("Longitude:");
      Serial.println(gps.location.lng(), 6);
      Serial.println("Speed KT:");
      Serial.println(gps.speed.knots());
      Serial.println("Altitude Feet:");
      Serial.println(gps.altitude.feet());
      Serial.println("");
      isaidHELLO = 0;
    }
  }
  if(isaidHELLO == 0)
  {
      Serial.println("Hello there");
      isaidHELLO = 1;
  }

```

---
Tags: arduino-mega, tinygps
---


title: USB to Arduino to bluetooth

text:
# Question
Title: USB to Arduino to bluetooth
I have a piece of equipment that has a USB output, that a flash drive gets inserted into, to collect data as the equipment completes its cycles. I need to make a device that can replace the Flash Drive and take the data from the USB port and either save onto an SD Card, to re transmit when completed, or to transmit live as the cycles complete. I was thinking about using a UNO, & a USB HOST Shield. to receive the data. Then transmit with a wireless or Bluetooth shield. I have a "SANDISK WIRELSS FLASH DRIVE" which works as a flashdrive, and then you can connect it to other devices through wireless transmission, problem with it is, the wireless feature disables when plugged into the usb port. If the wireless stayed connected, then this would be exactly what I needed.
Any help or ideas, sample schematics would be welcomed.

# Answer
> 1 votes
There once was once something called an "Infinite USB Memory Drive" that acted as a thumb drive that read and wrote data to a networked share over wifi.

They aren't selling those anymore, but their approach might be what you need - network share to resolve the issue of multi- device connected to same drive.

In your shoes, I'd be looking at a Raspberry Pi Zero W (the one with wireless) instead of an arduino. More computing options means more ways to solve your problems with the same hardware.

# Answer
> 0 votes
Your plan is flawed.

First, you don't want a USB host - a flash drive is a device, not a host. This unspecified unit that you are connecting to is the host.

Secondly you would require an Arduino a lot more complex than an Uno. You need one that is capable of operating as a USB MSD (Mass Storage Device), and the Uno or any other '328p-based device cannot do that.

The only two kinds of Arduino-like board that I know of that can do that are Teensy and chipKIT.

On top of that is a simple fact that is the reason your existing wireless flash drive doesn't work for you: only one thing can access a "block device" at once. If you had the USB and the wireless both accessing the flash drive at once you would get massive data and filesystem corruption - so it is just disabled. You need to have some manual way of switching off one point of access and switching on the other - and of course safely "unmounting" the device to ensure that all cached data is written to the disk properly.

---
Tags: arduino-uno, usb
---


title: Setup/Debug affordable 9DOF IMU

text:
# Question
Title: Setup/Debug affordable 9DOF IMU
I bought a 9 DOF IMU from AliExpress (pictures below), asking because this seems to be somewhat of a common issue (and I'm a bleeding noob). I tried setting up this board using example codes from Adafruit - presuming this would work and it's a compatible board (and it just looked exactly the same). However, surprise - several errors.

1. Using this guide I attempted to run the pitchrollheading example - it reports LSM303 not found. The wiring is according to this guide, A4 (SDA) and A5 (SCL) are connected, 5V in, Ground of IMU to Ground of Arduino (Arduino uno, like in the guide)
2. Next I debugged the lines on the board using the multimeter: 5V on line in vs ground, 5V on the SDA/SDC lines (seemed fine)
3. Then I debugged using the i2cdetect library, however it reported empty.

```
 0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
 00:          -- -- -- -- -- -- -- -- -- -- -- -- --
 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
 70: -- -- -- -- -- -- -- --

```
4. Using analog read I can get values that seem to change with board movement, that would confirm that - in theory - the board works.

Questions

1. Making sense from debugging: What could be somre reasons the board not listed using the i2cdetect library (also tried a script)?
2. Is there an easy way (or would you recommend spending time to investigate) to use the rawdata from the arduino's analog in lines to compute pitch,roll and heading?
3. Would a project like this be typically orders of magnitude easier to set up with a raspberry pi (I have one setup and ready)? (more libraries?)
4. Are IMU's usually easy to setup, and is it likely this would be easier with a more expensive IMU (e.g. MPU9250/6500)?

Thank you in advance, and please remember: I'm a noob, I ask for your patience and advice.

# Answer
I re-soldered all connections and used new wires. Now the board is recognized by the i2cdetect library. Upon multimetering all connections using the continuous mode (*the one that looks like a loudspeaker*), I noticed my breadboard sometimes does not conduct properly. Cheap breadboards and/or cables are at fault here, as far as I can tell - a rookie mistake. I'm guessing the ground connection is the only one I have not measured before
> 1 votes

---
Tags: imu, magnetometer
---


# Question
Title: Arduino fingerprint Scanner stop loop after enroll or delete
How can I stop the loop when I enroll a fingerprint to the module?

The loop is stuck in enrolling fingerprint even it was already done. The result I want was after the enrollment of fingerprint, it will exit the loop of enrollment and start the default switch command. Thank you in advance.

Here is my loop code.

```
    void loop() {
//
    if (Serial.available() > 0) {
      // read the incoming byte:
      command = Serial.read();

      // say what you got:
      Serial.print("I received: ");
      Serial.println(command);
    }
    switch (command) {
    case 'A':
    {
      Serial.println("Ready to enroll a fingerprint!");
      Serial.println("Please type in the ID # (from 1 to 127) you want to save this finger as...");
      id = readnumber();
      if (id == 0) {// ID #0 not allowed, try again!
         return;
      }
      Serial.print("Enrolling ID #");
      Serial.println(id);

      while (!  getFingerprintEnroll() );
    }
      break;
    case 'B':
    {
      Serial.println("Case 2");
    }
      break;
    default:
    {
        getFingerprintDoorLoob();
        delay(50);
    }
      break;
  }
}

```

Here is the enroll fingerprint code:

```
 uint8_t getFingerprintEnroll() {

  int p = -1;
  Serial.print("Waiting for valid finger to enroll as #"); Serial.println(id);
  while (p != FINGERPRINT_OK) {
    p = finger1.getImage();
    switch (p) {
    case FINGERPRINT_OK:
      Serial.println("Image taken");
      break;
    case FINGERPRINT_NOFINGER:
      Serial.println(".");
      break;
    case FINGERPRINT_PACKETRECIEVEERR:
      Serial.println("Communication error");
      break;
    case FINGERPRINT_IMAGEFAIL:
      Serial.println("Imaging error");
      break;
    default:
      Serial.println("Unknown error");
      break;
    }
  }

  // OK success!

  p = finger1.image2Tz(1);
  switch (p) {
    case FINGERPRINT_OK:
      Serial.println("Image converted");
      break;
    case FINGERPRINT_IMAGEMESS:
      Serial.println("Image too messy");
      return p;
    case FINGERPRINT_PACKETRECIEVEERR:
      Serial.println("Communication error");
      return p;
    case FINGERPRINT_FEATUREFAIL:
      Serial.println("Could not find fingerprint features");
      return p;
    case FINGERPRINT_INVALIDIMAGE:
      Serial.println("Could not find fingerprint features");
      return p;
    default:
      Serial.println("Unknown error");
      return p;
  }

  Serial.println("Remove finger");
  delay(2000);
  p = 0;
  while (p != FINGERPRINT_NOFINGER) {
    p = finger1.getImage();
  }
  Serial.print("ID "); Serial.println(id);
  p = -1;
  Serial.println("Place same finger again");
  while (p != FINGERPRINT_OK) {
    p = finger1.getImage();
    switch (p) {
    case FINGERPRINT_OK:
      Serial.println("Image taken");
      break;
    case FINGERPRINT_NOFINGER:
      Serial.print(".");
      break;
    case FINGERPRINT_PACKETRECIEVEERR:
      Serial.println("Communication error");
      break;
    case FINGERPRINT_IMAGEFAIL:
      Serial.println("Imaging error");
      break;
    default:
      Serial.println("Unknown error");
      break;
    }
  }

  // OK success!

  p = finger1.image2Tz(2);
  switch (p) {
    case FINGERPRINT_OK:
      Serial.println("Image converted");
      break;
    case FINGERPRINT_IMAGEMESS:
      Serial.println("Image too messy");
      return p;
    case FINGERPRINT_PACKETRECIEVEERR:
      Serial.println("Communication error");
      return p;
    case FINGERPRINT_FEATUREFAIL:
      Serial.println("Could not find fingerprint features");
      return p;
    case FINGERPRINT_INVALIDIMAGE:
      Serial.println("Could not find fingerprint features");
      return p;
    default:
      Serial.println("Unknown error");
      return p;
  }

  // OK converted!
  Serial.print("Creating model for #");  Serial.println(id);

  p = finger1.createModel();
  if (p == FINGERPRINT_OK) {
    Serial.println("Prints matched!");
  } else if (p == FINGERPRINT_PACKETRECIEVEERR) {
    Serial.println("Communication error");
    return p;
  } else if (p == FINGERPRINT_ENROLLMISMATCH) {
    Serial.println("Fingerprints did not match");
    return p;
  } else {
    Serial.println("Unknown error");
    return p;
  }

  Serial.print("ID "); Serial.println(id);
  p = finger1.storeModel(id);
  if (p == FINGERPRINT_OK) {
    Serial.println("Stored!");

  } else if (p == FINGERPRINT_PACKETRECIEVEERR) {
    Serial.println("Communication error");
    return p;
  } else if (p == FINGERPRINT_BADLOCATION) {
    Serial.println("Could not store in that location");
    return p;
  } else if (p == FINGERPRINT_FLASHERR) {
    Serial.println("Error writing to flash");
    return p;
  } else {
    Serial.println("Unknown error");
    return p;
  }
}

```

This was the current result, what I expect was after it was stored the loop will break. please help thank you

# Answer
> 1 votes
I see the problem here. Now observe the

`if(Serial.available>0)`

`{`

`//Block of Statements`

`}`

Your closing bracket for **that** if statement must be after the `switch()` statement.

For every iteration (`void loop()`) your `command` variable runs your switch and calls the enrolling function.

So it should be:

`if (Serial.available>0){`

`//Block of statements`

`Switch(command){`

`//Block of statements}`

`}`

`}`

Hope this helped

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


title: Send JSON body with SIM900 board

text:
# Question
Title: Send JSON body with SIM900 board
I'm trying to send JSON, but i'm not able to set `Content-Type` header.
Other commands are successful:

```
[23:49:41:856] AT+SAPBR=3,1,"CONTYPE","GPRS"␍␊
[23:49:41:899] ␍␊
[23:49:41:899] OK␍␊
[23:49:52:327] AT+SAPBR=3,1,"APN","internet"␍␊
[23:49:52:367] ␍␊
[23:49:52:367] OK␍␊
[23:49:59:585] AT+CSQ␍␊
[23:49:59:594] ␍␊
[23:49:59:610] +CSQ: 18,0␍␊
[23:49:59:610] ␍␊
[23:49:59:621] OK␍␊
[23:50:07:449] AT+SAPBR=1,1␍␊
[23:50:08:501] ␍␊
[23:50:08:512] OK␍␊
[23:50:13:900] AT+SAPBR=2,1␍␊
[23:50:13:928] ␍␊
[23:50:13:928] +SAPBR: 1,1,"127.0.0.1"␍␊
[23:50:13:955] ␍␊
[23:50:13:955] OK␍␊
[23:50:21:261] AT+HTTPINIT␍␊
[23:50:21:291] ␍␊
[23:50:21:291] OK␍␊
[23:50:40:284] AT+HTTPPARA="CID",1␍␊
[23:50:40:320] ␍␊
[23:50:40:320] OK␍␊
[23:50:47:652] AT+HTTPPARA="URL","http://127.0.0.1:5000/data"␍␊
[23:50:47:713] ␍␊
[23:50:47:713] OK␍␊
[23:50:54:359] AT+HTTPPARA="CONTENT","application/json"␍␊
[23:50:54:414] ␍␊
[23:50:54:414] +CME ERROR: operation not allowed␍␊
[23:51:06:576] AT+HTTPDATA=38,10000␍␊
[23:51:06:612] ␍␊
[23:51:06:612] DOWNLOAD␍␊
[23:51:12:034] ␍␊
[23:51:12:050] OK␍␊
[23:51:19:386] AT+HTTPACTION=1␍␊
[23:51:19:414] ␍␊
[23:51:19:414] OK␍␊
[23:51:27:747] ␍␊
[23:51:27:758] +HTTPACTION:1,500,290␍␊
[23:51:35:599] AT+HTTPREAD␍␊
[23:51:35:628] ␍␊
[23:51:35:628] +HTTPREAD:290␍␊
[23:51:35:635] <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">␊
[23:51:35:692] <title>500 Internal Server Error</title>␊
[23:51:35:735] <h1>Internal Server Error</h1>␊
[23:51:35:766] <p>The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application.</p>␊
[23:51:35:935] ␍␊
[23:51:35:935] OK␍␊

```

*ip addresses aren't real.*

My server received invalid request (with JSON body, but without special header), and replied `500 Internal Server Error`.

Revision: 1137B08SIM900M64\_ST\_DTMF\_JD\_MMS

# Answer
Thanks for **@Majenko**.
I solved problem by upgrade firmware to **1137B15SIM900M64\_ST**.
> 1 votes

---
Tags: serial, gsm, http
---


# Question
Title: Arduino DS3231 error: no matching function for call to 'DS3231::DS3231(const uint8_t&, const uint8_t&)'
I am building a arduino based bicycle speedometer with time and temperature display.

Im currently stuck with the DS3231 (zs-042) chip. I found online a lot of library issues, i tried using multiple libraries (Rinky-Dink, ds3231-master) but nothing works. I found a simple code online to test the chip but when I upload it the following error shows up: "no matching function for call to 'DS3231::DS3231(const uint8\_t&, const uint8\_t&)"

```
#include <Wire.h>
#include <DS3231.h>
DS3231  rtc(SDA, SCL);

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

  // Initialize the rtc object
  rtc.begin();
  rtc.setDOW(WEDNESDAY);     // Set Day-of-Week to SUNDAY
  rtc.setTime(12, 0, 0);     // Set the time to 12:00:00 (24hr format)
  rtc.setDate(1, 1, 2014);   // Set the date to January 1st, 2014
}

void loop()
{
  // Send Day-of-Week
  Serial.print(rtc.getDOWStr());
  Serial.print(" ");

  // Send date
  Serial.print(rtc.getDateStr());
  Serial.print(" -- ");

  // Send time
  Serial.println(rtc.getTimeStr());

  // Wait one second before repeating :)
  delay (1000);
}

```

The error occurs in the third line (rtc (SDA,SCL)) - I have checked the pins and switched the battery on the chip. I also tried using A4 and A5 instead of SDA and SCL pins...

Any type of help would be awesome.

Best regards, Marin

# Answer
Alright I found the problem.

https://www.youtube.com/watch?v=BM3A7w3bhqM&ab\_channel=MERTKILIC

In this video at 5:00 you can see the following:

First you have to download the library, unzip it and copy the files inside.

You will have to paste it to your Arduino/Libraries/DS3231 folder.

On the left is the current DS3231 Library which I added through the arduino library manager. Its not the same as the one the right, it should be, but its not, copy the files from the unzipped DS32321 library into the Arduino/library/DS3231.

Works fine now !
> 2 votes

---
Tags: arduino-uno
---


title: FastLED not performing as expected

text:
# Question
Title: FastLED not performing as expected
I'm fairly new to working and programming with arduinos. The project I am working on is a digital clock which uses a string of `WS2812` leds to light up the correct numbers. Each digit consists of 7 leds and there are two 'colon' leds between the second and third digits. I am using the `FastLED` library to try to program the code. I am able to make the leds light up such that all four digits are the same number (four consecutive 5's). However, the second I try to have it display multiple different numbers, everything goes south quickly. Here are some pictures of my current results:

55:55. I can create this with any number 0-9.

Should be 12:34.

Here is the code that I'm working with so far:

```
#include <RTClib.h>

RTC_DS3231 rtc;
DateTime now;

#define NUM_LEDS 30
#define LED_PIN 6

CRGB leds[NUM_LEDS];

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

  Serial.begin(57600);

  FastLED.addLeds<WS2812, LED_PIN>(leds, NUM_LEDS);

  FastLED.clear();
}

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

  const int ZERO[]={0,1,2,4,5,6};
  const int ONE[]={2,6};
  const int TWO[]={0,1,3,5,6};
  const int THREE[]={1,2,3,5,6};
  const int FOUR[]={2,3,4,6};
  const int FIVE[]={1,2,3,4,5};
  const int SIX[]={0,1,2,3,4,5};
  const int SEVEN[]={2,5,6};
  const int EIGHT[]={0,1,2,3,4,5,6};
  const int NINE[]={2,3,4,5,6};

  for(int i=0; i<sizeof(ONE);i++){
        leds[ONE[i]]=CRGB::Red;
        FastLED.show();
      }

  for(int i=0; i<sizeof(TWO);i++){
        leds[TWO[i]+7]=CRGB::Red;
        FastLED.show();
     }

  for(int i=0; i<sizeof(THREE);i++){
        leds[THREE[i]+16]=CRGB::Red;
        FastLED.show();
      }

  for(int i=0; i<sizeof(FOUR);i++){
        leds[FOUR[i]+23]=CRGB::Red;
        FastLED.show();
      }

```

Can anyone explain what's going wrong? Any help would be greatly appreciated. Let me know if you need clarification!

# Answer
Your problem is your usage of `sizeof()`. It doesn't do what you think it does.

`sizeof()` gives you the *amount of memory* a variable takes up. It does *not* give you the number of elements in an array.

For example:

```
const int ONE[]={2,6};

```

`sizeof(ONE)` will not give you 2. It will give you 4. An `int` is two bytes in size (16 bits). An array of 2 ints is, therefore, 2x2 = 4 bytes.

So when you're iterating over a 2 byte array but counting 0-3 you're overflowing your array and reading from the next bits of memory - which happen to be the first two entries of the `TWO` array in this case.

To get the number of entries in an array you must divide the `sizeof()` by the size of the variable type the array is made up of. The most common way of doing that is:

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

```

It's common to set up some macros at the time of array creation so you can easily refer to it later:

```
const int ONE[]={2,6};
#define ONE_SIZE (sizeof(ONE) / sizeof(ONE[0]))

```

You should also consider using an array of `byte` (or better, the standard `uint8_t`) where the size of one element will be 1 not 2, since you don't need to store any number \> 255. It's still good to do the division of the `sizeof()` even with a 1 byte size in case you should ever need to change the variable type in the future. It's also a good habit to get into.
> 2 votes

---
Tags: arduino-mega, arduino-ide, led
---


# Question
Title: How do I make LEDs lights up one by one according to how long the button was pressed and hold
In my project, I am trying to create a timer display with LEDs base on how long a button was pressed and hold.

There are 8 LED lights in total, when the toggle button was pressed, 1st LED lights up; keep holding/ pressing the button, the 2nd LED lights up after 1sec, the 3rd LED lights up after 2sec and so on. So 7s after the button was pressed and hold, all 8 LEDs shall light up. When the button was released at anytime, all LEDs would be off.

Something is wrong with my code which the timer seems not working (saving the time when the button was pressed) and calculate the time difference ("current time" - "time when button pressed") in order to lights up the LED.

My codes:

```
 int current;
 long millis_held;
 long prev_secs_held;
 unsigned long firstTime;
 byte previous = LOW;

 const int buttonPin = 13;

 void setup() {
 pinMode(buttonPin, INPUT);
 pinMode(2,OUTPUT) ;
 pinMode(3,OUTPUT) ;
 pinMode(4,OUTPUT) ;
 }

 void loop() {
 current = digitalRead(buttonPin);

 if (current == HIGH && previous == LOW) {
 firstTime = millis();
 digitalWrite(2, HIGH);

 millis_held = (millis() - firstTime);

 if (millis_held >= 1000 && firstTime <2000){
 digitalWrite(3, HIGH);
 }

  if (millis_held >= 2000){
  digitalWrite(4, HIGH);
 }
 }

 else {
 digitalWrite(2, LOW);
 digitalWrite(3, LOW);
 digitalWrite(4, LOW);
 }
 }

```

Hope you guys can help, thanks a lot.

# Answer
There are multiple errors in your code.

In the loop, the first if might not have the use you intended it to have. You are checking for `previous == low`, but you never set previous to high. Therefore this check can be removed entirely, or you could restructure your code a bit and add a `previous = high`.

Secondly, this `if` is also flawed:

```
if (millis_held >= 1000 && firstTime <2000){
    digitalWrite(3, HIGH);
}

```

You are checking for `firstTime < 2000` which means you need to press the button within 2 seconds of the power-up of the Arduino or else this code will not run.

Lastly, for this to run you probably only want to set `firstTime = millis()` once when you press the button, and not every time the `loop()` runs thereafter while you keep the button pressed. You would need to move the bracket on line 32 to line 22, that is from just above the `else` to the line above `millis_held = (millis() - firstTime);` and then add `previous = HIGH;` in the first if.

I am leaving it to you to fix your code, since that would be good practice to get some feeling for it. Happy coding!

Lastly you still need to add the last 5 leds, but once the first few work you should be fine.
> 3 votes

# Answer
Great thanks to Ananas\_hoi, I was finally able to get my code work accordingly!! The following code only show the 4 LED to be lights up one by one every second when the button was pressed and hold:

```
int current;
long millis_held;
unsigned long firstTime;
byte previous = LOW;

const int buttonPin = 13;

void setup() {
  pinMode(buttonPin, INPUT);
  pinMode(2,OUTPUT) ;
  pinMode(3,OUTPUT) ;
  pinMode(4,OUTPUT) ;
  pinMode(5,OUTPUT) ;
}

void loop() {
  current = digitalRead(buttonPin);

  if (current == HIGH && previous == LOW) {
     firstTime = millis();
     digitalWrite(2, HIGH);
     previous = HIGH;
  }

  millis_held = (millis() - firstTime);

  if (millis_held >= 1000 && previous == HIGH) {
      digitalWrite(3, HIGH);
     }

  if (millis_held >= 2000 && previous == HIGH) {
      digitalWrite(4, HIGH);
     }

  if (millis_held >= 3000 && previous == HIGH) {
      digitalWrite(5, HIGH);
     }

  if (current == LOW) {
  digitalWrite(2, LOW);
  digitalWrite(3, LOW);
  digitalWrite(4, LOW);
  digitalWrite(5, LOW);
  previous = LOW;
 }
}

```
> 3 votes

---
Tags: led, timers, button
---


# Question
Title: Get more PCINT capable pins on Mega 2560
I'm building kinda "ball game" for a total of 6 players based on these per-player specs:

* 1 stepper motor with 4 pins
* 2 end stops (start & finish) per motor
* 1 finish LED
* 3 holes to score, resulting in slow, medium or fast motor movement

Additionally, there's a "master reset" to move all motors back to their starting end stops.

Because of my initial assumption, 54 pins would be enough, I didn't realize actually requiring 60 pins (24 for motors, 12 for end stops, 6 for LED, 18 for holes). I'm also neither an expert at microelectronics nor C programming language, but my understanding of the Mega's pins is that I need 12 + 18 PCINT capable pins (end stops + holes) while only 16 pins are available.

So far, the only information I could find suggests buying an Arduino Shield to resolve this by providing additional 16 PCINT pins. But being connected via I2C, I suspect delays resulting in unequal treatment of player scores.

How to get at least 30 PCINT capable pins, treated equally by Arduino? In case there's no need for the PCINT requirement, which pins can be used as an alternative?

# Answer
> 2 votes
The Atmega2560 has a total of 24 pins associated to the PinChange interrupt. You cannot change that. It is an internal property of the microcontroller.

As you already have seen yourself, you need to use extra chips to extent the available IO pins. There are different options to consider:

* IO-Port-Expanders (available for I2C or SPI) (for example the PCF8574. Don't know, if that is the best, just the port expander, that I also used myself)
* Shift-In (for inputs) or Shift-Out (for outputs) registers (often used are the 74HC595 (Shift-out register) and the 75HC165 (Shift-In register). I often used this tutorial as reference)

As you don't want to poll these chips all the time, I suggest, that you use one, which provides an additional interrupt pin. That pin will change its value, when one of the input changes. You could then connect this pin to one of the interrupt pins of the Atmega2560. When the interrupt triggers, you can read the states of the input pins.

> But being connected via I2C, I suspect delays resulting in unequal treatment of player scores.

Indeed that wouldn't be good. So you should divide the pins up by their purpose, not by their association to a player. For example all end stop inputs, or all outputs for the stepper motors. Then you need to access, what timing requirements each group has. Then you can take the group with the lowest requirements and check, if and which chip would be able to handle the data fast enough. For example the "finish LED". You didn't specify, what exactly it does, but I guess, that it is not really time critical. So you could handle all finish LEDs via a single shift-out register.

Or take the inputs for the holes: I guess here you have some sensor, that triggers, when a ball passes it. Check how long the sensor get's triggered. Most likely (depending on the type of sensor) this depends on the speed of the ball. Take a speed, that you want to consider maximum (for example the pitching speed of a good baseball player, as these are really high), and calculate, how long the resulting pulse will be. The chip, that you choose, might be fast enough for this. So you could handle all ball hole inputs over extra chips (meaning chips providing extra input chips, like a Shift-In register or a port expander).

> In case there's no need for the PCINT requirement, which pins can be used as an alternative?

Every pin capable of digital IO. That's nearly every pin on the Arduino Mega. Though that means, that you cannot use interrupts for them and you have to poll then constantly. That might be ok for you. It really depends on your exact timing requirements.

> I thought polling was a "avoid where possible"-area?!

Yes and no. First you asked for the possibility of using other pins, so I mentioned that above. Though doing that means using no PinChange interrupt. Generally polling is bad, when

1. you spend too much time on it, leaving no time for other functions of the code, or
2. if the events, that you are polling, are too short for your polling code.

That can happen in the cases, that

1. you use blocking code to poll (like waiting with a `while` loop for a button press), which blocks all other functions from executing.
2. your code needs a long enough event to register it (for example the signal from your hole sensors might be very short. If your polling interval is bigger than that, you will loose some events)

If you stay inside of the confinements and use non-blocking code, there is nothing bad with polling.

Let's take the often used Bounce2 library for Arduino. It helps you with reading buttons and handles the debouncing for you. It does not use any interrupts. You are expected to call `Bounce.update()` often enough to catch all button presses, which is typically a few ms at max. But since the Arduino Mega runs on 16MHz, it is capable of way faster speeds than the few ms. Calling `Bounce.update()` often enough is easy, when you don't write code, that stays a long time to execute. So no delays, except for maybe very short ones. Instead you can use the coding style of the `BlinkWithoutDelay` example, that comes with the Arduino IDE. It uses the `millis()` function as a time base to check repeatedly, if it is time to do something, and only do so, if it really is time for it. Much like you are baking a pizza by putting it into the oven and then regularly watch at your clock, if it is time to get the pizza out of the oven. You don't want to sit in front of the oven waiting for pizza. The analog of doing that is writing blocking code with `delay()`.

So all in all about polling vs interrupts: It depends on your requirements. Fast response times or short events often need interrupts, though you need to cope with limited usable pin numbers and different interrupts (which is a bit more complex to code). Polling - when done right - can give you big freedom and rather easy handling, while saving interrupt sources for more important functions. Though it poses bigger limits on response times and the duration of events. Also it depends strictly on the rest of your code.

---

Note, that in the above, terms like "time critical", "fast response times" and such are more meant for the region of a low number of microseconds. Timings in the millisecond range can easily be done by using the mentioned non-blocking coding style (either with `millis()`, or for greater resolution and accuracy at low numbers of milliseconds `micros()`). The principle is always the same and there are tons of tutorials about it on the web and even many questions and answers on this site. So you can google for this, to get a more detailed tutorial.

---
Tags: pins, shields, atmega2560
---