# Question
Title: Bootloader onto an ATmega328p (3.3V/8MHz), the dude won't finish his business
Hi and thank you reading my question !

I need for my projects to design as small as i can. Both the skills, and the hardware counts. So i can't use a DIP package for them, and i have gone for a TQFP package. The point is to programm a TQFP ATmega328P using an external board without soldering it, which plugs into a Arduino UNO. Like that no need to constantly check the connection and everything. The shield is a basically a fat Arduino Pro Mini, with all the options available (3.3V/5V, 8MHz/16MHz, Sparkfun FTDI can be connected, ...) as shown below :

As you can see I am the enginneer of Gymetrics, but not an electronic enginner nor a programmer ... I actually did some mistakes designing it with the SS pin pins connected together and not the one of the Arduino UNO to the reset pin of the target, and added a capacitor in the wrong place. I did manage to connect the pin 10 of the Arduino to the reset pin of the target on another shield and take out that capacitor. When you order one you got tens of them at the minimum ...

As the schematic is the same as the Mini, and i don't think it's needed. I know that burn in sockets already exists, but because you to reverse enginneer the pins to make it works, i prefered design my own. Ok sorry for that long introduction, but i prefered you to know the full reflexion. As you imagine, i've been searching on so many forum, tutoriels, and so ever to do it and still it doesn't work.

As it is the first time i burn a bootloader into an ATmega328P, i am not confident in what i am doing. So i tried to burn a bootloader into an Arduino Pro Mini, it works fine. I'm happy on a point : I know how to follow a step by step procedure !

The microcontroller i use (ATmega328P) is the same as the one on the Arduino Pro Mini, so the configuration in the Arduino IDE is the same. However, when the work is done easily with the Arduino Pro Mini, it doesn't work with my board. Here is what the IDE errors shows :

```
Arduino : 1.8.12 (Windows 10), Carte : "Arduino Pro or Pro Mini, ATmega328P (3.3V, 8 MHz)"

C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avrdude -CC:\Program Files
(x86)\Arduino\hardware\tools\avr/etc/avrdude.conf -v -patmega328p -cstk500v1 -PCOM7 -b19200 -e -
Ulock:w:0x3F:m -Uefuse:w:0xFD:m -Uhfuse:w:0xDA:m -Ulfuse:w:0xFF:m

 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 "C:\Program Files
 (x86)\Arduino\hardware\tools\avr/etc/avrdude.conf"

     Using Port                    : COM7
     Using Programmer              : stk500v1
     Overriding Baud Rate          : 19200
     AVR Part                      : ATmega328P
     Chip Erase delay              : 9000 us
     PAGEL                         : PD7
     BS2                           : PC2
     RESET disposition             : dedicated
     RETRY pulse                   : SCK
     serial program mode           : yes
     parallel program mode         : yes
     Timeout                       : 200
     StabDelay                     : 100
     CmdexeDelay                   : 25
     SyncLoops                     : 32
     ByteDelay                     : 0
     PollIndex                     : 3
     PollValue                     : 0x53
     Memory Detail                 :

                              Block Poll               Page                       Polled
       Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
       ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
       eeprom        65    20     4    0 no       1024    4      0  3600  3600 0xff 0xff
       flash         65     6   128    0 yes     32768  128    256  4500  4500 0xff 0xff
       lfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
       hfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
       efuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
       lock           0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
       calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00
       signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00

     Programmer Type : STK500
     Description     : Atmel STK500 Version 1.x firmware
     Hardware Version: 2
     Firmware Version: 1.18
     Topcard         : Unknown
     Vtarget         : 0.0 V
     Varef           : 0.0 V
     Oscillator      : Off
     SCK period      : 0.1 us

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.02s

avrdude: Device signature = 0x1e950f (probably m328p)
avrdude: erasing chip
avrdude: reading input file "0x3F"
avrdude: writing lock (1 bytes):

Writing | ################################################## | 100% 0.01s

avrdude: 1 bytes of lock written
avrdude: verifying lock memory against 0x3F:
avrdude: load data lock data from input file 0x3F:
avrdude: input file 0x3F contains 1 bytes
avrdude: reading on-chip lock data:

Reading | ################################################## | 100% 0.01s

avrdude: verifying ...
avrdude: 1 bytes of lock verified
avrdude: reading input file "0xFD"
avrdude: writing efuse (1 bytes):

Writing | ################################################## | 100% 0.02s

avrdude: 1 bytes of efuse written
avrdude: verifying efuse memory against 0xFD:
avrdude: load data efuse data from input file 0xFD:
avrdude: input file 0xFD contains 1 bytes
avrdude: reading on-chip efuse data:

Reading | ################################################## | 100% 0.01s

avrdude: verifying ...
avrdude: 1 bytes of efuse verified
avrdude: reading input file "0xDA"
avrdude: writing hfuse (1 bytes):

C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avrdude -CC:\Program Files         (x86)\Arduino\hardware\tools\avr/etc/avrdude.conf -v -patmega328p -cstk500v1 -PCOM7 -b19200 -    Uflash:w:C:\Program Files     (x86)\Arduino\hardware\arduino\avr/bootloaders/atmega/ATmegaBOOT_168_atmega328_pro_8MHz.hex:i -    Ulock:w:0x0F:m
Writing | ################################################## | 100% 0.02s

avrdude: 1 bytes of hfuse written
avrdude: verifying hfuse memory against 0xDA:
avrdude: load data hfuse data from input file 0xDA:
avrdude: input file 0xDA contains 1 bytes
avrdude: reading on-chip hfuse data:

Reading | ################################################## | 100% 0.01s

avrdude: verifying ...
avrdude: 1 bytes of hfuse verified
avrdude: reading input file "0xFF"
avrdude: writing lfuse (1 bytes):

Writing | ################################################## | 100% 0.03s

avrdude: 1 bytes of lfuse written
avrdude: verifying lfuse memory against 0xFF:
avrdude: load data lfuse data from input file 0xFF:
avrdude: input file 0xFF contains 1 bytes
avrdude: reading on-chip lfuse data:

Reading | ################################################## | 100% 0.01s

avrdude: verifying ...
avrdude: 1 bytes of lfuse verified

avrdude done.  Thank you.

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 "C:\Program Files     (x86)\Arduino\hardware\tools\avr/etc/avrdude.conf"

     Using Port                    : COM7
     Using Programmer              : stk500v1
     Overriding Baud Rate          : 19200
     AVR Part                      : ATmega328P
     Chip Erase delay              : 9000 us
     PAGEL                         : PD7
     BS2                           : PC2
     RESET disposition             : dedicated
     RETRY pulse                   : SCK
     serial program mode           : yes
     parallel program mode         : yes
     Timeout                       : 200
     StabDelay                     : 100
     CmdexeDelay                   : 25
     SyncLoops                     : 32
     ByteDelay                     : 0
     PollIndex                     : 3
     PollValue                     : 0x53
     Memory Detail                 :

                              Block Poll               Page                       Polled
       Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
       ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
       eeprom        65    20     4    0 no       1024    4      0  3600  3600 0xff 0xff
       flash         65     6   128    0 yes     32768  128    256  4500  4500 0xff 0xff
       lfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
       hfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
       efuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
       lock           0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
       calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00
       signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00

     Programmer Type : STK500
     Description     : Atmel STK500 Version 1.x firmware
     Hardware Version: 2
     Firmware Version: 1.18
     Topcard         : Unknown
     Vtarget         : 0.0 V
     Varef           : 0.0 V
     Oscillator      : Off
     SCK period      : 0.1 us

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.02s

avrdude: Device signature = 0x000000 (retrying)

Reading | ################################################## | 100% 0.02s

avrdude: Device signature = 0x000000 (retrying)

Erreur lors de la gravure de la séquence d'initialisation.
Reading | ################################################## | 100% 0.02s

avrdude: Device signature = 0x000000
avrdude: Yikes!  Invalid device signature.
     Double check connections and try again, or use -F to override
     this check.

avrdude done.  Thank you.

```

Something very weird is that it reads the first and second time the right signature, and it's what i understand reading the error, and then doesn't read the signature anymore. If i try to burn again the bootloader, it can't read the signature anymore. I don't know what i am missing here.

What should i do ? I'm gonna try soldering an ATmega328P directly to see if it's a problem in the socket, but i don't think it is as it is working in the first communications.

Thank you !

**EDIT**

Programming interface :

```
UNO               Target

10                RST
11                MOSI
12                MISO
13                SCK

```

# Answer
> 1 votes
Problem solved, i did put two capacitors way to big on the XTAL's pins, which was making the crystal unable to resonate.

Thanks to @Wirewrap for finding the mistake

---
Tags: arduino-uno, atmega328, bootloader, avrdude
---


# Question
Title: Does Adafruit PowerBoost 1000 Charger support data transfer?
As the title says - Does Adafruit PowerBoost 1000 Charger support data transfer? I mean that if I connect USB on one side to PC and Arduino on other side - can I still program it and get serial monitor communication? Are the data lines connected??

# Answer
No it doesn't.

As you can see from the schematic the incoming data lines aren't connected, and the outgoing are wired through appropriate resistors to set the current availability.
> 0 votes

---
Tags: usb, adafruit, charging
---


# Question
Title: Connect multiple pins to same VCC using breadboard
Ok so I am pretty green as far as AVR programming is concerned so bear with me.

I am doing a project with an ATmega32 MCU on a dev board which has 4 VCC pins. The project includes a GPS, SD card and a TFT display. Currently, the GPS and SD card take up 2 out of the 4 VCC pins for powering themselves up. I have two free left.

The display controller I have is the SSD1289:

I've connected it to my MCU, the VCC pin on the display took up one more VCC pin so I have one VCC left. I've been reading up and I've found that the LED\_A and RD pins need to be connected to 3.3V, that is VCC. The LED\_A pin should also have a resistor on the line connecting it to VCC.

First question - can someone confirm this is the way to connect it?

Second question - Is it possible to, for example, connect the VCC and RD pins of the display to the same VCC using a breadboard? So then I have one VCC left to connect to LED\_A pin through a resistor? I don't know if multiple pins can share the same VCC. Will the voltage drop if I connect two pins to it? Is this safe to do?

# Answer
> 1 votes
You have basic misconceptions there:

1. Vcc is the power input (!) for the Atmega, not an output to provide current to other parts. Your power supply (whatever you use as one) should be connected to every Vcc pin at the same time. Sure, the Vcc pins are internally connected, but the Atmega has multiple of them, so that the needed current does not have to flow through a single pin. Also you don't want to draw the current for peripherals through the Atmega chip itself (which would happen, when you connect the power source to one of them and the peripherals to another). So every device in your circuit, including the Atmega, has it's own Vcc pin, which needs to be connected directly to the power supply. That is ok and correct, as long as the power supply can provide enough current for all components. If it doesn't, you need to buy a power supply, that can.
2. When connecting device to one pin, the number of devices is not imporant. The current draw is what is important. For example let's take simple digital output pin of the Atmega. It can provide up to 20mA (recommended value; max. 40mA for a short time). We must no exceed that value. So we can connect 1 device, that draws 20mA, or 2 devices, that draw 10mA each. Or 100 devices, which draw 0.2mA each. The number is not important, only the total power draw. The current will drop, when you draw more current, that the source can provide. In that case often the source will be damaged or at least go into thermal emergency shutdown (as for the voltage regulator of a genuine Arduino).

So the Todo for you: Connect every Vcc pin, that you have, directly with the power source.

---
Tags: voltage-level, electronics, breadboard, atmega
---


title: How to use this Toggle Switch?

text:
# Question
Title: How to use this Toggle Switch?
I purchased this toggle switch recently because I want to use it in my project:

But I don't know what to connect up the three pins to and I can't find any information about it online. Nor can I find sample code. Can someone show me how to wire it up and provide sample code please?

# Answer
> 3 votes
It's basically a push button. Possible examples depend on what you want to do. As it seems, you simply want to start interfacing it with Arduino, just use it as a normal push button. Use the `DigitalInputPullup` example, that comes with the Arduino IDE:

```
Middle pin to pin 2 on the Arduino
One of the other pins to ground (depending on which state you want to be reflected with a HIGH in the Arduino)
The other pin unconnected

```

Look at these two schematics. The left one is a normal push button. It connects, when pressed and disconnects, when released. The right one is your button. When pressed it disconnects the upper pin and connects to the lower pin. When released vice versa. When you don't use the upper pin, your button behaves just like the push button on the left.

simulate this circuit – Schematic created using CircuitLab

---
Tags: switch
---


# Question
Title: PWM Input Pins Never Receive a Value from Working Receiver?
I have a very simple sketch that's supposed to intercept the signal from an RC receiver and print the pulse duration from that channel.

## Sketch

```
int PwmPin = 9;
unsigned long duration;

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

void loop() {
  duration = pulseIn(PwmPin, HIGH);
  Serial.println(duration);
}

```

## Output

```
0
0
0
...

```

My setup is the normal one that would occur without an Arduino, and only the battery is connected through the ESC to provide power to the receiver. The Arduino is connected via USB because I'm just trying to read values.

I have been trying to plug between the receiver's data pin to the Arduino's PWM pin and read the pulses from the rudder channel. (I have previously tested the channel with a servo and know that it works correctly). However, no signal (`0`) is being printed to the serial monitor. I have difficulty understanding why.

I checked the documentation for `pulseIn()`, and it seems simple enough. I tested PWM pins `D3`, `D5`, `D10`... none of them works. I don't understand where the problem is at this point. *Update: I am now connecting from the receiver's negative pin to one of the Arduino's `GND`s.*

This is a simplistic scenario, so I don't see what's going wrong (my programming experience is good, but my experience with Arduino is near nil).

The goal of this experiment is to program lights to change according to throttle input, and asymmetric thrust through two motors for a boat. I know that pulseIn isn't the best function to use, but for the moment I just want to do some quick development before getting into the weeds.

**Update:** I am attempting to follow this video, except that connecting the Arduino to the receiver didn't work, possibly because the ESC's BEC sends some sort of power signal that arms the receiver. (The receiver's LEDs usually make a visual signal, but they just turn on without a signal when connected through the Arduino).

According to the manual on page 6 and page 8, "receivers have an operational voltage range of 3.5 to 9 volts", with an ideal voltage being above 4.8V (because servos tend to brownout sooner). This should fall within Arduino range at 5V.

# Answer
> 1 votes
What misled me is the pin numbers. I was referencing this diagram:

I thought that all the pins were numbered sequentially, so that `pinMode(9, ...)` would set `D6` *(09 in the diagram)*. However, this sets `D9`. Connecting to the correct pin works fine.

---
Tags: arduino-nano, pwm
---


# Question
Title: How can I understand which arduino I need to run some code?
I want to build this project (but any other project would give me the same uncertainty): https://github.com/ltpitt/arduino-n64-controller-library

But I cannot understand which arduino I can buy that will be compatible and also very small / easy to program / cheap.

There are countless possibilities but I cannot understand how can I match available code and compatible hardware.

# Answer
> 1 votes
In this case, the description on Github says specifically that it is compatible with the Uno:

> Based on the work in http://www.instructables.com/id/Use-an-Arduino-with-an-N64-controller/ here comes a comfortable library for usage with e.g. Arduino Uno.

If you know in advance that you intend to write a very large body of code, of which this library is only a part, you can anticipate needing an Arduino with more memory at some point, but an Uno will get you a long way there. And, with all due respect, the fact that you're asking this question also suggests that an Uno will be more than adequate.

Genuine Italian Unos just barely exceed U$D 20 and Uno clones are about 2/3 of that price. Some of the clones may not be quite up to quality of the genuine boards, but reputable board makers' products are usually quite good. The best advice I can offer would be to buy a genuine Uno for your first board, both for the most likely best experience starting out, as well as to support the folks who did the upfront work and released the design as open source. Then maybe branch out to other board-makers' products for price, or especially, for added features (assuming those are useful to you) that some of them have engineered into their versions of the product.

Update:

> My final goal is to put it into a Nintendo 64 so its size is really important. Something like this could be ok? kiwi-electronics.nl/beetle-arduino-leonardo

The Beetle's processor, AtMega32U4, has a similar memory complement as the Uno's AtMega328. In fact it has a little bit more RAM than the Uno. It should be quite doable to compile it for the Beetle.

---
Tags: arduino-nano, arduino-leonardo, hardware
---


title: conflict with different i2c devices

text:
# Question
Title: conflict with different i2c devices
I am trying to communicate with two i2c components using an arduino nano - some ADS1115s and some i2c flow sensors each connected to a different i2c multiplexer, but they seem to be conflicting.

Some of the ADS1115s are 0x49 addresses, the same as all the flow sensors. The full code works, including constructing and initialising the ads1115s, but if I then try to read from them also, I don't get almost any data from the flow sensors (they just read 0 or close to when they should be reading around 8192 for zero flowrate). Any help or suggestions much appreciated!

I've put the full code at the bottom as its quite long and I keep changing it anyway but the important parts are here:

ADS1115:

```
Adafruit_ADS1115();  //Construct an instance of an ADS1115 with the default address (0x48)
ads1115.begin();  // Initialize ads1115
int16_t readADC_Differential_0_1(void);  //Perform a differential analog to digital conversion on the voltage between channels 0 and 1.

```

tca9548a multiplexer:

```
#define TCAADDR 0x70

void tcaselect(uint8_t i) {
  if (i > 7) return;

  Wire.beginTransmission(TCAADDR);
  Wire.write(1 << i);
  Wire.endTransmission();
}

tcaselect(i);

```

Zephyr flow sensors:

```
void getflows (int sensor, float range, float flowreading) {
Wire.requestFrom(0x49, 2);
while (Wire.available())   // slave may send less than requested
  {
    int flowdata = Wire.read();    // receive a byte as character
    //Serial.println(flowdata);
    flowdata = flowdata << 8;
    flowdata |= Wire.read();    // receive a byte as character
    //Serial.println(flowdata);
    flowreading = range * ((flowdata / 16384.0) - 0.5) / 0.4;
    //Serial.print("sensor 3 flow = "); Serial.println(flow3);
    //Serial.println();         // print the character
    //Serial.println();
  }
  delay(20);

```

}

The full code:

```
#include <ModbusRtu.h>
#include <Wire.h>
#include <Adafruit_ADS1015.h>
#include <SPI.h>
#include <PID_v1.h>
#include <math.h>

//modbus
#define ID          1
#define TXEN        2

//valve TTL and DAC CS pins - nos correspond to valve driver numberings in rig box
//Current connections - O2high = 1 = A, CO2 = 2 = B, O2low = 3 = C
#define ATTL       5
#define CTTL       4
#define BTTL       3

#define BCS         7
#define CCS         8
#define ACS         9

#define tempfreq    5
#define tempnum     3
///////////////////////////////////////////
//Sensor ranges - USER DEFINED
float DACrange = 3500.0; //ml/min

int POutrange = 2000; //mbar abs
int PInrange = 2000; //mbar abs
///////////////////////////////////////////

//ADC multiplexer
#define TCAADDR      0x70
#define TCA2ADDR      0x77

//Input resistor values
float         T1R2  =  2320.0;
float         FPR1  =  3090.0;
float         FPR2  =  12010.0;

//max variation from setpoint before PID cycle
int maxdif    =  5;
//max variation from setpoint at end of PID cycle
int PIDdif    =  1;

///////////////////////////////////////////
//MATHS
//scale factor
long FPscale = 10000000;
long flowscale = 10000000;
//vrefs - with scale factors applied
float vref   = 2.5; //tscaled
float Tref   = 1.0; //tscaled
long FPref  = 20000000; //FPscaled
//divisions - integrated to sensor range in long format for calculations
float FPdiv = (FPR1 + FPR2) / FPR2;
int Vmax = 5;

int Poutfac = (int)((POutrange / Vmax) * FPdiv);
int Pinfac = (int)((PInrange / Vmax) * FPdiv);

//ADC mv/bit
float Tbit = 0.00003125;
long FPbit = 625; //- with scale factor of 10,000,000

//temp sensor steinhart constants
double sA = 0.001462146;
double sB = 0.0002393355;
double sC = 0.0000000963049;

//declare holding constants
int16_t hT1 = 0;
int16_t hT2 = 0;
int16_t hT3 = 0;
int16_t hT4 = 0;
int16_t hT5 = 0;
int16_t hT6 = 0;
int16_t hT7 = 0;
int16_t hT8 = 0;

int16_t hFP1 = 0;
int16_t hFP2 = 0;
int16_t hFP3 = 0;
int16_t hFP4 = 0;
int16_t hFP5 = 0;
int16_t hFP6 = 0;
int16_t hFP7 = 0;
int16_t hFP8 = 0;

//intermediates
int i = 0;
int j = 0;
int b[3];
int loopnum = tempfreq;
float tres = 0.0;
double treslog = 0.0;
long lconv = 0;
int16_t O2dif = 0;
int16_t CO2dif = 0;
int16_t N2dif = 0;
int16_t gasdif = 0;
int gasreading = 0;
int hFP = 0;
uint16_t val = 0;
bool truePID;
bool trueAPID = false;
bool trueBPID = false;
bool trueCPID = false;
int (*gasreadfunc)();

int flowdata = 0;
float flow3 = 0.0;
float flow2 = 0.0;
float flow4 = 0.0;
float flow5 = 0.0;
long reading = 0;

uint16_t Setpt;
int CS;
int TTL;

//initialise nested functions
//void eachPID(int16_t (*)(), int16_t, int, bool);

enum
{
  Error1,    //CHANNEL 0  //0
  Error2,    //CHANNEL 1
  FP2a,      //CHANNEL 2  //1
  FP2b,      //CHANNEL 3
  T1a,       //CHANNEL 4  //2
  T1b,       //CHANNEL 5
  T2a,       //CHANNEL 6  //3
  T2b,       //CHANNEL 7
  T3a,       //CHANNEL 8  //4
  T3b,       //CHANNEL 9
  T4a,       //CHANNEL 10 //5
  T4b,       //CHANNEL 11
  Flow2a,    //CHANNEL 12 //6
  Flow2b,    //CHANNEL 13
  Flow3a,    //CHANNEL 14 //7
  Flow3b,    //CHANNEL 15
  Flow4a,    //CHANNEL 16 //8
  Flow4b,    //CHANNEL 17
  Flow5a,    //CHANNEL 18 //9
  Flow5b,    //CHANNEL 19
  A_set,     //CHANNEL 20
  B_set,     //CHANNEL 21
  C_set,     //CHANNEL 22
  HOLDING_REGS_SIZE
};

unsigned int holdingRegs[HOLDING_REGS_SIZE];

/**
    Modbus object declaration
    u8id : node id = 0 for master, = 1..247 for slave
    u8serno : serial port (use 0 for Serial)
    u8txenpin : 0 for RS-232 and USB-FTDI
                 or any pin number > 1 for RS-485
*/
Modbus slave(1, 0, TXEN); // this is slave @1 and RS-485

//Construct ADCs at addresses
Adafruit_ADS1115 adcOne(0x48);
Adafruit_ADS1115 adcTwo(0x49);
Adafruit_ADS1115 adcThree(0x4B);
Adafruit_ADS1115 adcFour(0x4A);

// SPI - set up the speed, data order and data mode
SPISettings settings(4000000, MSBFIRST, SPI_MODE0);

//PID
//Define Variables we'll be connecting to
double Output, Setpoint, Input;

//Define the aggressive and conservative Tuning Parameters
double aggKp = 4, aggKi = 0.2, aggKd = 1;
double consKp = 1, consKi = 0.05, consKd = 0.25;

//Specify the links and initial tuning parameters
PID myPID(&Input, &Output, &Setpoint, aggKp, aggKi, aggKd, DIRECT);

///////////////////////////////////////////////////////////////////////////////////////////////
void tcaselect(uint8_t i, int address) {
  if (i > 7) return;

  Wire.beginTransmission(address);
  Wire.write(1 << i);
  Wire.endTransmission();
}

void setup() {
  ///////////////////////////////////////////////////////////////////////////////////////////////
  //DAC
  pinMode (BCS, OUTPUT);
  digitalWrite(BCS, HIGH);
  pinMode (CCS, OUTPUT);
  digitalWrite(CCS, HIGH);
  pinMode (ACS, OUTPUT);
  digitalWrite(ACS, HIGH);

  pinMode (ATTL, OUTPUT);
  digitalWrite(ATTL, LOW);
  pinMode (CTTL, OUTPUT);
  digitalWrite(CTTL, LOW);
  pinMode (BTTL, OUTPUT);
  digitalWrite(BTTL, LOW);
  ///////////////////////////////////////////////////////////////////////////////////////////////
  //ADC
  adcOne.begin();
  adcTwo.begin();
  adcThree.begin();
  adcFour.begin();

  // 2/3x gain +/- 6.144V  1 bit = 0.1875mV (default)
  // ads1015.setGain(GAIN_ONE);     // 1x gain   +/- 4.096V  1 bit = 0.125mV
  // ads1015.setGain(GAIN_TWO);     // 2x gain   +/- 2.048V  1 bit = 0.0625mV
  // ads1015.setGain(GAIN_FOUR);    // 4x gain   +/- 1.024V  1 bit = 0.03125mV
  // ads1015.setGain(GAIN_EIGHT);   // 8x gain   +/- 0.512V  1 bit = 0.015625mV
  // ads1015.setGain(GAIN_SIXTEEN); // 16x gain  +/- 0.256V  1 bit = 0.0078125mV

  //////////////////////////////////////////////////////////////////////////////////////////////
  //Flow sensor serial number readouts
  getflows(2, 750.0, flow2);
  getflows(3, 400.0, flow3);
  getflows(4, 50.0, flow4);
  getflows(5, 400.0, flow5);

  //////////////////////////////////////////////////////////////////////////////////////////////
  //PID
  //initialize the variables we're linked to
  Input = 0;
  Setpoint = 0;

  //Define the aggressive and conservative Tuning Parameters
  float aggKp = 4, aggKi = 0.2, aggKd = 1;
  float consKp = 1, consKi = 0.05, consKd = 0.25;

  //turn the PID on
  myPID.SetMode(AUTOMATIC);
  //////////////////////////////////////////////////////////////////////////////////////////////
  // start modbus communication
  slave.begin(115200);

  // initialize SPI:
  SPI.begin();

  //Serial.begin(115200);
  gettemperatures();

  holdingRegs[Error2] = 0;
}

void loop() {
  //each tempfreq no of loops, it reads the temp sensors also
  loopnum++;
  if (loopnum > tempfreq) {
    gettemperatures();
    loopnum = 0;
  }

  holdingRegs[Error1] = 0;//set to 0 for normal operation, 65535 = PID control
  //Serial.print("Holding Regs Error1 "); Serial.print(holdingRegs[Error1]); Serial.print(", holdingRegs[Error2]"); Serial.println(holdingRegs[Error2]);

  //flow and pressure sensors
  tcaselect(0, TCAADDR);
  adcOne.setGain(GAIN_TWO);
  //adcTwo.setGain(GAIN_TWO);
  //adcThree.setGain(GAIN_TWO);
  //adcFour.setGain(GAIN_TWO);

  //hFP1 = adcOne.readADC_Differential_0_1();
  hFP2 = adcOne.readADC_Differential_2_3();
  //hFP3 = adcTwo.readADC_Differential_0_1();
  //hFP4 = adcTwo.readADC_Differential_2_3();
  //hFP5 = adcThree.readADC_Differential_0_1();
  //hFP6 = adcThree.readADC_Differential_2_3();
  //hFP7 = adcFour.readADC_Differential_0_1();
  //hFP8 = adcFour.readADC_Differential_2_3();

  //FPconv(hFP1, &holdingRegs[FP1a], &holdingRegs[FP1b], Pinfac);
  //Serial.print("hFP1: "); Serial.println(hFP1);
  FPconv(hFP2, &holdingRegs[FP2a], &holdingRegs[FP2b], Poutfac);
  //Serial.print("hFP2: "); Serial.println(hFP2);
  //FPconv(hFP3, &holdingRegs[FP3a], &holdingRegs[FP3b], CO2fac);
  //Serial.print("hFP3: "); Serial.println(hFP3);
  //FPconv(hFP4, &holdingRegs[FP4a], &holdingRegs[FP4b], O2fac);
  //Serial.print("hFP4: "); Serial.println(hFP4);
  //FPconv(hFP5, &holdingRegs[FP5a], &holdingRegs[FP5b], Finfac);
  //Serial.print("hFP5: "); Serial.println(hFP5);
  //FPconv(hFP6, &holdingRegs[FP6a], &holdingRegs[FP6b], N2fac);
  //Serial.print("hFP6: "); Serial.println(hFP6);
  //FPconv(hFP7, &holdingRegs[FP7a], &holdingRegs[FP7b], Finfac);
  //Serial.print("hFP7: "); Serial.println(hFP7);
  //FPconv(hFP8, &holdingRegs[FP8a], &holdingRegs[FP8b], Finfac);
  //Serial.print("hFP8: "); Serial.println(hFP8);
  //Serial.println("");

  getflows(2, 750.0, flow2);
  getflows(3, 400.0, flow3);
  getflows(4, 50.0, flow4);
  getflows(5, 400.0, flow5);

  flowconvert();

  //modbus communication
  slave.poll( holdingRegs, HOLDING_REGS_SIZE );

  checkgasflow(1);
  checkgasflow(2);
  checkgasflow(3);

  //delay(1000);
}

void gasread(int gastoread) {
  switch (gastoread) {
    case 1: //O2high
      getflows(3, 400.0, flow3);
      gasreading = flow2;
      Setpt = A_set;
      CS = ACS;
      TTL = ATTL;
      truePID = trueAPID;
      //return gasreading;
      break;
    case 2: //CO2
      getflows(4, 50.0, flow4);
      Setpt = B_set;
      CS = BCS;
      TTL = BTTL;
      truePID = trueBPID;
      //return gasreading;
      break;
    case 3: //O2low
      getflows(5, 400.0, flow5);
      Setpt = C_set;
      CS = CCS;
      TTL = CTTL;
      truePID = trueCPID;
      //return gasreading;
      break;
  }
}

void checkgasflow(int gastoread) {
  gasread(gastoread);
  Input = (double)gasreading;
  Setpoint = (double)Setpt;
  gasdif = Input - Setpoint;
  if (abs(gasdif) < PIDdif) {
    truePID = 1;
    return;
  }
  else {
    GasPID();
  }
}

void GasPID() {
  holdingRegs[Error1] = 65535; //set to 0 for normal operation, 65535 = PID control

  //modbus communication
  slave.poll( holdingRegs, HOLDING_REGS_SIZE );

  do {
    eachPID(1);
    eachPID(2);
    eachPID(3);
  } while (!trueAPID || !trueBPID || !trueCPID);

  holdingRegs[Error1] = 0;
}

void eachPID(int gastoread) {
  gasread(gastoread);
  Input = (double)gasreading;
  Setpoint = (double)Setpt;
  gasdif = Input - Setpoint;
  if (abs(gasdif) < PIDdif) {
    truePID = 1;
    return;
  }
  else if (abs(gasdif) < 10)
  { //we're close to setpoint, use conservative tuning parameters
    truePID = 0;
    myPID.SetTunings(consKp, consKi, consKd);
  }
  else
  {
    //we're far from setpoint, use aggressive tuning parameters
    truePID = 0;
    myPID.SetTunings(aggKp, aggKi, aggKd);
  }
  myPID.Compute();
  val = (uint16_t)Output;
  DACspi(CS, val, TTL);
}

void FPconv (int16_t FPin, uint16_t *hRega, uint16_t *hRegb, int FPfac) {
  lconv = (FPfac * (FPref + (long)(FPbit * FPin)));
  memcpy((uint8_t *)hRega, (uint8_t *)&lconv, 2);
  memcpy((uint8_t *)hRegb, (uint8_t *)&lconv + 2, 2);
}

void Flowconv (float FPin, uint16_t *hRega, uint16_t *hRegb) {
  lconv = (long)(FPin*flowscale);
  memcpy((uint8_t *)hRega, (uint8_t *)&lconv, 2);
  memcpy((uint8_t *)hRegb, (uint8_t *)&lconv + 2, 2);
}

void Tconv (int16_t Tin, uint16_t *hRega, uint16_t *hRegb) {
  tres = T1R2 * ((vref / (Tref + (Tbit * Tin))) - 1.0);
  treslog = log(tres);
  lconv = lround(10000000.0 * ((1.0 / (sA + sB * treslog + sC * (pow(treslog, 3.0)))) - 273.15));
  memcpy((uint8_t *)hRega, (uint8_t *)&lconv, 2);
  memcpy((uint8_t *)hRegb, (uint8_t *)&lconv + 2, 2);
}

void DACspi(uint16_t CS, uint16_t val, int TTL) {
  digitalWrite(CS, LOW);
  if (val > 0) {
    digitalWrite(TTL, HIGH);
  }
  else {
    digitalWrite(TTL, LOW);
  }
  SPI.transfer16(val);
  digitalWrite(CS, HIGH);
}

void gettemperatures() {
  tcaselect(6, TCAADDR);
  adcOne.setGain(GAIN_FOUR);
  adcTwo.setGain(GAIN_FOUR);
  adcThree.setGain(GAIN_FOUR);
  adcFour.setGain(GAIN_FOUR);
  //temp sensors - 2 consecutive readings to allow pins to warm up first
  for (i = 0; i < tempnum; i++) {
    hT1 = adcOne.readADC_Differential_0_1();
  }
  for (i = 0; i < tempnum; i++) {
    hT2 = adcOne.readADC_Differential_2_3();;
  }
  for (i = 0; i < tempnum; i++) {
    hT3 = adcTwo.readADC_Differential_0_1();
  }
  for (i = 0; i < tempnum; i++) {
    hT4 = adcTwo.readADC_Differential_2_3();
  }
  //for (i = 0; i < tempnum; i++) {
  //  hT5 = adcThree.readADC_Differential_0_1();
 // }
  //for (i = 0; i < tempnum; i++) {
  //  hT6 = adcThree.readADC_Differential_2_3();
  //}
  //for (i = 0; i < tempnum; i++) {
  //  hT7 = adcFour.readADC_Differential_0_1();
  //}
  //for (i = 0; i < tempnum; i++) {
  //  hT8 = adcFour.readADC_Differential_2_3();
  //}

  Tconv(hT1, &holdingRegs[T1a], &holdingRegs[T1b]);
  //Serial.print("hT1: "); Serial.println(hT1);
  Tconv(hT2, &holdingRegs[T2a], &holdingRegs[T2b]);
  //Serial.print("hT2: "); Serial.println(hT2);
  Tconv(hT3, &holdingRegs[T3a], &holdingRegs[T3b]);
  //Serial.print("hT3: "); Serial.println(hT3);
  Tconv(hT4, &holdingRegs[T4a], &holdingRegs[T4b]);
  //Serial.print("hT4: "); Serial.println(hT4);
  //Tconv(hT5, &holdingRegs[T5a], &holdingRegs[T5b]);
  //Serial.print("hT5: "); Serial.println(hT5);
  //Tconv(hT6, &holdingRegs[T6a], &holdingRegs[T6b]);
  //Serial.print("hT6: "); Serial.println(hT6);
  //Tconv(hT7, &holdingRegs[T7a], &holdingRegs[T7b]);
  //Serial.print("hT7: "); Serial.println(hT7);
  //Tconv(hT8, &holdingRegs[T8a], &holdingRegs[T8b]);
  //Serial.print("hT8: "); Serial.println(hT8);
}

void getflows (int sensor, float range, float flowreading) {
  tcaselect(sensor, TCA2ADDR);
  Wire.requestFrom(0x49, 2);

  while (Wire.available())   // slave may send less than requested
  {
    int flowdata = Wire.read();    // receive a byte as character
    //Serial.println(flowdata);
    flowdata = flowdata << 8;
    flowdata |= Wire.read();    // receive a byte as character
    //Serial.println(flowdata);
    flowreading = range * ((flowdata / 16384.0) - 0.5) / 0.4;
    //Serial.print("sensor 3 flow = "); Serial.println(flow3);
    //Serial.println();         // print the character
    //Serial.println();
  }
  delay(20);
}

void flowconvert (){

  Flowconv(flow2, &holdingRegs[Flow2a], &holdingRegs[Flow2b]);
  //Serial.print("hFP1: "); Serial.println(hFP1);
  Flowconv(flow3, &holdingRegs[Flow3a], &holdingRegs[Flow3b]);
  //Serial.print("hFP1: "); Serial.println(hFP1);
  Flowconv(flow4, &holdingRegs[Flow4a], &holdingRegs[Flow4b]);
  //Serial.print("hFP1: "); Serial.println(hFP1);
  Flowconv(flow5, &holdingRegs[Flow5a], &holdingRegs[Flow5b]);
  //Serial.print("hFP1: "); Serial.println(hFP1);
}

/*void FPconv (int16_t FPin, uint16_t *hRega, uint16_t *hRegb, int FPfac, long FPcal) {
  lconv = (FPfac * (FPcal + FPref + (long)(FPbit * FPin)));
  memcpy((uint8_t *)hRega, (uint8_t *)&lconv, 2);
  memcpy((uint8_t *)hRegb, (uint8_t *)&lconv + 2, 2);
  }*/

/*void GasPID() {
  holdingRegs[Error1] = 65535; //set to 0 for normal operation, 65535 = PID control

  //modbus communication
  slave.poll( holdingRegs, HOLDING_REGS_SIZE );

  tcaselect(0);

  do {
    eachPID(O2read, O2_set, BCS, trueAPID);
    eachPID(CO2read, CO2_set, CCS, trueBPID);
    eachPID(N2read, N2_set, ACS, trueCPID);
  } while (!trueAPID || !trueBPID || !trueCPID);

  trueAPID = !trueAPID;
  trueBPID = !trueBPID;
  trueCPID = !trueCPID;
  }*/

/*
  void eachPID(int16_t gasReadfunc(), int16_t Setpt, int CS, bool truePID, int TTL) {
  Setpoint = (double)Setpt;

  for (i = 0; i < 3; i++) {
    hFP = (*gasreadfunc)();
  }
  Input = (double)hFP;
  gasdif = Input - Setpoint;
  if (abs(gasdif) < PIDdif) {
    truePID = 1;
    return;
  }
  else if (abs(gasdif) < 10)
  { //we're close to setpoint, use conservative tuning parameters
    myPID.SetTunings(consKp, consKi, consKd);
  }
  else
  {
    //we're far from setpoint, use aggressive tuning parameters
    myPID.SetTunings(aggKp, aggKi, aggKd);
  }
  myPID.Compute();
  val = (uint16_t)Output;
  DACspi(CS, val, TTL);
  }*/

/*//Connections
  int16_t O2read() {
  gasread = adcOne.readADC_Differential_0_1();
  return gasread;
  }
  int16_t CO2read() {
  gasread = adcOne.readADC_Differential_2_3();
  return gasread;
  }
  int16_t N2read() {
  gasread = adcTwo.readADC_Differential_0_1();
  return gasread;
  }*/

/*// SPI communication with DAC
  DACspi(BCS, holdingRegs[CO2_set], BTTL); //CO2 controller
  DACspi(CCS, holdingRegs[N2_set], CTTL); //N2 controller
  DACspi(ACS, holdingRegs[O2_set], ATTL); //O2 controller*/

```

# Answer
You pass `flowreading` to `void getflows (int sensor, float range, float flowreading)` as a value and therefore changing `flowreading` has no effect on the variable you pass to that function.

Instead, you need to do `void getflows (int sensor, float range, float *flowreading)`.
> 1 votes

# Answer
I had not realised that once opened, the tca9548a channels stay open until either POR or the RESET pin is brought low. Hence when using two multiplexers I just needed to use an extra wire to the RESET pin on each from the nano.
> 0 votes

---
Tags: arduino-nano, i2c
---


# Question
Title: How to actually concatenate two Strings?
I'm using the SPISlave library, and I have the following code snippet:

```
String arg;

SPISlave.onData([arg](uint8_t *data, size_t len) {
  data[len] = 0;
  arg += String((char *)data);
  // ...
}

```

The compiler doesn't like my string concatenation, though:

> /home/lars/sketch\_apr01a/sketch\_apr01a.ino: In lambda function: sketch\_apr01a:65:12: error: passing 'const String' as 'this' argument of 'String& String::operator+=(const String&)' discards qualifiers \[-fpermissive\] arg += String((char \*)data);

I've tried other versions as well, with similar results:

* `arg.concat((char *)data)`
* `arg = arg + String((char *)data)`
* `arg += String((const char *)data)`

So how exactly do I write this unusual operation?

# Answer
Your lambda is capturing `arg` by copy, which is most certainly not what you want. And since it doesn't have the `mutable` qualifier, the captured parameters are not modifiable. Hence the compiler error.

You could get rid of the error by qualifying the capture as `mutable`, but you would then be modifying the captured copy of `arg`, not the original one. The correct solution would be to capture the String by reference instead of capturing by copy. See Lambda expressions.

But then, I concur with Michel Keijzers that avoiding Strings altogether is a better option.
> 3 votes

# Answer
Actually for such string concatenation (which is in a function that may be called a lot), this could result in memory fragmentation, an on most Arduinos the memory will be soon too scattered that no useful memory is left.

Instead, it's better to create beforehand a buffer with the maximum size of the string you want to handle, like:

```
static const int MAX_BUFFER_LENGTH = 256;

char buffer[MAX_BUFFER_LENGTH];

```

And use the function `strcat` or `strncat` for concatenating two strings; there are generic C functions.
> 2 votes

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

static const int MAX_BUFFER_LENGTH = 32;
char buffer[MAX_BUFFER_LENGTH];

sprintf(buffer, "%s%s", string1, string2);

```
> 1 votes

---
Tags: programming, c++, string
---


# Question
Title: My Arduino smokes every time I connect an AC/DC wall adapter to it. Can someone help me to fix it?
I copied the schematic below and when I ran the code from my laptop, it worked well but every time I unplug it to my laptop and connect an ac dc wall adapter, my Arduino smokes. Why does it smoke and how to fix it so that I can connect an AC/DC wall adapter to power my Arduino?
**EDIT** from the comments: My AC/DC adapter has 19.5V DC out.

# Answer
As already stated in the comments, the voltage of your power supply is the problem. The Arduino has a linear voltage regulator at the Vin pin. It dissipates the excess voltage as heat. The higher the supplied voltage, the lower the current, that you can draw before it overheats. The regulator on a genuine Arduino should go into thermal shutdown, while the regulators on most cheap clones will just get destroyed.

19.5V is too high for the Arduino. The Vin pin is meant for 6 to 12V max. You need a power supply, that can provide a voltage in that range. Or you can buy a regulated power supply, that directly gives you the 5V, that the Arduino needs.

Also you should be really carefull with powering the motor through the Arduinos 5V pin. Motors can easily draw a big amount of current. When drawing too much current through the Arduino (to be specific: through the voltage regulator or the protection diode), the same as explained above will happen. Only very small motors can be supplied through the Arduino. As you use a relay to control it, I guess the motor draws a lot of current. You need tp connect it directly to a fitting power supply, so that the current for it does not flow through the Arduino.

And always be sure, that the used parts can work with the voltage, that you want to supply, including the motor.
> 3 votes

---
Tags: arduino-uno, motor, voltage-level
---


# Question
Title: How to connect multiple NodeMCUs and 1 PC over wifi and have PC control NodeMCUs?
I am trying to design a laser tag system using multiple NodeMCUs in the guns. I am trying to figure out how to connect and control them over WiFi. I also need a computer connected that will control the game. I was origionally just thinking I could use the PC as a server that tells all the guns what to do. Im sure this is possible, but it looks very complicated and I dont know a whole lot about theese types of things. So then I was thinking it might be better to have another NodeMCU connected to the computer with USB. That NodeMCU would then act as a WiFi server for the clients(Guns). That way, the PC would only have a GUI for that MCU, and once started the MCU would actually control the game. Is that the best option or is there some easier and simpler way? That seems like the best solution to me. I am just making sure this will work. Are there any other solutions or tips? Here is a basic idea of what would happen when someone shoots someone else.

Gun 1 will send IR signal (Shoot) gun 2.

Gun 1 will tell the server that it tried to shoot gun 2.

Gun 2 tells server it got IR signal from gun 1.

Server will first make sure no other guns were shot accidentally at the same time. If they were, it will determine which gun received the IR signal stronger. That gun will be the one actually shot.

Server will add points to gun 1 score and remove points from gun 2 score on both PC monitor and small screens on guns themselves.

Thanks!

# Answer
I would not consider it easier to connect a NodeMCU to the PC just to act as a Wifi interface. Most computers already have means of connecting to a network. Wether it is via Wifi or LAN is not important. Every PC has a LAN port on it's mainboard. You could connect it directly to your Wifi router.

Using a NodeMCU as you proposed would mean, that you have to program for 2 platforms: The main logic on the PC and the Wifi communication on the NodeMCU. That does not really make it easier.

The communication depends on your wanted topology. I would build the PC as Server and the NodeMCUs as clients. You can easily create a webserver programmatically with python, for example with Flask, as I have done it once. Though there even might be better webserver modules for python. It is really not that difficult and you already need to write a program for the game logic on the PC,so why not using python. Though of course you could choose any language, that you like. Python is just an easy choice, that I already did.
> -1 votes

---
Tags: wifi, nodemcu, web-server
---


# Question
Title: How can I connect an OLED display to arduino
I'm new on this!

So I want to know if is it posible to connect this oled display: oled display to arduino nano and if is it posible where can I found information of how to learn about connect this type of mini display.

And if you can share some links about good learning site would be cool too!

Thanks!

# Answer
Yes, you can. If you have the adaptor board for it as shown in the video.

The key item from the description to note is the driver chip: **SSD1309**

That is what you need to know to find a library and connection schema.
> 0 votes

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


# Question
Title: Can two electronic speed controllers be connected to the same ground pin?
I have a setup to read two sets of signals from a radio control receiver using an Arduino NANO: the throttle channel and the rudder channel. With some programming knowledge (which I have) this isn't too difficult, but I need help on the electrical side of things. This is the current setup I have (it works, though I'm told there is the possibility that my computer is acting as a ground for the PWM signal wires from the receiver):

OK, great. I'm able to control the motor programmatically, mix values from the receiver, etc. See this video for what I'm doing. However, this setup leaves some gaps:

**Question 1** I actually need two motors for dual thrust. Each motor is to be controlled individually by the program (for asymmetric thrust). Since there are only two grounds on the Arduino, can I plug both ESC grounds to the same pin? Currently, the receiver is getting power from the Arduino, and grounds back. The speed controller grounds to the second ground pin. Diagram below:

**Question 2** All that is great, but the NANO is still powered by USB: obviously I'm not putting my laptop in the RC boat just to supply a few volts! Incidentally, both electronic speed controllers (ESCs) have battery eliminator circuits (BECs), usually used to power the receiver. Would I be able to connect one of them to the VIN pin of the Arduino?

I tried something like that, but the Arduino got very hot near the pin, and it smelled. Unfortunately, I don't have my circuit at the time. The Arduino's Amazon page states support for 5V to 12V external power supply. Each ESC can supply 5V at 3A. Maybe there's a way to plug them to make 10V?

**Question 3** My idea also calls for three sets of LEDs, which will be lit also based on inputs from the receiver. Can these be grounded to the same wire, like I was suggesting above for the ESCs?

# Answer
You can connect all the grounds together and the circuit will be safe. If the BEC outputs 5V, you can feed it directly to the Arduino's 5V pin. Any more volts and you'll need to feed the BEC output to the Arduino's VIN pin.
> 1 votes

---
Tags: arduino-nano, voltage-level, remote-control
---


title: NeoPixel Gradient sweep function

text:
# Question
Title: NeoPixel Gradient sweep function
I'm trying to create a function that takes two colours and creates a smooth gradient between them one colour at the beginning and one at the end

I just can't figure the math of mixing them evenly

I'm using neopixel library

# Answer
> 1 votes
I can think of two ways of doing this.

One is to use the H channel of the HSV colour space (as I show in the answer to this question. This would give you a smooth transition between two colours through the pre-defined spectrum of the hue range.

The second is to simply specify two colours and then mix them at different percentages depending on how far along the length you are.

For example, here's a (untested) small function that "mixes" two individual colour channels together and returns the result:

```
uint8_t mix(uint8_t a, uint8_t b, int pct, int range) {
    if (pct <= 0) return a;
    if (pct >= range) return b;
    return (((uint32_t)a * (range-pct)) / range) + (((uint32_t)b * pct) / range);
}

```

`pct` is the led number in your chain, and `range` is the total number of LEDs.

So you could (hypothetically):

```
uint8_t red1 = 0, green1 = 255, blue1 = 0;
uint8_t red2 = 255, green2 = 100, blue2 = 100;

for (int i = 0; i < 50; i++) {
    uint8_t red = mix(red1, red2, i, 50);
    uint8_t green = mix(green1, green2, i, 50);
    uint8_t blue = mix(blue1, blue2, i, 50);
    setLedColor(i, red, green, blue);
}

```

---
Tags: esp8266, neopixel, ws2812
---


# Question
Title: How to get full response json SIM900 + Arduino?
```
  void toSerial(int delay_ms)
  {
    delay(delay_ms);

    while(mySerial.available())
    {
       Serial.write(mySerial.read());
    }
  }

  Serial.begin(9600);
  mySerial.begin(9600);

  mySerial.println("AT+HTTPINIT");
  toSerial(500);

  mySerial.println("AT+HTTPPARA=\"CID\", 1");
  toSerial(500);

  mySerial.println("AT+HTTPPARA=\"URL\", \"www.example.test\"");
  toSerial(500);

  mySerial.println("AT+HTTPPARA=\"CONTENT\", \"application/json\"");
  toSerial(500);

  mySerial.println("AT+HTTPACTION=0");
  toSerial(4000);

  mySerial.println("AT+HTTPREAD");
  delay(3000);

  while(mySerial.available())
  {
    Serial.write(mySerial.read());
  }

  Serial.println("");
  mySerial.println("AT+HTTPTERM");
  toSerial(500);

```

**Result:**

```
AT+HTTPREAD

+HTTPREAD:39
{"pinRed":0,"pinGreen":1,"pinYello

```

**I expect messages:**

```
{"pinRed":0,"pinGreen":1,"pinYellow":0}

```

# Answer
Okay, I've found a solution. To start with, you need to download the server response length and loop according to the response length.
> 1 votes

---
Tags: json
---


title: Inductive spikes upset Interrupts

text:
# Question
Title: Inductive spikes upset Interrupts
I am using an Arduino Uno to create a kinetic sculpture with magnets and electromagnets (EMs). I have a setup with two externally debounced buttons using resistors,capacitor and CMOS 4584 hex inverter. All non-used inputs of the 4584 are grounded. These buttons deliver a clean signal to the board and trigger the two interrupts which set flags to turn LEDs on or off and trigger one or both optoisolators (OIs). These connect to another board with a separate 12V supply. One of the OIs turns a BUZ71 power mosfet on and the other triggers a relay which can reverse the polarity of the power to a small 30 ohm EM coil. This can make the magnet suspended above like a pendulum fly away from the coil...

This works perfectly well with the buttons, the LEDs and the two inputs to the OIs But when I connect the relay/mosfet board to the output of the OIs it stops working properly. button 2 turns off button 1 as well as itself. Button one always turns off and on cleanly But button two triggers ISR2 about 10 times and ISR1 a couple of times, leaving both off. If I disconnect the EM coil the buttons work properly. It seems that switching the polarity is somehow interfering with the Uno maybe due to a fairly hefty inductive spike generated by switching the relay. I have tried using shielded coax to the coil. I have 47000 uF caps on both boards. I tried a crude faraday cage around the relay board - no luck. Could the spike be coming through the household power supply somehow even though the Uno board and the relay board have different power supplies and are fully seperated by the OIs? Here is the sketch I am using:

```
    //  Coding by Jeremy 070520
//  development for ricochet module

const int coilButton = 2;
const int directionButton = 3;
const int coilPin = 8; //coil driver
const int directionPin = 9; //direction driver
volatile bool coilFlag;
volatile bool directionFlag;
int coilLedState = LOW;
int directionLedState = LOW;

void setup()
{
  pinMode(coilButton,INPUT);
  pinMode(directionButton, INPUT);
  pinMode(coilPin, OUTPUT);
  pinMode(directionPin, OUTPUT);
  digitalWrite(coilPin,LOW);
  digitalWrite(directionPin, LOW);
  attachInterrupt(digitalPinToInterrupt(coilButton), ISR1, FALLING);
  attachInterrupt(digitalPinToInterrupt(directionButton), ISR2, FALLING);
  Serial.begin(9600);
  }

void loop(){
  if(coilFlag)
  {
    coilFlag = false;
    coilLedState = !coilLedState;
    digitalWrite(coilPin, coilLedState);
  }
 if(directionFlag)
  {
    directionFlag = false;
    directionLedState = !directionLedState;
    digitalWrite(directionPin, directionLedState);
  }
delay(1);   //I'm desperate I will try anything ....
} //end loop

void ISR1()
{
  Serial.println("ISR1");
  coilFlag = true;
  }

void ISR2()
{
  Serial.println("ISR2");
  directionFlag = true;
  }

```

# Answer
I'd suggest building a Faraday cage around the inductive coil. It's probably inducing enough current in all the wires around it to trigger logic level voltages in your signal wires, in the board, etc.

It sounds like the goal is for the coil to fling a magnet away, so you might have to settle for a "Faraday bowl" (an open-topped Faraday cage). Some magnetic field would leak out the top of the bowl, but if you place the control board below the bottom and several feet away it might be enough.

You might need to shield everything separately: Faraday cage around the Arduino. "Faraday Bowl" around the coil. Coax cables for everything, where the power to the coil is in a coax cable that's grounded separately, etc.
> 0 votes

---
Tags: power
---


title: What is the meaning of the term FQBN?

text:
# Question
Title: What is the meaning of the term FQBN?
So I'm reading the Platform specification and doing some programming and I'm getting the error:

```
Error missing FQBN

```

So what does FQBN mean?

# Answer
> 1 votes
My guess: Fully Qualified Board Name

I.e., a descriptor that uniquely identifies a board and its configuration.

---
Tags: terminology
---


title: Atmega Millis with Quartz crystal

text:
# Question
Title: Atmega Millis with Quartz crystal
I followed https://www.arduino.cc/en/Tutorial/ArduinoToBreadboard this tutorial to program my Atmega 328p to run on a breadboard with a 16 MHZ Quarz crystal and two 22pF capacitor. I want to program a digital clock without a RTC (code below). So I wrote my code by using millis(), and set the time exactly to the time of my mobile. After two minutes the Atmega was about a quarter minute early, but it seems to stay there. Why is that? Doesen't it use the crystal? Do I have to program it differently? Or will it stay at this time difference and run more or less accurate now?

My code:

```
#define ZERO 0b01110111
#define ONE 0b00000110
#define TWO 0b10110011
#define THREE 0b10010111
#define FOUR 0b11000110
#define FIVE 0b11010101
#define SIX  0b11110101
#define SEVEN 0b00000111
#define EIGHT 0b11110111
#define NINE 0b11010111
#define SECOND 1000
static int changed = 0;

static int led01 = 1;
static int led02 = 3;

static int led11 = 4;
static int led12 = 5;

static int state = 0;
static int selP = 0;

static int blink = 0;
static int btn_1 = 0, btn_2 = 0;

static long last = millis();
static long tm = 0;

static int seconds = 0, minutes = 45, hours = 13;

static const int DATAH1 = 2, ST_CPH1 = 3, SH_CPH1 =4;
static const int DATAH2 = 5, ST_CPH2 = 6, SH_CPH2 =7;

static const int DATAM1 = 11, ST_CPM1 = 12, SH_CPM1 =13;
static const int DATAM2 = A0, ST_CPM2 = A1, SH_CPM2 =A2;

static const char numbers[10] = {ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE};
void setup()
{
  pinMode(DATAH1, OUTPUT);
  pinMode(ST_CPH1, OUTPUT);
  pinMode(SH_CPH1, OUTPUT);

  pinMode(DATAH2, OUTPUT);
  pinMode(ST_CPH2, OUTPUT);
  pinMode(SH_CPH2, OUTPUT);

  pinMode(DATAM1, OUTPUT);
  pinMode(ST_CPM1, OUTPUT);
  pinMode(SH_CPM1, OUTPUT);

  pinMode(DATAM2, OUTPUT);
  pinMode(ST_CPM2, OUTPUT);
  pinMode(SH_CPM2, OUTPUT);

  pinMode(9, INPUT_PULLUP);
  pinMode(10, INPUT_PULLUP);
}

// main loop
void loop()
{
  long curr = millis();
  tm += curr-last;
  if(tm < 0 || tm > 900000){
    tm = 0;
  }
  last = curr;
  if(digitalRead(9) == LOW){
    if(!btn_1){
      if(state == 0){
        state = 1;
        selP = 0;
      }else{
        if(selP >= 3) state = 0;
        else selP++;
      }
      tm = 0;
      blink = 0;
    }
    btn_1 = 1;
  }else btn_1 = 0;

  if(state == 0){ //ZEIT LAEUFT
    if(tm >= SECOND){
      seconds+=tm/SECOND;
      tm = tm%SECOND;
      changed = 1;
    }
    if(seconds >= 60){
      minutes += seconds/60;
      seconds = seconds%60;
    }
    if(minutes >= 60){
      hours += minutes/60;
      minutes = minutes%60;
    }
    if(hours >= 24){
      hours = 0;
    }
  }else{ //UHR STELLEN
    if(tm>=500){
        blink = blink?0:1;
        tm = 0;
        changed = 1;
      }
    if(digitalRead(10) == LOW){
      if(!btn_2){
        changed = 1;
        switch(selP){
          case 0:
            hours+=10;
            if(hours >= 24) hours -= 20;
            break;
          case 1:
            if(hours/10 < 2){ //in else case zaehlt man die 2. Ziffer nur noch bis 3, da 24 kein Bestandteil mehr ist
              if(hours%10 == 9){
                hours-= 9;
              }else hours++;
            }else{
              if(hours%10 == 3){
                hours-= 3;
              }else hours++;
            }
          break;
          case 2:
            minutes+=10;
            if(minutes >=60) minutes = 0;
          break;
          case 3:
             if(minutes%10 == 9){
              minutes-= 9;
            }else minutes++;
        }
      }
      btn_2 = 1;
    }else btn_2 = 0;
  }
  if(changed){
    led01 = hours/10;
    led02 = hours%10;
    led11 = minutes/10;
    led12 = minutes%10;
    byte str[4];
    str[0] = numbers[led01];
    str[1] = numbers[led02];
    str[2] = numbers[led11];
    str[3] = numbers[led12];
    if(blink){
      str[selP]=str[selP]|(1<<3);
    }
    digitalWrite(ST_CPH1, LOW);
    shiftOut(DATAH1, SH_CPH1,MSBFIRST, str[0]);
    digitalWrite(ST_CPH1, HIGH);

    digitalWrite(ST_CPH2, LOW);
    shiftOut(DATAH2, SH_CPH2,MSBFIRST, str[1]);
    digitalWrite(ST_CPH2, HIGH);

    digitalWrite(ST_CPM1, LOW);
    shiftOut(DATAM1, SH_CPM1,MSBFIRST, str[2]);
    digitalWrite(ST_CPM1, HIGH);

    digitalWrite(ST_CPM2, LOW);
    shiftOut(DATAM2, SH_CPM2,MSBFIRST, str[3]);
    digitalWrite(ST_CPM2, HIGH);
  }
}

```

# Answer
> 1 votes
I don’t see anything in this code that allows you to set the time. You set it by hard coding the numbers. That’s fine but it takes some time to compile and load to the board and the board is going to start at that time you hard coded. If the board doesn’t get to start running the program for a few seconds while you upload then it’s obviously going to be a few seconds off.

It’s going to be nearly impossible to guess exactly what time the program starts running. Maybe you could set the time for several minutes into the future, upload, and then unplug and wait until exactly that time to plug the board in and start it. Remember there’s a couple seconds for the boot loader before the program starts to run. It may take some trial and error.

Or you can write code there that allows you to set the time through the serial monitor or something.

---
Tags: arduino-uno, atmega328, millis
---


# Question
Title: Print connection password typed by user on NodeMCU Lua ESP8266 ESP-12E
I want to make a WiFi Access point created with the ESP8266. Let's say that the SSID is '**net\_work**' and the password is '**12345678**'.

When a client tries to connect with a **wrong** password, I want to print that wrong password in the serial console. But nowhere in the docu I can find an event listener or something to do this... The only thing i can find in the docu is how to start the AP and wait for a successfull connection.

# Answer
> 3 votes
You can't.

The password does not exist.

In short:

* The password is used to create a key
* The key is used to encrypt the connection
* If both ends agree on the encryption then it's "connected" and packets can travel back and forth.

There is no password for you to print, only the fact that encryption didn't agree.

It actuality it's more complex than that, but that's the rough outline of how it works.

---
Tags: esp8266, wifi, nodemcu
---


title: very small PWM when timer says zero

text:
# Question
Title: very small PWM when timer says zero
I'am getting a little PWM signal when my potentiometer is at zero and OCR2B always reads zero on the serial monitor. My LED has low forward voltage but I still get a little PWM on the pin when I prob it. I use timer 1 and it works good. I have a picture of the scope.

```
#include "RTClib.h"
RTC_DS3231 rtc;

#include <ResponsiveAnalogRead.h>
ResponsiveAnalogRead analog0(A0, true, .001);

unsigned int nowHour;

int analogOutPin3 = 3;
int sensorValueTimer2Pin3;

long z;

int analogOutPin9 = 9;
int analogOutPin10 = 10;

void setup() {
  Serial.begin(9600);
  //===============mode 5 pin 3,11==================//
  TCCR2A |= (1 << COM2A1);
  TCCR2A |= (1 << COM2B1);
  TCCR2A |= (1 << WGM21);
  TCCR2A |= (1 << WGM20);
  TCCR2B |= (1 << WGM22);
  TCCR2B |= (1 << CS22);
  OCR2A = 249;   //1KHz frequency
  TCNT2 = 0;
  //====================mode 5 pin 3,11==============//

  pinMode(3, OUTPUT);

  rtc.adjust(DateTime(2014, 1, 21, 7, 0, 0));
}

void loop() {
  DateTime now = rtc.now();
  nowHour = now.hour();
  analogWrite(9, LOW);
  analogWrite(10, LOW);
  analog0.update();
  sensorValueTimer2Pin3 = ((analog0.getValue() * 249L) / 1024);
  if (nowHour >= 7 && nowHour <= 21) {
    z = sensorValueTimer2Pin3;
    OCR2B = z;
    Serial.println(OCR2B);
  }
}

```

# Answer
> 2 votes
When `analogWrite` writes 0 or 255 value, it actually disables PWM output and sets the output to 0 or 1 correspondingly (maybe just one of them). That's because there is just 256 values, but with both fully off and fully on PWM you'll need 257 values to archieve it. If you're using direct access into `OCRx`, you have to make a choice if you want to have not fully on pwm or not fully off pwm (by setting polarity with `COM2Xx`)

Btw, you should clear `TCCR2A`/`TCCR2B` as all of the timers are configured by Arduino core to be running and prepared for the analogWrites...

---
Tags: pwm, timers, rtc, potentiometer
---


# Question
Title: Problems lighting LEDs on receiving Arduino given a char array from sending Arduino in Tinkercad
The gist of the problem is that I'm trying to have an Arduino with a breadboard that has 5 buttons and 4 LEDs each led is linked with a button and the fifth button "sends" the lights that were switched on with a char array to the receiving Arduino, in this Arduino, this Arduino algo has a breadboard with 4 LEDs of the same color and with the char array I try to switch the same LEDs that were switched on in the first Arduino, my problem is when I send the char array and receive it in the second Arduino and try to run a function that runs through the array and find which points in the char array are different than 0 and turn on a led it never turns any LEDs, I know the logic is right but I don't understand why it doesn't work.

This is the design I am working with in tinkercad and will also link the project if you wish to run it on there, I assume that the problem is from tinkercad and not the code though I may be horribly wrong.

This is the sender sketch

```
#include <SoftwareSerial.h>

#define rxPin 9
#define txPin 8

// Iniciamos los pins de los 4 leds de sender y reciver
const int ledRed = 13;
const int ledBlue = 12;
const int ledGreen = 11;
const int ledWhite = 10;

// iniciamos los pins de los 5 botones
const int pushbuttonRed = 7;
const int pushbuttonBlue = 6;
const int pushbuttonGreen = 5;
const int pushbuttonWhite = 4;
const int pushbuttonEnviar = 3;

// Declaramos el estado de los 4 leds de sender y reciver
int ledStateRed = 0;
int ledStateBlue = 0;
int ledStateGreen = 0;
int ledStateWhite = 0;

char c;
char leds[7] = {'H','0','0','0','0','F','\0'};

//String cadena_final = "";
SoftwareSerial receiver =  SoftwareSerial(rxPin, txPin);

void setup() {
  pinMode(rxPin, INPUT);
  pinMode(txPin, OUTPUT);
  Serial.begin(9600);
  receiver.begin(9600);
  pinMode(ledRed, OUTPUT);
  pinMode(ledBlue, OUTPUT);
  pinMode(ledGreen, OUTPUT);
  pinMode(ledWhite, OUTPUT);
  pinMode(pushbuttonRed, INPUT);
  pinMode(pushbuttonBlue, INPUT);
  pinMode(pushbuttonGreen, INPUT);
  pinMode(pushbuttonWhite, INPUT);
  pinMode(pushbuttonEnviar, INPUT);
}

void loop() {

    // Boton Rojo
    if(digitalRead(pushbuttonRed) == 1) {
      digitalWrite(ledRed, HIGH);
      ledStateRed += 1;
      leds[1] = '1';
      if(ledStateRed % 2 == 0){
        digitalWrite(ledRed, LOW);
        leds[1] = '0';
        ledStateRed = 0;
      }
      delay(100);
    }

    // Boton Azul
    if(digitalRead(pushbuttonBlue) == 1) {
      digitalWrite(ledBlue, HIGH);
      ledStateBlue += 1;
      leds[2] = '1';
      if(ledStateBlue % 2 == 0){
        digitalWrite(ledBlue, LOW);
        ledStateBlue = 0;
        leds[2] = '0';
      }
      delay(100);
    }

    // Boton Verde
    if(digitalRead(pushbuttonGreen) == 1) {
      digitalWrite(ledGreen, HIGH);
      ledStateGreen += 1;
      leds[3] = '1';
      if(ledStateGreen % 2 == 0){
        digitalWrite(ledGreen, LOW);
        ledStateGreen = 0;
        leds[3] = '0';
      }
      delay(100);
    }

    // Boton Blanco
    if(digitalRead(pushbuttonWhite) == 1) {
      digitalWrite(ledWhite, HIGH);
      ledStateWhite += 1;
      leds[4] = '1';
      if(ledStateWhite % 2 == 0){
        digitalWrite(ledWhite, LOW);
        ledStateWhite = 0;
        leds[4] = '0';
      }
      delay(100);
    }

    // Boton Enviar
    if(digitalRead(pushbuttonEnviar) == 1) {
      // Reinicio los leds de sender para enviar otro mensaje
      ledStateWhite = 0;
      ledStateGreen = 0;
      ledStateBlue = 0;
      ledStateRed  = 0;
      digitalWrite(ledWhite, LOW);
      digitalWrite(ledRed, LOW);
      digitalWrite(ledBlue, LOW);
      digitalWrite(ledGreen, LOW);
      delay(100);
      Serial.write(leds,7);
      leds[1] = '0';
      leds[2] = '0';
      leds[3] = '0';
      leds[4] = '0';
    }
}

void printArray(char A[]){
    int i = 0;
    for(i=0;i<6;i++){
        Serial.print(A[i]);
    }
}

```

This is the receiver sketch

```
#include <SoftwareSerial.h>

#define rxPin 9
#define txPin 8

char leds2[7] = {'\0'};

// Iniciamos los pins de los 4 leds
const int Red = 4;
const int Blue = 5;
const int Green = 6;
const int White = 7;

// Creamos el boton que limpia pantalla
const int buttonClear = 10;

char c;
String recData;

SoftwareSerial receiver =  SoftwareSerial(rxPin, txPin);

void setup() {
  pinMode(rxPin, INPUT);
  pinMode(txPin, OUTPUT);
  receiver.begin(9600);
  pinMode(Red, OUTPUT);
  pinMode(Blue, OUTPUT);
  pinMode(Green, OUTPUT);
  pinMode(White, OUTPUT);

  Serial.begin(9600);
}

void loop() {
    int i=0;

    if (receiver.available()) {

      delay(100); //allows all serial sent to be received together
      while(receiver.available() && i<6) {
        leds2[i] = receiver.read();   // starts with i=0
        delay(100);
        i++;
      }
      leds2[i]='\0';
      //digitalWrite(Red,HIGH);
    }
    if(i>0) {
      lightLeds(leds2);
    }
}

void lightLeds(char A[]){
    int i;

    for(i=0;i<6;i++){
        if(A[1]=='1' || A[1]==1) digitalWrite(Red, HIGH);
        if(A[2]=='1' || A[2]==1) digitalWrite(Blue, HIGH);
        if(A[3]=='1' || A[3]==1) digitalWrite(Green, HIGH);
        if(A[4]=='1' || A[4]==1) digitalWrite(White, HIGH);
    }
}

void printArray(char A[]){
    int i = 0;
    for(i;i<6;i++){
        Serial.print(A[i]);
    }
}

```

# Answer
> 2 votes
Your "working logic" is quite unlogic:

In sender you define a char array:

char leds\[6\] = {'H','0','0','0','0','F'};

which should be

```
 char leds[7] = {'H','0','0','0','0','F','\0'}; // terminate the array

```

Here each '0' represents a led as can be seen in subroutine `Boton Enviar` Instead of assigning a state to each position 0/1 so leds\[2\]='1' would be e.g. led blue ON you write a number to it (example walk through for blue):

```
if(digitalRead(pushbuttonBlue) == 1) {
      digitalWrite(ledBlue, HIGH);
      ledStateBlue += 1;
      leds[2] = '5';  // Here should be leds[2] = '1';
      if(ledStateBlue % 2 == 0){
        digitalWrite(ledBlue, LOW);
        ledStateBlue = 0;
        leds[2] = '0';

```

so if blue and and you send (if using the terminator)

```
 leds[] = {'H','5','0','0','0','F'.'\0'};

```

On the receiver side the following happens:

```
   while(receiver.available() && i<6) {
        leds2[i++] = receiver.read();   // starts with i=1
        delay(100);
      }
      leds2[i++]='\0';
      digitalWrite(Red,HIGH);
    }
    if(i>0) {
      lightLeds(leds2);

```

so your led2 looks like

```
 {XX,'H','5','0','0','0','F'} //XX is undefined garbage might be '\0' so the array ends here

```

Solution define array as follows:

```
char leds2[7] ={'\0'};
.....
   while(receiver.available() && i<6) {
        leds2[i] = receiver.read();   // starts with i=0
        delay(100);
        i++;
      }
      leds2[i]='\0';
      // digitalWrite(Red,HIGH); // USE builtin led not one of the used as "end marker"
    }
    if(i>0) {
      lightLeds(leds2)

```

The light logic should go for the space a value is and not the value:

```
void lightLeds(char A[]){
    int i;

    for(i=0;i<6;i++){
        if(A[2]=='1' || A[2]==1) digitalWrite(Blue, HIGH);
        if(A[2]=='0' || A[2]==0) digitalWrite(Blue, LOW);
       ....
    }
}

```

To get the mix of different logics apart place both progs in an editor (eg. notepad++) side by side and look for differences in the logic. There is more than one error in the programs, fix them as proposed and it wll work (Read the comments in my code for further details).
**EDIT**
The OP had still problems with his code. I tookthe example and let it run hardware based on two UNOs, it worked but SoftwareSerial is very bad. No problem on the hardware with AltSoftSerial.h. In TinkerCAD no chance, the moment I switched to HW-Serial it worked like a charm, so here is the refined code for SENDER:

```
// Time variables
unsigned long startTime = 0;
unsigned long intervalTime = 1000; // send once a second

// Iniciamos los pins de los 4 leds de sender y reciver
const int ledRed = 13;
const int ledBlue = 12;
const int ledGreen = 11;
const int ledWhite = 10;

// iniciamos los pins de los 5 botones
const int pushbuttonRed = 7;
const int pushbuttonBlue = 6;
const int pushbuttonGreen = 5;
const int pushbuttonWhite = 4;
const int pushbuttonEnviar = 3;

// Declaramos el estado de los 4 leds de sender y reciver
int ledStateRed = 0;
int ledStateBlue = 0;
int ledStateGreen = 0;
int ledStateWhite = 0;

char c;
char leds[7] = {'H', '0', '0', '0', '0', 'F', '\0'};

//String cadena_final = "";
SoftwareSerial sender =  SoftwareSerial(rxPin, txPin);

void setup() {
  pinMode(ledRed, OUTPUT);
  pinMode(ledBlue, OUTPUT);
  pinMode(ledGreen, OUTPUT);
  pinMode(ledWhite, OUTPUT);
  pinMode(pushbuttonRed, INPUT);
  pinMode(pushbuttonBlue, INPUT);
  pinMode(pushbuttonGreen, INPUT);
  pinMode(pushbuttonWhite, INPUT);
  pinMode(pushbuttonEnviar, INPUT);
  sender.begin(19200);
  DEBUG_INTERFACE.begin(9600);
  DEBUG_INTERFACE.println("DEBUG ON");
}

void loop() {

  // Boton Rojo
  if (digitalRead(pushbuttonRed) == 1) {
    digitalWrite(ledRed, HIGH);
    ledStateRed += 1;
    leds[1] = '1';
    if (ledStateRed % 2 == 0) {
      digitalWrite(ledRed, LOW);
      leds[1] = '0';
      ledStateRed = 0;
    }
  }

  // Boton Azul
  if (digitalRead(pushbuttonBlue) == 1) {
    digitalWrite(ledBlue, HIGH);
    ledStateBlue += 1;
    leds[2] = '1';
    if (ledStateBlue % 2 == 0) {
      digitalWrite(ledBlue, LOW);
      ledStateBlue = 0;
      leds[2] = '0';
    }
  }

  // Boton Verde
  if (digitalRead(pushbuttonGreen) == 1) {
    digitalWrite(ledGreen, HIGH);
    ledStateGreen += 1;
    leds[3] = '1';
    if (ledStateGreen % 2 == 0) {
      digitalWrite(ledGreen, LOW);
      ledStateGreen = 0;
      leds[3] = '0';
    }
  }

  // Boton Blanco
  if (digitalRead(pushbuttonWhite) == 1) {
    digitalWrite(ledWhite, HIGH);
    ledStateWhite += 1;
    leds[4] = '1';
    if (ledStateWhite % 2 == 0) {
      digitalWrite(ledWhite, LOW);
      ledStateWhite = 0;
      leds[4] = '0';
    }
  }

  // Boton Enviar
  if (digitalRead(pushbuttonEnviar) == 1) switchAll();

    if (millis() - startTime > intervalTime) {
    DEBUG_INTERFACE.println(leds);
    sender.println(leds);
    startTime = millis();
  }
}

void switchAll() {
  // Reinicio los leds de sender para enviar otro mensaje
  ledStateWhite = 0;
  ledStateGreen = 0;
  ledStateBlue = 0;
  ledStateRed  = 0;
  digitalWrite(ledWhite, LOW);
  digitalWrite(ledRed, LOW);
  digitalWrite(ledBlue, LOW);
  digitalWrite(ledGreen, LOW);
  DEBUG_INTERFACE.println(leds);
  leds[1] = '0';
  leds[2] = '0';
  leds[3] = '0';
  leds[4] = '0';
}

```

and the code for RECEIVER:

```
// Iniciamos los pins de los 4 leds
const int Red = 4;
const int Blue = 5;
const int Green = 6;
const int White = 7;

// Creamos el boton que limpia pantalla
const int buttonClear = 10;

char rc;
const int maxChar = 6;
static byte charCount = 0;
char leds2[7] = {'\0'};
bool newData = false;

#define DEBUG_INTERFACE Serial
#define receiver Serial

void setup() {
  receiver.begin(9600);
  pinMode(Red, OUTPUT);
  pinMode(Blue, OUTPUT);
  pinMode(Green, OUTPUT);
  pinMode(White, OUTPUT);

  DEBUG_INTERFACE.begin(9600);
  DEBUG_INTERFACE.println("DEBUG ON");
}

void loop() {
  receiveStartEndMarkers();
  if (newData) {
    DEBUG_INTERFACE.print(" LED Array received: ");
    DEBUG_INTERFACE.println(leds2);
    lightLeds(leds2);
    newData = false;
  }
}

void lightLeds(char A[]) {
  for (int i = 0; i < 6; i++) {
    if (A[1] == '1' || A[1] == 1) digitalWrite(Red, HIGH);
    if (A[2] == '1' || A[2] == 1) digitalWrite(Blue, HIGH);
    if (A[3] == '1' || A[3] == 1) digitalWrite(Green, HIGH);
    if (A[4] == '1' || A[4] == 1) digitalWrite(White, HIGH);
    if (A[1] == '0' || A[1] == 0) digitalWrite(Red, LOW);
    if (A[2] == '0' || A[2] == 0) digitalWrite(Blue, LOW);
    if (A[3] == '0' || A[3] == 0) digitalWrite(Green, LOW);
    if (A[4] == '0' || A[4] == 0) digitalWrite(White, LOW);
  }
  DEBUG_INTERFACE.print(A); DEBUG_INTERFACE.println(" Leds switched");
}

void receiveStartEndMarkers() {
  static boolean recvInProgress = false;
  char startMarker = 'H';
  char endMarker = 'F';

  if (receiver.available() > 0) {
    rc = receiver.read();
    //DEBUG_INTERFACE.print(rc);
    if (recvInProgress) {
      if (rc != endMarker) {
        leds2[charCount] = rc;
        charCount++;
        if (charCount > maxChar) {
          charCount = maxChar;
        }
      }
      else {
        leds2[charCount] = rc;
        charCount++;
        leds2[charCount] = '\0'; // terminate the string
        recvInProgress = false;
        charCount = 0;
        newData = true;
      }
    }
    else if (rc == startMarker) {
      recvInProgress = true;
      leds2[charCount] = rc;
      charCount++;
    }
  }
}

```

Working code looks like this - change to HW-Serial 0(RX), 1(TX) to 1(TX), 0(RX):
So as a result **DO NOT USE SoftwareSerial.h in TinkerCAD** \- its not working at the moment, use HW serial for communication examples or you will get crazy if working code suddenly outputs garbagge. When using real hardware use AltSoftSerial (full duplex mode). If you plan to use your design with real hardware use resistors for the LEDs (search for resistor calculator LED) as different colored leds need different resistor values.

---
Tags: arduino-uno
---


title: Using ESP8266-01 with Arduino uno R3

text:
# Question
Title: Using ESP8266-01 with Arduino uno R3
I am trying to learn how to use ESP-01(AI-Cloud, Black Version) with arduino

Initially, I created an adapter for it that has 4 inputs: RX, TX, Vcc(3.3v), GND I checked it and the wiring seems fine then I attached TX of arduino to TX of ESP and same with RX but with a voltage divider (1k ohm,2kohm),I uploaded arduino with a blank sketch and tried to run commands like AT and AT+CWMODE? but I got no response on the serial monitor.I tried to look for a proper tutorial to do this but, all tutorials show how to upload a sketch to ESP rather than arduino. Then I searched and found this piece of code:

```
#include <SoftwareSerial.h>

#define DEBUG true

SoftwareSerial esp8266(2,3); // make RX Arduino line is pin 2, make TX Arduino line is pin 3.
                            // This means that you need to connect the TX line from the esp to the Arduino's pin 2
                            // and the RX line from the esp to the Arduino's pin 3
void setup()
{
 Serial.begin(9600);
 esp8266.begin(115200); // your esp's baud rate might be different

 sendData("AT+RST\r\n",2000,DEBUG); // reset module
 sendData("AT+CWMODE=2\r\n",1000,DEBUG); // configure as access point
 sendData("AT+CIFSR\r\n",1000,DEBUG); // get ip address
 sendData("AT+CIPMUX=1\r\n",1000,DEBUG); // configure for multiple connections
 sendData("AT+CIPSERVER=1,80\r\n",1000,DEBUG); // turn on server on port 80
}

void loop()
{
 if(esp8266.available()) // check if the esp is sending a message
 {
   /*
   while(esp8266.available())
   {
     // The esp has data so display its output to the serial window
     char c = esp8266.read(); // read the next character.
     Serial.write(c);
   } */

   if(esp8266.find("+IPD,"))
   {
    delay(1000);

    int connectionId = esp8266.read()-48; // subtract 48 because the read() function returns
                                          // the ASCII decimal value and 0 (the first decimal number) starts at 48

    String webpage = "<h1>Hello</h1>&lth2>World!</h2><button>LED1</button>";

    String cipSend = "AT+CIPSEND=";
    cipSend += connectionId;
    cipSend += ",";
    cipSend +=webpage.length();
    cipSend +="\r\n";

    sendData(cipSend,1000,DEBUG);
    sendData(webpage,1000,DEBUG);

    webpage="<button>LED2</button>";

    cipSend = "AT+CIPSEND=";
    cipSend += connectionId;
    cipSend += ",";
    cipSend +=webpage.length();
    cipSend +="\r\n";

    sendData(cipSend,1000,DEBUG);
    sendData(webpage,1000,DEBUG);

    String closeCommand = "AT+CIPCLOSE=";
    closeCommand+=connectionId; // append connection id
    closeCommand+="\r\n";

    sendData(closeCommand,3000,DEBUG);
   }
 }
}

String sendData(String command, const int timeout, boolean debug)
{
   String response = "";

   esp8266.print(command); // send the read character to the esp8266

   long int time = millis();

   while( (time+timeout) > millis())
   {
     while(esp8266.available())
     {

       // The esp has data so display its output to the serial window
       char c = esp8266.read(); // read the next character.
       response+=c;
     }
   }

   if(debug)
   {
     Serial.print(response);
   }

   return response;
}

```

I hooked pins according to the code and it worked serial monitor output some lines but with allot of garbage values, This also created a wifi hotspot 'AI-Thinker' which I connected to and opened Ip as shown on debugging. This made ESP try to send string 'webpage' but mostly was garbage.

so my question is, how to properly use esp with arduino to maybe just switch an led on or send data from sensors, super basics?

Is it better to use esp Library and upload sketches to esp and control arduino with it?

Can some one suggest the proper tutorial for this? because even after all this I am still confused that is RX of arduino connected to RX(which makes no sense but given in many of google images) or TX of ESP-01?

# Answer
To confirm that the serial communication is working, connect the ESP to the Arduino D10 and D11 that is used as SoftSerial pins.

```
+----+
| PC |
+--/-+
   |       +---------+
   \-------| Arduino |
     USB   +--.------+
              | SoftSerial
              |
           +--\----+
           | ESP01 |
           +-------+

```

And then upload this code to the Arduino. The code is from https://www.arduino.cc/en/Tutorial/SoftwareSerialExample

```
/*
 Receives from the hardware serial, sends to software serial.
 Receives from software serial, sends to hardware serial.

 The circuit:
 * RX is digital pin 10 (connect to TX of ESP01)
 * TX is digital pin 11 (connect to RX of ESP01)

 Created back in the mists of time
 modified 25 May 2012
 by Tom Igoe
 based on Mikal Hart's example

 This example code is in the public domain.
 */

#include <SoftwareSerial.h>

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

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(115200);
  while (!Serial) {
    ;
  }

  Serial.println("Goodnight moon!");

  // Set the data rate for the SoftwareSerial port
  mySerial.begin(115200);
  mySerial.println("Hello, world?");
}

void loop() {

  if (mySerial.available()) {
    Serial.write(mySerial.read());
  }
  if (Serial.available()) {
    mySerial.write(Serial.read());
  }
}

```
> 1 votes

# Answer
```
#include <WiFiEsp.h>
#include <WiFiEspClient.h>
#include <SoftwareSerial.h>

...

SoftwareSerial wifiSerial(WIFI_RX, WIFI_TX);
WiFiEspClient WIFI_CLIENT;

...

void setup() {
  wifiSerial.begin(9600); // or 115200
  WiFi.init(&wifiSerial);
  if (WiFi.status() == WL_NO_SHIELD) {
    printLog("WiFi shield not present");
    // don't continue
    while (true);
  }
  printLog("Connecting to AP ...");
  WiFi.begin(WIFI_SSID, WIFI_PASS);
  printLog("Connected to AP");
}

...

```
> 1 votes

# Answer
The `TX` pin of the Arduino goes into the `RX` pin of the ESP and vice versa: that's the way serial communication works, apart for voltage level considerations.

Another factor you have to take into consideration is the two devices MUST operate at the same speed, once known as *Baud Rate*: I believe 115200 might be the ESP default speed, but that's programmable. There are also other two additional parameters which play a role in serial communication, *Parity* and *Data bits*, but the default values are more than likely fine and you shouldn't worry about those.

So, in essence, verify your wiring and set the right speed considering some ESP modules run a firmware using non standard speed for serial comm.
> 0 votes

---
Tags: arduino-uno, serial, esp8266, wifi
---


# Question
Title: How send method POST with JSON? Arduino UNO R3 + SIM900
Why is the server side of php not loading any data from arduino? What did I do wrong?

```
  String reading="{\"latitude\": 12.983027,  \"longitude\": 80.2594}";
  mySerial.println("AT+HTTPINIT");
  toSerial(1000);

  mySerial.println("AT+HTTPPARA=\"CID\",1");
  toSerial(1000);

  mySerial.println("AT+HTTPPARA=\"URL\",\"http://gerro.usermd.net/updateData.php\"");
  toSerial(1000);

  mySerial.println("AT+HTTPPARA=\"CONTENT\", \"application/json\"");
  toSerial(1000);

  mySerial.println("AT+HTTPDATA=" + String(reading.length()) + ",100000");
  toSerial(5000);

  mySerial.println(reading);
  toSerial(1000);

  mySerial.println("AT+HTTPACTION=1");
  toSerial(15000);

  mySerial.println("AT+HTTPREAD");
  toSerial(1000);

  mySerial.println("AT+HTTPTERM");
  toSerial(500);

```

**Result:**

```
AT+HTTPINIT

OK
AT+HTTPPARA="CID",1

OK
AT+HTTPPARA="URL","http://gerro.usermd.net/updateData.php"

OAT+HTTPPARA="CONTENT", "application/json"

OK
AT+HTTPDATA=46,100000

DOWNLOAD

OK
AT+HTTPACTION=1

OK

+HTTPACTION:1,200,55
AT+HTTPREAD

+HTTPREAD:55
array(0) {
}
array(0) {
}
nic ciekAT+HTTPTERM

OK

```

**EDITING**

```
void toSerial(int delay_ms)
  {
    delay(delay_ms);

    while(mySerial.available())
    {
       Serial.write(mySerial.read());
    }
  }

```

**PHP**

```
<?php
var_dump($_POST);
if (isset($_POST['latitude']) && isset($_POST['longitude']) && $_SERVER['REQUEST_METHOD'] === 'POST') {
//code
} else {
echo 'nic';
}

```

# Answer
> 1 votes
You had to change the php file:

```
var_dump($_POST);

```

to:

```
echo print_r(json_decode(file_get_contents("php://input")));

```

Thank you !

---
Tags: arduino-uno, json
---


title: PC8563 Arduino interface

text:
# Question
Title: PC8563 Arduino interface
i am trying to interface pc8563 with arduino uno . I have small doubt related to RTC slave address reading

RTC datasheet says page no 14 where device slave address is A2 for write and Read A3 i would like to know how A2 /A3

Example code from website device id mentioned as 0X51

**My question how to config exact slave address ??**

```
#include "Wire.h"
#define PCF8563address 0x51

byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
String days[] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };

byte bcdToDec(byte value)
{
  return ((value / 16) * 10 + value % 16);
}

byte decToBcd(byte value){
  return (value / 10 * 16 + value % 10);
}

void setPCF8563()
// this sets the time and date to the PCF8563
{
  Wire.beginTransmission(PCF8563address);
  Wire.write(0x02);
  Wire.write(decToBcd(second));
  Wire.write(decToBcd(minute));
  Wire.write(decToBcd(hour));
  Wire.write(decToBcd(dayOfMonth));
  Wire.write(decToBcd(dayOfWeek));
  Wire.write(decToBcd(month));
  Wire.write(decToBcd(year));
  Wire.endTransmission();
}

void readPCF8563()
// this gets the time and date from the PCF8563
{
  Wire.beginTransmission(PCF8563address);
  Wire.write(0x02);
  Wire.endTransmission();
  Wire.requestFrom(PCF8563address, 7);
  second     = bcdToDec(Wire.read() & B01111111); // remove VL error bit
  minute     = bcdToDec(Wire.read() & B01111111); // remove unwanted bits from MSB
  hour       = bcdToDec(Wire.read() & B00111111);
  dayOfMonth = bcdToDec(Wire.read() & B00111111);
  dayOfWeek  = bcdToDec(Wire.read() & B00000111);
  month      = bcdToDec(Wire.read() & B00011111);  // remove century bit, 1999 is over
  year       = bcdToDec(Wire.read());
}

void setup()
{
  Wire.begin();
  Serial.begin(9600);
  // change the following to set your initial time
  second = 0;
  minute = 28;
  hour = 9;
  dayOfWeek = 2;
  dayOfMonth = 13;
  month = 8;
  year = 13;
  // comment out the next line and upload again to set and keep the time from resetting every reset
  setPCF8563();
}

void loop()
{
  readPCF8563();
  Serial.print(days[dayOfWeek]);
  Serial.print(" ");
  Serial.print(dayOfMonth, DEC);
  Serial.print("/");
  Serial.print(month, DEC);
  Serial.print("/20");
  Serial.print(year, DEC);
  Serial.print(" - ");
  Serial.print(hour, DEC);
  Serial.print(":");
  if (minute < 10)
  {
    Serial.print("0");
  }
  Serial.print(minute, DEC);
  Serial.print(":");
  if (second < 10)
  {
    Serial.print("0");
  }
  Serial.println(second, DEC);
  delay(1000);
}

```

RTC datasheet

# Answer
Normal I2C addresses are 7-bit long. On the first frame of an I2C transaction, the master sends an 8-bit byte containing the address of the slave followed by a bit specifying whether this is a read or a write operation. Some people tend to call “address” the whole 8-bit frame, which causes confusion. Because of this, we end up having three flavors of I2C addresses:

* the 7-bit address, which is the real device address
* the 8-bit “write address”, which is the address followed by a 0 meaning “write operation”
* the 8-bit “read address”, which is the address followed by a 1 meaning “read operation”

For your RTC, the 3 addresses are the following, in hex and binary:

```
7-bit = 0x51 = 0b1010001
write = 0xA2 = 0b10100010
read  = 0xA3 = 0b10100011

```

The Arduino Wire library expects the 7-bit address.
> 2 votes

---
Tags: arduino-uno, i2c, rtc
---


title: Timer Accuracy Always off by 1uS

text:
# Question
Title: Timer Accuracy Always off by 1uS
I am using the ATMega32u4 to generate a pulse at 1 kHz. I am using Timer 3, which is a 16-bit timer and using a prescaler of 1, so I have a 0.0625uS resolution. The good news is that this is working, I can control the frequency and pulse length of the square wave. The issue is that I noticed the pulse always seems to be 1uS off.

If I set a period of 1000uS, and a pulse of 500uS, the oscilloscope shows a period of 1001uS and a pulse of 501uS.

If I set a period of 100uS, and pulse of 10uS, the oscilloscope shows a period of 101uS, and a pulse of 11uS.

If the Timer had an error percentage, then both the period and pulse should be off by the same percentage, but there are always off by the same 1uS length. I assume I am doing something wrong, so I have posted my code below.

```
const int pin1 = 4;

void setup() {
  //Set pin to output
  pinMode(pin1, OUTPUT);

  // Reset Timer 3 Control Register to 0
  TCCR3A = 0;

  // Set prescaler to 1
  TCCR3B &= ~(1 << CS32); //0
  TCCR3B &= ~(1 << CS31); //0
  TCCR3B |= (1 << CS30);  //1

  //Reset Timer 3 and set compare value
  TCNT3 = 0;

  // Enable Timer 3 compare interrupt A and B
  TIMSK3 |= (1 << OCIE3B);
  TIMSK3 |= (1 << OCIE3A);

  //Enable global interrupts
  sei();

  //Set Refresh Rate
  OCR3A = 1000;
  OCR3B = 100 / 0.0625;
}

void loop() {
  delay(100);
}

ISR(TIMER3_COMPA_vect) {
  PORTD &= ~_BV(pin1); //LOW
  OCR3A = 160;
}

ISR(TIMER3_COMPB_vect) {
  TCNT3 = 0;
  PORTD |= _BV(pin1); //HIGH
}

```

# Answer
> 4 votes
The problem is here:

```
ISR(TIMER3_COMPB_vect) {
  TCNT3 = 0;
  ...

```

If you want to get anything that vaguely looks like accurate timings, you should **never** reset the timer. The MCU needs time to process an interrupt: it has to save the program counter to the stack, load the address of the interrupt vector, execute it (it's typically a jump), save all the registers it needs to the stack, and only then can it start executing the code you wrote in the ISR. From your experiment, it looks like all this process takes about 1 µs. But don't take this delay for granted: from time to time the interrupt will fire while the MCU is processing another interrupt, and this will increase the latency.

You have two options:

1. Update the compare registers in order to program the next interrupts some time in the future. In this case, the COMPB ISR would do `OCR3A = OCR3B + 160; OCR3B += 1600;`. Do not worry about the overflows: they do the Right Thing.
2. Let the timer reset itself to zero: it will then do so without loosing a single cycle. See the CTC and fast PWM modes of the timer.

For your specific use case, PWM seems like the obvious choice. Not only will the timer handle the resetting itself, it can also generate the output signal without requiring you to write any ISR. Beware that in this case the period of the signal is whatever you load in corresponding compare register *plus one*, and the duration of the pulse is another compare register *plus one*.

As a side note:

```
  // Reset Timer 3 Control Register to 0
  TCCR3A = 0;

```

I would also reset `TCCR3B`. The Arduino core configures both registers for it's own purposes, so it would be safer to clear them both.

---
Tags: timers
---


title: How to use DO pin on ldr module?

text:
# Question
Title: How to use DO pin on ldr module?
I have ldr module with 4 pins 1. Vin 2. Gnd 3. AO 4. DO

I want to know how can i take advantage of DO suppose i want to turn on lcd display when light falls on the ldr sensor!

I have noticed when light falls on ldr sensor the Green led with DO written next to it lights up.

# Answer
The DO pin gives a Digital Output that is HIGH when the light falling on the LDR is above a threshold, and LOW when it's below a threshold. Just connect it to a digital input pin and read that pin with `digitalRead()`.

You can change the threshold by adjusting the small blue trimpot.
> 1 votes

---
Tags: sensors
---


title: 5 arrays or one matrix?

text:
# Question
Title: 5 arrays or one matrix?
I am working on a project where i need to store as fast I can following :

1 - Acceleration on X

2 - Acceleration on Y

3 - Acceleration on Z

4 - timestamp

5 - A value from some other sensor

Because I need to get these as fast as I can I am thinking to not do any calculation while acquire values and just store them for 30 -60 seconds and then when the "test" is complete to compute calculations. My question is if will be better to create 5 arrays and put these values there or create a matrix and store values there. I need these values to be stored like they are "connected" e.g. on reading 1 i get 5 values and put them on array\[0\] , then on reading 1 and so on Also an important thing to mention, this will run on a esp32.

Thank you

# Answer
> 3 votes
I fully agree with Edgar Bonet.

My opinion is keeping a 'matrix' is better, or actually one array (of structs), where each array elements stores all information for one measurement (which is stored inside one struct). This has some benefits:

* Data of one measurement is consecutive in memory, so you can easily transfer it (to some external memory or sending it). It's exact one struct (and you can use `sizeof(struct_item)` to know how many bytes you have to transfer.
* It's good practice in general to keep information together, creating 5 always-equal length arrays seems strange.
* If for some reason you want to make a single array dynamic or change it to a ring buffer for example, you can easily add/remove items (instead of dynamically changing 5 arrays).
* Locality of change (see comments of Kwasmich/DuncanC)

There is also one benefit about having separate arrays (where each array stores one type of information, like an acceleration or timestamp: when you have a function (especially in another class) that only needs one of them, you can specifically send that array (or pointer/reference), so the other information is hidden from that function.

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


# Question
Title: src folder in sketch structure and include library from subfolder
My Arduino/PlatformIO libraries folder

```
libraries
└── cleaner_robot
    └── TB6612_Dual
        ├── tb6612_dual.h
        └── tb6612_dual.cpp

```

I used this code to innclude it:

```
#include <TB6612_Dual/tb6612_dual.h>

```

But the compilation has errors like "undefinded variables, undefinded reference,...etc"

This is my sketch folder

```
Cleaner_Robot
└── src
    └── TB6612_Dual
        ├── tb6612_dual.cpp
        └── tb6612_dual.h

```

If i use this code, all is ok

```
#include "src/libs/TB6612_Dual/tb6612_dual.h"

```

So the question is how to include if header file is in a sub folder of a folder in libraries folder of Arduino/PlatformIO ?, i has searched for many things, but cant help. I also read about src folder allowed in Arduino, but where can find an official announcement/manual for this structure ?, cant find much about this

Thanks :)

# Answer
> 1 votes
I could include header files in subfolder after including root header file.

```
#include <TB6612_Dual.h>
#include <TB6612_Dual/tb6612_dual.h>

```

```
TB6612_Dual
└── src
    ├── TB6612_Dual.h << Add this empty file.
    └── TB6612_Dual
        ├── tb6612_dual.cpp
        └── tb6612_dual.h

```

Examples:

---
Tags: arduino-ide, library
---


# Question
Title: HID communication between Arduino Uno and computer
I used some firmware I found online to turn the UNO into an emulated HID device. The Arduino is no longer connected to a Serial COM port so I can't send serial data from my computer to the device. Is there a way that the Arduino can receive data from the computer in order to drive a function while in the HID emulated state?

# Answer
> 1 votes
You could use a second USB on the PC and use Hardware Serial to transmit commands. (Either via a second Arduino or a FTDI adapter)
But be aware that at least the firmware I use and the controller programs are very sensitive to being disturbed in the loop. So you should have a good understanding of timers, interupts and non blocking code.

---
Tags: arduino-uno, communication, hid
---


title: Vin & VU pins of NodeMCU V3

text:
# Question
Title: Vin & VU pins of NodeMCU V3
Can we use the vin pin of the lolin v3 nodeMCU as a 5V supply. If yes, i checked mine with a multimeter. At max, it gives a voltage of 2V. Is my pin blown out? Also, can use the VU pin as a 5V supply? Will using it cause any problems to my laptop's USB port? Can somebody help me out?

I need 5V to drive a relay using the v3

# Answer
On the NodeMCU “v3” (and only on the v3) there’s a pin called VU (Vusb) that is connected to the +5V on the USB bus of the NodeMCU socket. This pin can be used to feed external components when it’s connected to USB, within the limits of the USB power supply it’s connected to.

The Vin pin (which is available on all NodeMCUs (and not just the v3) is a +5V power *input* which can be used to power the NodeMCU if it is not connected to USB. It can not be used as an output and it needs a stabilized supply.
> 9 votes

---
Tags: nodemcu
---