# Question
Title: DFRobot GSM / GPS shield with UNO init error
Apologies, but I have little experience of Arduino etc. Has the "Sim808 init error" been resolved anywhere please? I have tried every example I can find including the ones on these StackExchange pages without success. I started with the GPS test code from:

https://wiki.dfrobot.com/SIM808\_GPS\_GPRS\_GSM\_Shield\_SKU\__TEL0097

Parancey, Marcello, Pooya and Arslan and others have suggested mods to this code so I have tried all of them I think - none working.

Then I watched this video:

https://www.youtube.com/watch?v=fN8fwX3KmsM

which appears to show the code below or similar:

```
/*
### Get GPS data
1. This example is used to test SIM808 GPS/GPRS/GSM Shield's reading GPS data.
2. Open the SIM808_GetGPS example or copy these code to your project
3. Download and dial the function switch to Arduino
4. open serial helper
4. Place it outside, waiting for a few minutes and then it will send GPS data to serial

create on 2016/09/23, version: 1.0
by jason

*/
#include <DFRobot_sim808.h>
#include <SoftwareSerial.h>

//#define PIN_TX    10
//#define PIN_RX    11
//SoftwareSerial mySerial(PIN_TX,PIN_RX);
//DFRobot_SIM808 sim808(&mySerial);//Connect RX,TX,PWR,

DFRobot_SIM808 sim808(&Serial);

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

  //******** Initialize sim808 module *************
  //while(!sim808.init()) {
  while(!sim808.checkPowerUp()) {
      delay(1000);
      Serial.print("Sim808 init error\r\n");
  }

  //************* Turn on the GPS power************
  if( sim808.attachGPS())
      Serial.println("Open the GPS power success");
  else
      Serial.println("Open the GPS power failure");

}

void loop() {
   //************** Get GPS data *******************
   if (sim808.getGPS()) {
    Serial.print(sim808.GPSdata.year);
    Serial.print("/");
    Serial.print(sim808.GPSdata.month);
    Serial.print("/");
    Serial.print(sim808.GPSdata.day);
    Serial.print(" ");
    Serial.print(sim808.GPSdata.hour);
    Serial.print(":");
    Serial.print(sim808.GPSdata.minute);
    Serial.print(":");
    Serial.print(sim808.GPSdata.second);
    Serial.print(":");
    Serial.println(sim808.GPSdata.centisecond);

    Serial.print("latitude :");
    Serial.println(sim808.GPSdata.lat,6);

    sim808.latitudeConverToDMS();
    Serial.print("latitude :");
    Serial.print(sim808.latDMS.degrees);
    Serial.print("\^");
    Serial.print(sim808.latDMS.minutes);
    Serial.print("\'");
    Serial.print(sim808.latDMS.seconeds,6);
    Serial.println("\"");
    Serial.print("longitude :");
    Serial.println(sim808.GPSdata.lon,6);
    sim808.LongitudeConverToDMS();
    Serial.print("longitude :");
    Serial.print(sim808.longDMS.degrees);
    Serial.print("\^");
    Serial.print(sim808.longDMS.minutes);
    Serial.print("\'");
    Serial.print(sim808.longDMS.seconeds,6);
    Serial.println("\"");

    Serial.print("speed_kph :");
    Serial.println(sim808.GPSdata.speed_kph);
    Serial.print("heading :");
    Serial.println(sim808.GPSdata.heading);

    //************* Turn off the GPS power ************
    sim808.detachGPS();
  }

}

```

I have mounted the DFRobot shield on a UNO and powered through the barrel connector with a 2\_amp 5V stabilised power supply. The DFRobot shield shows a red LED power light and pressing reset flashes the blue LED next to it, but nothing else does anything - the serial monitor just repeats "Sim808 init error". In the video the blue "net" LED flashes even before the SIM card is inserted, but my card does not flash. Do I return the board to Farnell and ask for my money back?

Any help greatly appreciated!

# Answer
The dfrobot board has a weird boot button system that you need to follow to boot up the board. I spent ages attempting to get it to work before I finally achieved anything.

There is a blue led on the board that will flash continuously at different rates if the chip has been correctly powered and is searching for a mobile network.

I noticed that you commented it the while(!sim808.init()) line. This attempts to power the board on automatically, but I do remember something being funny about the implementation.

From doing a while load of research the dfrobot breakout board is not the best hardware implementation of this chip. Actually from memory there aren't any modules I have been able to find which satisfy all my requirements for a project. I'd recommend looking at all the documentation dfrobot provide on their website. Hopefully that should get you working.

Summary: it's an insanely fiddly process to get it working, but the boards are functional
> 1 votes

---
Tags: gsm, gps, error
---


title: Pullup on compatible Arduino Mega

text:
# Question
Title: Pullup on compatible Arduino Mega
I've got an Arduino mega compatible board, called Ethermega, from Freetronics (ATmega2560).

Schematic here.

In setup, I've written this code:

Serial.begin(9600);

```
  pinMode(4, INPUT_PULLUP);
  digitalWrite(4, HIGH); // Optional, I tried with and without
  while (1)
  {
    if (digitalRead(4) == HIGH)
    {
      Serial.write("Up!\n");
    }
  }

```

(Don't worry about the fact I'm not using loop)

When I connect input 4 with 5V, I see "Up!". Rest of the time, I see nothing.

Considering I have enabled the internal pull-up, I'm expecting it should be up/high by default, and I would have to connect it to GND to get it low...

Another thing that puzzles me is I can find heaps of examples that use a tactile switch and no pullup/pulldown at all...

So what am I missing or doing wrong? Seems like whatever I do, I've got some kind of pulldown enabled...

# Answer
As @Juraj mentions, pin 4 is the CS pin for the SD card. That pin has a volage divider of 1kΩ + 2.2kΩ on it (a total of 3.2kΩ) to ground. So yes, you do have a pulldown on that pin. 3.2kΩ is about 1/10th of the value of the typical pullup resistor internal to the chip, so pulls the output low enough to be seen as LOW unless you manually override it.

You can't use that pin as an *active low* input on that board - choose another, or use it as *active high*.
> 1 votes

---
Tags: arduino-mega
---


# Question
Title: digitalRead() function of Arduino doesn't read Input value sent by sensor after detecting the object
I'm trying to turn ON the LED(inbuilt/PIN13) when photoelectric proximity sensor(12v) senses any object. Sensor is connected on pin 2. Assigned pin 2 as INPUT, I've got a 12v spdt relay for switching. 12v output from sensor is fed to coil, on the other end 5v supplied to COM pin and "Normally Open"(NO) pin to Arduino (with pull-down resistor). When 'NO' connected to loose LED it works properly (shows 5V on voltmeter when object is detected). But when connected to Arduino digitalRead(), it always returns LOW/0.

```
//code
int a=0;
void setup() {
  pinMode(2,INPUT);
  pinMode(13,OUTPUT);
  Serial.begin(9600);
}

void loop() {
  a ==  digitalRead(2);
  Serial.println(a);
  if(a==HIGH){
    Serial.println("Object Detected");
    digitalWrite(13,HIGH);
  }else{
    Serial.println("There's no object");
    digitalWrite(13,LOW);
  }
  delay(1000);
}

```

# Answer
`a == digitalRead(2)` must be `a = digitalRead(2)`. You also better change the if clause to `if(a)` to avoid `true/HIGH/1` confusions.

If you had formatted the code properly, you'd have safed some time (you just need to select the code and press the `{}` button).

You also better replace the relay with a voltage divider (as I mentioned in my comment), because as long as you don't have a datasheet for the sensor you can't be sure that the sensor is designed to source that much current. If the sensor is supposed to drive a TTL logic, it will eventually fail, just like you don't drive relays with GPIOs directly. And beside that you *need a freewheeling diode across the relay coil* to deal with back EMF which will also harm the sensor.
> 2 votes

---
Tags: arduino-uno, sensors, relay, digital
---


title: Short circuiting GND and power pins

text:
# Question
Title: Short circuiting GND and power pins
I have created an arduino shield and i want to measure the voltage between the GND pin and 5V pins, to see if i see a voltage difference between the two points, in order to test if my pcb is fine.

My concern is since these are right next to each other and my multimeter probes are thick.

If the multimeter probe that 5V pin touches the GND pin, in other words, if i short circuit the 5V and GND pins, then will my arduino be safe?

I am afraid of damaging the arduino.

# Answer
> 1 votes
It all depends on how you are powering the board.

If you're running it from USB then the computer should shut off the power to the USB port. If it doesn't then the Arduino has a small self-resetting fuse on the USB power which should shut the power off for you.

However if you're powering through the barrel jack there's no protection. Worst case scenario: it will blow the voltage regulator, which then "fails short", meaning it passes the whole of the input voltage through to the microcontroller, which then kills it.

So yes, it's possible to damage the Arduino with a short circuit.

Most multimeters have a better way of testing the board though: either the "beepy" continuity test, or the resistance mode. You can use that to test the continuity or resistance between your 5V and GND pins without having to connect the shield to the Arduino at all. 100% safe.

# Answer
> 1 votes
No, shorting +5 to Gnd is not safe, although a brief short might not cause damage. If it persists, you could burn a trace, overheat the voltage regulator, or damage the computer USB if that is what powers your Arduino. Most computers will sense that short and disconnect power to that USB until the short goes away, but you don't want to count on it!

If your meter has probes with clip-ends, use those to clip two bread-board wires, and probe the Arduino pins by plugging the wires into your shield. If the shield has no pin sockets installed, at least the bread-board wires are small enough not to short adjacent pins.

# Answer
> 1 votes
mostly yes , mostly no . my old arduino got a little too much dusty and when i cleaned it with mild amount of water (nervously) and dried it partially . nothing happened to it . it was operating normally . but some beginner manuals tell not to short circuit it . dunno what's going on ...

---
Tags: power, pins
---


title: need to use jp2 because need extra pins

text:
# Question
Title: need to use jp2 because need extra pins
i clearly understand jp2 is the extra leftover pins of atmega16u2 . but how to access it ? i find my arduino has less pins and jp2 are the only ones left . but if it is not accessable , why do they have it ? and also , if it requires seperate programing of the atmega16u2 , i'd like to know how . i completely dunno a thing about atmega16u2 . only thing i understand is that it makes the arduino more compatible with the usb input ...

thanks alot !

# Answer
> if it requires seperate programing of the atmega16u2,

It does. Often an ATMega8U2 is used here instead though.

> i'd like to know how.

You might start by having a look at HoodLoader2 and NicoHood's related projects.

This involves replacing the normal Xu2 transceiver firmware with HoodLoader. There are different ways to do that outlined in the installation instructions. If you don't have an ISP programmer or a second Arduino to behave as one, there's a method that involved burning an installer-sketch to the 328P which turns around and reprograms the Xu2 chip.

Once you have that done you can use their board definitions for put sketches onto the ATMegaXU2 itself.

Apparently, JP2's layout is flipped on some boards. So, beware of that. In any case, the header it makes the ATMegaXU2's PB4, PB4, PB6, and PB7 available. Sketches on the XU2 would use the Hoodloader pin mapping of these:

| Arduino Pin No. | AVR GPIO PIN |
| --- | --- |
| D4 | PB4 |
| D5 | PB5 |
| D6 | PB6 |
| D7 | PB7 |

Or course, now you need to find some way to coordinate what happens on the ATMegaXU2 with the ATMega328P.

> i find my arduino has less pins and jp2 are the only ones left.

There are clever ways to reuse pins on microcontrollers. For example, it is possible to put an LED and a switch on the same GPIO pin. And there are GPIO expanders, SPI/I2C ADCs, etc.

Messing with JP2 and programming the ATMegaXU2 and having it coordinate with the 328P **may be more trouble than you like just to get a couple extra pins.**

> but if it is not accessable, why do they have it ?

Just added capability. Usually that header is unpopulated, so there's no part cost there.

> and also , i completely dunno a thing about atmega16u2 . only thing i understand is that it makes the arduino more compatible with the usb input ...

It serves the role of a USB to logic-level-serial converter for connecting to the USART of the otherwise non-USB-aware ATMega328P (you have tagged UNO). But, it can be made to run sketches. Usually if you're doing this, it's to get native USB support on an UNO (or Mega, or..), e.g. so you can have your board act as a keyboard, like you might with a Leonardo or Micro or any other board that has native-USB in normal use. And that's a large part of what NicoHood's project is about.
> 1 votes

---
Tags: arduino-uno, atmega16u2
---


# Question
Title: Is it possible to change and save I2C address programatically?
I want to drive 3 i2c devices on a single i2c line. Is it possible to achieve this without using A0,A1,A2 pins? I thought the address of i2c devices should be programmatically changeable. 2 mcp23017 and si5351 chips I use.

# Answer
As far as I can see in the datasheets of the 2 mentioned chips, they don't provide a way to change the address programmatically over the I2C bus. They only have address pins, which have to be tied to Vcc or ground for setting the address. Most ready to use boards with such chips already have pullup or pulldown resistors for this. If you use the blank chips, you absolutely need to tie the address pins to a fixed value. Normally this is done semi-permanently.

You can also connect the address pins to Arduino output pins to dynamically change the addresses.

There is no other way to change the addresses but to use the address pins.
> 1 votes

---
Tags: i2c
---


title: LEDs always dim with arduino nano

text:
# Question
Title: LEDs always dim with arduino nano
so I'm making an animated LED brake light using arduino nano, similar to this: https://www.youtube.com/watch?v=d5Ohzg3JKq0&ab\_channel=IMEEMADE

I have 18 channels, with differet amount of series LEDs and resistor. All LED + are wired together, intended for 14.5V input, with individual resistor after the last LED cathode: `14.5V -> + LED - -> R -> GND`

I have some channels with 1 LED, 2 LED and 4 LED, all tuned with different resistors so that each channel "pulls" ~20mA at 14.5V. 12V works fine as well just ever so slightly dimmer. On a power supply, I can ground any channel without cross talk, or ground all and all LEDs light up evenly (from what my eyes can tell).

I had originally planned on providing 5V input to the arduino using a buck converter and sinking each channel to a digital output pin (D2-D19 or D2-D13 + A0-A5). I ended up providing 12V to Vin and 12V to the LEDs as well as the arduino did not work at all as expected with 14.5V to the LEDs and 12V to the Vin.

My problem is that with this setup, no matter what I do in code, when the arduino is connected to Vin and ground, some LEDs are always lit dimly (D2-D13 oddly). They do indeed get brighter when `pinMode` is set to `OUTPUT` and `digitalWrite({pin}, LOW)` is called. But writing `HIGH` or setting `pinMode` to `INPUT` doesn't turn them off, just leaves them dim. I've tried adjusting Vin between 7-12V, setting the regulator to 5V and connecting directly to 5V. No change in behavior. Only thing that gets the LEDs to stop lighting dimly is lowering input voltage to the LEDs themselves. But then I don't have enough to drive the 4 series LED channels...

I know this can work because in the video I linked, there are 4 series LEDs driven in the same manner (though red, I'm using white), but not much is explained with the use of the arduino.

What am I doing wrong or how can I make this work? I need at least 12V to the LED board to ensure the 4 series channels light up properly. I've already maxed out the digital channels on the arduino nano from what I've read, so I can't use one as input (instead of Vin or 5V) if that matters or split the 4 series into 2 channels, etc...

Thanks in advance!

# Answer
> 1 votes
You can't drive LEDs from a source greater than 5V as a low-side switch with an Arduino directly. To do so you need an "open drain" output.

You can create them on the Arduino by adding a single transistor (N-channel MOSFET with "logic level" threshold, or NPN BJT) which the Arduino switches:

simulate this circuit – Schematic created using CircuitLab

R2 just exists to keep M1 turned off when the Arduino's not actively driving it (i.e., while the bootloader runs, etc).

# Answer
> 1 votes
For what to do see Majenko's answer.

This is regarding *why* you're seeing what you're seeing, or the nature of "What am I doing wrong" part of your question, and so why you need do something like what Majenko is suggesting.

Internal to the microcontroller, are diodes that protect it from voltage transients seen at the GPIO pin. One of these connects from the GPIO pin to the VCC ("5V") pin(s) of the MCU. This is pretty much the case with about any MCU, and so just about any Arduino's pins, with variations for things like 5V tolerant 3.3V parts. The RESET pin on AVR-based Arduinos has an external diode on it for reasons that have to do with (not) wanting to enter high voltage programming.

When the GPIO is *not* OUTPUT-and-LOW, that is if it's HIGH, or INPUT, or INPUT\_PULLUP, the current is going from your 12V nominal source, down through your load (LED and current limiting), into your GPIO pin, and through the protection diode onto the 5V rail of your Arduino. From there it will compete with your 5V regulator (or USB host's regulator) to try to power everything on the Arduino, e.g. your "L" LED, the the serial transceiver, the 3.3v regulator, the AVR itself, etc. and whatever else you have connected to "5V".

So, your GPIO pins are only rated to whatever-VCC-is plus about a diode drop; somewhere around 5.5V in this case. Above that voltage, the protection diode begins conducting and the GPIO doesn't appear high impedance to whatever is connected to it.

When you're lucky, there's enough resistance in your load to limit the current through the protection diode to:

* less current than the continuous current rating of the protection diode, which is quite low, often under 1mA. Otherwise, while this is going on you are likely trying to kill the protection diode and whatever else it can take out with it.
* less current than the Arduino can make use of. Otherwise the voltage at the "5V" well climb to the point of frying things. It will be backfeeding whatever is supposed to be regulating the 5V on the Arduino, which may or may not be a problem depending on the design of whatever regulator that is.

If you'd done this with a larger load, it probably would have just popped things on your Arduino. On the other end of the spectrum, putting a *sufficiently large* resistor in series with a GPIO pin is a common method of crudely accepting higher voltage input signals.

The circuit in Majenko's answer doesn't provide path would allow any current to speak of to travel from the 12V source into the GPIO pin.

---
Tags: arduino-nano, led, voltage
---


# Question
Title: How to send AT command to sim800l with SoftwareSerial
I have SIM800l module connected to Arduino and I'm trying to initialize it in my setup function with this code:

```
#include <SoftwareSerial.h>

//SIM800 TX is connected to Arduino D8
#define SIM800_TX_PIN 6
//SIM800 RX is connected to Arduino D7
#define SIM800_RX_PIN 7
SoftwareSerial serialSIM800(SIM800_TX_PIN,SIM800_RX_PIN);

void setup()
{
  Serial.begin(38400);
  while(!Serial);
  serialSIM800.begin(38400);
  Serial.println("wait for .... it");
  delay(10000);

  // comments added just for example, both commands return junk
  //serialSIM800.write("AT\r\n");
  //serialSIM800.write("AT+SAPBR=3,1,\"Contype\",\"GPRS\"\r\n");

  Serial.println("command sent");
  delay(2500);

  Serial.write(serialSIM800.read());
}

```

But `Serial.write` returns junk.

When I use this code in loop:

```
  //Read SIM800 output (if available) and print it in Arduino IDE Serial Monitor
  if(serialSIM800.available()){
    Serial.write(serialSIM800.read());
  }
  //Read Arduino IDE Serial Monitor inputs (if available) and send them to SIM800
  if(Serial.available()){
    serialSIM800.write(Serial.read());
  }

```

and send `AT+SAPBR=3,1,"Contype","GPRS"` or just `AT` command with serial monitor, everything works fine.

Can someone help with this?

# Answer
> 0 votes
You can try to use serialSIM800.println("AT") instead of write. Here some examples https://github.com/stanleyhuangyc/Freematics/issues/17

# Answer
> 1 votes
NeoSWSerial would be better for this. It can read and write at the same time, unlike SoftwareSerial, and it doesn't disable interrupts for the entire character receive time (~1ms!). AltSoftSerial would be even better, but you can only use it on pins 8 & 9 (on an UNO, different pins on other Arduinos).

# Answer
> 1 votes
Somewhere you said that ...but Serial.write return's junk.... Make sure that serial print is Both NL & CR

# Answer
> 1 votes
You are getting junk because of baud rate, set as 9600.

Serial.begin(9600); while(!Serial); serialSIM800.begin(9600); Serial.println("wait for .... it"); delay(10000);

# Answer
> 1 votes
IIRC, SIM800 modems are very 1990s, they default to 9600 baud. You will get garbage at 38400.

I successfully used a SIM800 at 9600.

# Answer
> 0 votes
My SIM808 returns a bit of junk right from the get-go, so that might be influencing things.

Also, it's conceivable you are retrieving a -1 from your initial serialSIM800.read() call - it's a nonblocking call and returns -1 when no data is available. That would almost definitely appear as junk.

# Answer
> 0 votes
Sim800 series free Atcommander software.

http://bayanbox.ir/info/3493267131357723232/ATcenter

---
Tags: arduino-uno, serial, arduino-nano, gsm, softwareserial
---


# Question
Title: I have a problem combining two different sketches into one sketch
Below are two attached the two codes, the second code is for using a microphone to detect for cough and sneezes where the first code is used for humidity and temp.

```
// For Scanning Insitu Exhale Parameters via nRFConnect or any BLE Service App
// Carbon-dioxide & Volatile OCs have been pseudo-mapped under Pressure & Rainfall respectively(ppm & ppb);)
#include <ArduinoBLE.h>
#include <Wire.h>
#include <SparkFunBME280.h>
#include <SparkFunCCS811.h>
#define CCS811_ADDR 0x5B
#define PIN_NOT_WAKE 5
CCS811 myCCS811(CCS811_ADDR);
BME280 myBME280;

BLEService sensorService("181A");  // Environmental_Sensor-Service
// 180D HeartRate
// 181B BodyComposi.
BLEShortCharacteristic sensorLevelChar1("2A6E", BLERead | BLENotify);   // Temperature-Characteristic
BLEShortCharacteristic sensorLevelChar2("2A6F", BLERead | BLENotify);   // Humidity-Characteristic
BLELongCharacteristic sensorLevelChar3("2A6D", BLERead | BLENotify);    // PCo2-Characteristic
BLELongCharacteristic sensorLevelChar4("2A78", BLERead | BLENotify);    // PTVoC-Characteristic
// 2A37 HRmeasurement
// 2A2C Magdeclination
// 2A98 weight
// 2A6D Pressure
// 2A9D Recom.HRMax.
// 2A8E Height
// 2A8D Max.HR
// 2A8C Gender
// 2A00 DeviceName
// 2A38 bodysensorlocation
int oldSensorLevel1 = 0;
int oldSensorLevel2 = 0;
int oldSensorLevel3 = 0;
int oldSensorLevel4 = 0;
long previousMillis = 0;

void setup() {
  Serial.begin(9600);
  while (!Serial);
  pinMode(23, OUTPUT);

  if (!BLE.begin()) {
    Serial.println("Bluetooth init. failed!");
    while (1);
  }
  Wire.begin();
  CCS811Core::status returnCode = myCCS811.begin();
  Serial.print("CCS811 begin exited with: ");
  printDriverError( returnCode );
  Serial.println();
  myBME280.settings.commInterface = I2C_MODE;
  myBME280.settings.I2CAddress = 0x77;
  myBME280.settings.commInterface = I2C_MODE;
  myBME280.settings.I2CAddress = 0x77;
  myBME280.settings.runMode = 3; //Normal mode
  myBME280.settings.tStandby = 0;
  myBME280.settings.filter = 4;
  myBME280.settings.tempOverSample = 5;
  myBME280.settings.pressOverSample = 5;
  myBME280.settings.humidOverSample = 5;
  delay(10);
  myBME280.begin();

  BLE.setLocalName("Mask.xME");
  BLE.setAdvertisedService(sensorService);
  sensorService.addCharacteristic(sensorLevelChar1);
  BLE.addService(sensorService);
  sensorLevelChar1.writeValue(oldSensorLevel1);

  sensorService.addCharacteristic(sensorLevelChar2);
  BLE.addService(sensorService);
  sensorLevelChar2.writeValue(oldSensorLevel2);

  sensorService.addCharacteristic(sensorLevelChar3);
  BLE.addService(sensorService);
  sensorLevelChar3.writeValue(oldSensorLevel3);

  sensorService.addCharacteristic(sensorLevelChar4);
  BLE.addService(sensorService);
  sensorLevelChar4.writeValue(oldSensorLevel4);

  // start advertising
  BLE.advertise();
  Serial.println("Bluetooth active, waiting to be connected.....");
}

void loop() {
  // waiting for a BLE central device.
  BLEDevice central = BLE.central();
  if (central) {
    Serial.print("Connected to central: ");
    Serial.println(central.address());
    digitalWrite(23, HIGH);  // indicate connection
    while (central.connected()) {
  if (myCCS811.dataAvailable())
  {
    myCCS811.readAlgorithmResults();
    printInfoSerial();
    float BMEtempC = myBME280.readTempC();
    float BMEhumid = myBME280.readFloatHumidity();
    myCCS811.setEnvironmentalData(BMEhumid, BMEtempC);
  }
  else if (myCCS811.checkForStatusError())
  {
    printSensorError();
  }
      long currentMillis = millis();
      if (currentMillis - previousMillis >= 200) {
        previousMillis = currentMillis;
        updateSensorLevel1();
        updateSensorLevel2();
        updateSensorLevel3();
        updateSensorLevel4();
      }
    }
    digitalWrite(23, LOW);
    Serial.print("Disconnected from central: ");
    Serial.println(central.address());
  }
}

void updateSensorLevel1() {
  float temperature = myBME280.readTempC();
  Serial.print("Temperature = ");
  Serial.print(temperature, 0);
  //float T = myBME280.readTempC();
  Serial.println(" °C");
  float sensorLevel1 = map(temperature, 0, 100, 0, 10000);
  sensorLevelChar1.writeValue(sensorLevel1);
  oldSensorLevel1 = sensorLevel1;
}

void updateSensorLevel2() {
  float humidity = myBME280.readFloatHumidity();
  Serial.print("Humidity = ");
  Serial.print(humidity, 0);
  Serial.println(" %");
  float sensorLevel2 = map(humidity, 0, 100, 0, 10000);
  sensorLevelChar2.writeValue(sensorLevel2);
  oldSensorLevel2 = sensorLevel2;
}

void updateSensorLevel3() {
  float CO2 = myCCS811.getCO2();
  Serial.print("Co2 = ");
  Serial.print(CO2);
  Serial.println(" ppm");
  float sensorLevel3 = map(CO2, 0, 100, 0, 1000);
  sensorLevelChar3.writeValue(sensorLevel3);
  oldSensorLevel3 = sensorLevel3;
}

void updateSensorLevel4() {
  float VoC = myCCS811.getTVOC();
  Serial.print("TVoC = ");
  Serial.print(VoC);
  Serial.println(" ppb");
  float sensorLevel4 = map(VoC, 0, 100, 0, 100);
  sensorLevelChar4.writeValue(sensorLevel4);
  oldSensorLevel4 = sensorLevel4;
}

void printInfoSerial()
{
  Serial.println("CCS811 data:");
  Serial.print(" CO2 concentration : ");
  Serial.print(myCCS811.getCO2());
  Serial.println(" ppm");
  Serial.print(" TVOC concentration : ");
  Serial.print(myCCS811.getTVOC());
  Serial.println(" ppb");

  Serial.println("BME280 data:");
  Serial.print(" Temperature: ");
  Serial.print(myBME280.readTempC(), 2);
  Serial.println(" degrees C");
  Serial.print(" %RH: ");
  Serial.print(myBME280.readFloatHumidity(), 2);
  Serial.println(" %");
  Serial.println();
}

void printDriverError( CCS811Core::status errorCode )
{
  switch ( errorCode )
  {
    case CCS811Core::SENSOR_SUCCESS:
      Serial.print("SUCCESS");
      break;
    case CCS811Core::SENSOR_ID_ERROR:
      Serial.print("ID_ERROR");
      break;
    case CCS811Core::SENSOR_I2C_ERROR:
      Serial.print("I2C_ERROR");
      break;
    case CCS811Core::SENSOR_INTERNAL_ERROR:
      Serial.print("INTERNAL_ERROR");
      break;
    case CCS811Core::SENSOR_GENERIC_ERROR:
      Serial.print("GENERIC_ERROR");
      break;
    default:
      Serial.print("Unspecified error.");
  }
}
void printSensorError()
{
  uint8_t error = myCCS811.getErrorRegister();
  if ( error == 0xFF ) //comm error
  {
    Serial.println("Failed to get ERROR_ID register.");
  }
  else
  {
    Serial.print("Error: ");
    if (error & 1 << 5) Serial.print("HeaterSupply");
    if (error & 1 << 4) Serial.print("HeaterFault");
    if (error & 1 << 3) Serial.print("MaxResistance");
    if (error & 1 << 2) Serial.print("MeasModeInvalid");
    if (error & 1 << 1) Serial.print("ReadRegInvalid");
    if (error & 1 << 0) Serial.print("MsgInvalid");
    Serial.println();
  }
}

```

Code 2

```
// Cough & Sneeze Classifier built through Edge Impulse Studio.
// If your target is limited in memory remove this macro to save 10K RAM
#define EIDSP_QUANTIZE_FILTERBANK   0
#include <PDM.h>
#include <cscan2_inference.h>

typedef struct {
    int16_t *buffer;
    uint8_t buf_ready;
    uint32_t buf_count;
    uint32_t n_samples;
} inference_t;

static inference_t inference;
static bool record_ready = false;
static signed short sampleBuffer[2048];
static bool debug_nn = false; // Set this to true to see e.g. features generated from the raw signal

/**
 * @brief      Arduino setup function
 */
void setup()
{
    // put your setup code here, to run once:
    Serial.begin(115200);
    Serial.println("SpecVital Inference...");
    // summary of inferencing settings (from model_metadata.h)
    ei_printf("Inferencing settings:\n");
    ei_printf("\tInterval: %.2f ms.\n", (float)EI_CLASSIFIER_INTERVAL_MS);
    ei_printf("\tFrame size: %d\n", EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE);
    ei_printf("\tSample length: %d ms.\n", EI_CLASSIFIER_RAW_SAMPLE_COUNT / 16);
    ei_printf("\tNo. of classes: %d\n", sizeof(ei_classifier_inferencing_categories) / sizeof(ei_classifier_inferencing_categories[0]));
    if (microphone_inference_start(EI_CLASSIFIER_RAW_SAMPLE_COUNT) == false) {
        ei_printf("ERR: Failed to setup audio sampling\r\n");
        return;
    }
}

/**
 * @brief      Arduino main function. Runs the inferencing loop.
 */
void loop()
{
    ei_printf("Starting inferencing in 2 seconds...\n");
    delay(5000);
    ei_printf("Recording...\n");
    bool m = microphone_inference_record();
    if (!m) {
        ei_printf("ERR: Failed to record audio...\n");
        return;
    }
    ei_printf("Recording done\n");

    signal_t signal;
    signal.total_length = EI_CLASSIFIER_RAW_SAMPLE_COUNT;
    signal.get_data = &microphone_audio_signal_get_data;
    ei_impulse_result_t result = { 0 };

    EI_IMPULSE_ERROR r = run_classifier(&signal, &result, debug_nn);
    if (r != EI_IMPULSE_OK) {
        ei_printf("ERR: Failed to run classifier (%d)\n", r);
        return;
    }

    // print the predictions
    ei_printf("Predictions (DSP: %d ms., Classification: %d ms., Anomaly: %d ms.): \n",
        result.timing.dsp, result.timing.classification, result.timing.anomaly);
    for (size_t ix = 0; ix < EI_CLASSIFIER_LABEL_COUNT; ix++) {
        ei_printf("    %s: %.5f\n", result.classification[ix].label, result.classification[ix].value);
    }
#if EI_CLASSIFIER_HAS_ANOMALY == 1
    ei_printf("    anomaly score: %.3f\n", result.anomaly);
#endif
}
/**
 * @brief      Printf function uses vsnprintf and output using Arduino Serial
 *
 * @param[in]  format     Variable argument list
 */
void ei_printf(const char *format, ...) {
    static char print_buf[1024] = { 0 };
    va_list args;
    va_start(args, format);
    int r = vsnprintf(print_buf, sizeof(print_buf), format, args);
    va_end(args);
    if (r > 0) {
        Serial.write(print_buf);
    }
}
/**
 * @brief      PDM buffer full callback
 *             Get data and call audio thread callback
 */
static void pdm_data_ready_inference_callback(void)
{
    int bytesAvailable = PDM.available();
    // read into the sample buffer
    int bytesRead = PDM.read((char *)&sampleBuffer[0], bytesAvailable);
    if (record_ready == true || inference.buf_ready == 1) {
        for(int i = 0; i < bytesRead>>1; i++) {
            inference.buffer[inference.buf_count++] = sampleBuffer[i];
            if(inference.buf_count >= inference.n_samples) {
                inference.buf_count = 0;
                inference.buf_ready = 1;
            }
        }
    }
}
/**
 * @brief      Init inferencing struct and setup/start PDM
 *
 * @param[in]  n_samples  The n samples
 *
 * @return     { description_of_the_return_value }
 */
static bool microphone_inference_start(uint32_t n_samples)
{
    inference.buffer = (int16_t *)malloc(n_samples * sizeof(int16_t));
    if(inference.buffer == NULL) {
        return false;
    }
    inference.buf_count  = 0;
    inference.n_samples  = n_samples;
    inference.buf_ready  = 0;
    // configure the data receive callback
    PDM.onReceive(&pdm_data_ready_inference_callback);
    // optionally set the gain, defaults to 20
    PDM.setGain(80);
    //ei_printf("Sector size: %d nblocks: %d\r\n", ei_nano_fs_get_block_size(), n_sample_blocks);
    PDM.setBufferSize(4096);
    // initialize PDM with:
    // - one channel (mono mode)
    // - a 16 kHz sample rate
    if (!PDM.begin(1, EI_CLASSIFIER_FREQUENCY)) {
        ei_printf("Failed to start PDM!");
    }
    record_ready = true;
    return true;
}
/**
 * @brief      Wait on new data
 *
 * @return     True when finished
 */
static bool microphone_inference_record(void)
{
    inference.buf_ready = 0;
    inference.buf_count = 0;
    while(inference.buf_ready == 0) {
        delay(10);
    }
    return true;
}
/**
 * Get raw audio signal data
 */
static int microphone_audio_signal_get_data(size_t offset, size_t length, float *out_ptr)
{
    arm_q15_to_float(&inference.buffer[offset], out_ptr, length);
    return 0;
}

/**
 * @brief      Stop PDM and release buffers
 */
static void microphone_inference_end(void)
{
    PDM.end();
    free(inference.buffer);
}

#if !defined(EI_CLASSIFIER_SENSOR) || EI_CLASSIFIER_SENSOR != EI_CLASSIFIER_SENSOR_MICROPHONE
#error "Invalid model for current sensor."
#endif

```

# Answer
You have 2 different problems you need to solve before you can merge these sketches.

The first sketch has a loop within a loop. in psuedocode it is:

```
void loop(){
   Connection con = connect();
   while(con.connected()){
       doStuff();
   }
   notify_disconnected();
}

```

This is a problem because the loop never exits in normal operation.

you can rewrite this into

```
Connection con;
void loop(){
    if(con.connected()){
        was_connected = true;
        doStuff();
    } else{
        if(was_connected){
            notify_disconnected();
            was_connected = false;
        }
        con = connect();
    }
}

```

The other sketch has the classic delay problem which the first sketch gives an example of handling.

```
void loop(){
    delay(5000);
    doStuff();
}

```

this can be changed into

```
void loop(){
    long currentMillis = millis();
    if (currentMillis - previousMillis >= 5000) {
        previousMillis = currentMillis;
        doStuff();
    }
}

```

After you do these fixes and make sure the names of the globals and functions don't collide and no unneeded wires cross you can put both in the same sketch:

```
void setup(){
    setup_sketch1();
    setup_sketch2();
}

void loop(){
    loop_sketch1();
    loop_sketch2();
}

```
> 2 votes

---
Tags: programming, arduino-ide
---


title: Not getting data from GPS

text:
# Question
Title: Not getting data from GPS
When I run FullExample program from TinyGPS++, I get following types of entries,

```
Sats HDOP Latitude   Longitude   Fix  Date       Time     Date Alt    Course Speed Card  Distance Course Card  Chars Sentences Checksum
          (deg)      (deg)       Age                      Age  (m)    --- from GPS ----  ---- to London  ----  RX    RX        Fail
---------------------------------------------------------------------------------------------------------------------------------------

0    9999 ********** *********** **** 07/01/2016 07:32:50 689  ****** ****** ***** ***   ******** ****** ***   75128 0         0
0    9999 ********** *********** **** 07/01/2016 07:32:51 857  ****** ****** ***** ***   ******** ****** ***   75389 0         0
0    9999 ********** *********** **** 07/01/2016 07:32:52 864  ****** ****** ***** ***   ******** ****** ***   75642 0         0
0    9999 ********** *********** **** 07/01/2016 07:32:53 870  ****** ****** ***** ***   ******** ****** ***   75895 0         0
0    9999 ********** *********** **** 07/01/2016 07:32:54 878  ****** ****** ***** ***   ******** ****** ***   76148 0         0

```

Other details:
GPSBaud = 9600;
RXPin = 11;
TXPin = 10
Module: GY-NEO6MV2

# Answer
That is a ***perfect*** printout of a GPS system that can see **zero** satellites.

The fact that the timestamps are one second apart shows that you have correctly interfaced with the GPS device. Now, the GPS device has to 'interface' with the satellites!

Many people don't realise two things:

1. The GPS antenna really does need a clear view of the sky. A tiny view through a window may show one or two satellites, but you need a minimum of three, and preferaby four or more at a number of points around the sky to get a fix.
2. If the GPS unit has been completely powered off (called 'cold'), when it first powers on it has NO idea where anything is. It simply listens for any signal anywhere until it "hears" the current time. It can then guess where satellites might be, and listens for updates on satellite positions.

All of this listening, guessing and waiting takes time before it can start to actually lock on to satellites and start to get a fix. This time could easily be 90 seconds or more - you need to be patient. Check your GPS device specifications for "cold start" times.

### Edit

I'm impressed! The GY-NEO6MV2 that you list has a cold-start of 27 seconds - but that assumes it has a clear view of the sky.
> 3 votes

# Answer
The GPS actually seems to be getting some data: the date and time. Which means it can be used to set the time (and date) in a clock if the timezone is known without needing a fix (useful inside).
> 1 votes

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


# Question
Title: Any advice on how to repeat the song 6 times instead of infinitely?
//Here is my code so far

```
int speakerPin = 9;

int length = 28;

char notes[] = "GGAGcB GGAGdc GGxecBA yyecdc";

int beats[] = { 2, 2, 8, 8, 8, 16, 1, 2, 2, 8, 8,8, 16, 1, 2,2,8,8,8,8,16, 1,2,2,8,8,8,16 };

int tempo = 150;

void playTone(int tone, int duration) {

for (long i = 0; i < duration * 1000L; i += tone * 2) {

   digitalWrite(speakerPin, HIGH);

   delayMicroseconds(tone);

   digitalWrite(speakerPin, LOW);

   delayMicroseconds(tone);

}

}

void playNote(char note, int duration) {

char names[] = {'C', 'D', 'E', 'F', 'G', 'A', 'B',

                 'c', 'd', 'e', 'f', 'g', 'a', 'b',

                 'x', 'y' };

int tones[] = { 1915, 1700, 1519, 1432, 1275, 1136, 1014,

                 956,  834,  765,  593,  468,  346,  224,

                 655 , 715 };

int SPEE = 5;

for (int i = 0; i < 17; i++) {

   if (names[i] == note) {
    int newduration = duration/SPEE;
     playTone(tones[i], newduration);

   }

}

}

void setup() {

pinMode(speakerPin, OUTPUT);

}

void loop() {

for (int i = 0; i < length; i++) {

   if (notes[i] == ' ') {

     delay(beats[i] * tempo);

   } else {

     playNote(notes[i], beats[i] * tempo);

   }

   delay(tempo);

}

}

```

# Answer
> 5 votes
Assuming, the program can stop after playing 6 times, put another `for` loop in the `loop` function:

```
void loop()
{
   for (int nTimes = 0; nTimes < 6; nTimes++)
   {
      // Existing loop code
   }

   while(true) {};
}

```

A less crude way is to create a global variable:

```
int _timesPlayed = 0;

```

And change the `for loop`:

```
void loop()
{
   if (_timesPlayed < 6)
   {
      // Existing loop code

     _timesPlayed++;
   }
}

```

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


# Question
Title: What would be the best way of dynamically 'change' instances regarding dynamic memory?
Since I'm very used to object oriented programming, I would like to use this into my design. My application will have 4 led strips and each led strip will have a 'pattern' running on it. For this I like to create a base class and for each pattern a derived class. So this means I have 4 instances to a pattern. However, the pattern can change dynamically (based on music MIDI input). Each pattern has between 10-16 parameters.

I know dynamic memory allocation is mostly not a good idea in an Arduino. I'm using a Mega which has 8 KB. I found several 'solutions' but neither one I'm sure about. The first is not the solution but the way I should do it when I have 'plenty' of SRAM available (and simplified):

```
class Pattern
{
   public:
      virtual void Process();
}

class PatternA: Pattern
{
   public:
      void Process();

      // In example I only use 2 out of 10-16 parameters
      uint8_t SetColor(uint8_t colorIndex);
      uint8_t SetSpeed(uint8_t speed);

   private:
      uint8_t _colorIndex;
      uint8_t _speed;
}

// In this example I only use 2 out of 24 patterns
class PatternB: Pattern
(like PatternA but with its own implementation)

class LedStrip
{
   public:
       void SetPattern(Pattern* pattern);

   private:
       Pattern* _pattern;
}

```

Other derived classes may have other (named) parameters.

When changing instances, I would get something like this:

```
LedStrip::SetPattern(Pattern* pattern)
{
    delete _pattern;
    _pattern = pattern;
}

pattern* pattern = new PatternA(...);
ledStrip1.SetPattern(pattern);

```

However, since the new pattern may use more memory then the deleted pattern, there will be a memory gap. So this is not suitable for the Arduino to be used I assume.

Solutions:

**1. Create all possible patterns beforehand.**

Assume I would implement 24 patterns, and create any possible combination, I would have 4 (led strips) * 24 (patterns) * 13.5 (average number of parameters) = 1,296 bytes. This seems a bit much as only 4 are 'active'.

```
class LedStrip
{
   public:
      enum EPattern {A, B}

      void SetPattern(EPattern pattern);

   private:
      PatternA* _patternA;
      PatternB* _patternB;

      Pattern* _pattern;
}

```

To change pattern:

```
void LedStrip::SetPattern(EPatternpattern)
{
case EPatternA: _pattern = _patternA; break;
case EPatternB: _pattern = _patternB; break;
}

ledStrip1.SetPattern(EPattern::A);

```

Of course I could also pass a pattern where the patterns are created globally but this is does not matter for this example. The idea is to create 4 (led strips) * 24 (patterns) instances beforehand and never use `delete`. This means out of the 4 * 24 patterns, only 4 are used, 1 per led strip.

Of course this causes a lot of unused memory.

**2. New/Delete**

I create the 4 correct derived instances and when one pattern (instance) change, I delete the instance and create the new. When I put no (instance) variables in the derived class, this could work, but I have some specific questions regarding this solution:

I make sure all the max. parameters are in the base class and I 'cast' 4 instances of the base class to a derived class. This seems a bit of 'tricky' solution.

```
class Pattern
{
   public:
      SetParameter(uint8_t parameter, uint8_t parameterValue);
      uint8_t parameter GetParameter(uint8_t parameter);

   private:
      uint8_t _parameters[16];
}

class PatternA: Pattern
... (does not have any variables)

```

To change pattern:

```
delete ledStrip1.pattern;
ledStrip1.pattern = new PatternA();

```

Question: can I assume the deleted memory of the old pattern will be replaced by the new pattern as the memory usage is equal?

The downside of this way is that each pattern will have the worst-case amount of parameters in each instance, but this is not a problem (I only have 4 led strips).

# Answer
> 3 votes
I don't know what you'll make of this, but:

*If* you can set aside a properly aligned and sufficiently large memory block you can use the placement form of the `new` operator.

Placement `new` is essentially `new` without the the part that behaves like (and typically is) `malloc`. Or put differently, it lets you construct an object inside of already allocated memory. By "already allocated" I don't mean already allocated on the heap; the memory can come from whereever you want. This more or less lets you make your own custom allocator with predictable behaviour that you don't get from generic heap allocator like `malloc`.

So you can set aside memory however you want. It can be an array of `unsigned char` in static storage duration (global, static local, static member). And placement `new` can put an object into it, or importantly, into *part* of it. Basically you're making your own arena for your allocator.

It's up to you to align the memory correctly. There are compiler keywords that can help with that. You can also resort to an older technique oversizing the block just large enough so that a properly aligned sub-block exists and can be found within it. However, on an 8-bit microcontroller like the AVR, there are no alignment requirements to speak of.

When it comes to using `delete`, well, you don't. You just call the destructor on the object directly. There are ways you could try to clean that up also.

If I become awake enough to completely understand your specific usage, I may try to make an example. But that is the basic technique I'd consider.

---

Regarding avoiding `new`/`malloc`: the case against them it is often *slightly* overstated. For example, doing a set of `malloc` / `new` at the beginning, and only the beginning, of your program and not thereafter is normally fairly stable and predictable. For example, you can read a configuration out of eeprom in `setup()` and use that information to allocate say three "dynamic" "arrays" with `malloc`, that you know they won't total more than some testable maximum. Maybe a slightly more accurate warning for them is something like: you will get into trouble if you don't have a reasonable understanding of your maximum heap usage and if your usage pattern requires that you `free`/`delete`/`remalloc`.

I mention this in part also because it's not completely unreasonable to `malloc/new` once, early in your execution, to acquire an arena to use with placement `new` calls.

# Answer
> 1 votes
Pattern classes are code and variables for the current set of parameters. The code doesn't take SRAM it is executed from flash. I would instance all 24 patterns for all 4 LED strips using global two dimensional array.

Advanced version could be a pool of pattern instances allocated with 'new' but never deleted, only reused. You would only create a new pattern class instance of requested type, if there is no free pattern instance of that type in the pool.

The parameters sets could be stored in PROGMEM or in EEPROM and loaded as needed into the variables of the corresponding pattern class instance.

# Answer
> 1 votes
When I need dynamically allocate memory, I generally pre-allocate a pool of memory blocks, each sufficiently large for the maximum size request I'll handle. Then, Whether the app requests 1 byte or MAXSIZE bytes, it gets a pointer to the *first available* one of those MAXSIZE blocks in the pool. `free()`ing such a block works just as you'd expect. Since all allocations are the same size, and no more memory is ever taken from the real heap, the pool doesn't have to (and can't, in my implementation) grow.

If this is the only dynamically allocated memory for your application, you can re-write `new()` and `delete()` to use your pool-allocator, or, if `new()` and `delete()` are implemented as wrappers around `malloc()` and `free()`, just replace those more primitive ones with the pool-based `malloc()` and `free()`.

# Answer
> 1 votes
Since you only need four objects at any given time, it would be wasteful to statically allocate 4×24 objects, as you only really need four times the size of the largest object. You can still use static allocation by using an array of unions: each cell of the array will then be large enough to store the largest possible pattern.

There may be more elegant solutions, but the simple approach is to use a tagged union, i.e. a struct holding both a union and an extra variable telling you what data type the union is actually holding. Beware that there are limitations on what type of objects you can put in an union. You should be safe if the actual classes have trivial do-nothing constructors.

Below is a simplified example with two classes that each hold only a number, either an `uint8_t` or a `uint16_t`:

```
class Pattern
{
public:
    virtual void process();
};

class Pattern8 : public Pattern
{
public:
    void process() { Serial.println(8000 + param); }
    void set_param(uint8_t param8) { param = param8; }
private:
    uint8_t param;
};

class Pattern16 : public Pattern
{
public:
    void process() { Serial.println(16000 + param); }
    void set_param(uint8_t param16) { param = param16; }
private:
    uint16_t param;
};

// This is the tagged union.
struct AnyPattern : public Pattern
{
    AnyPattern() {}  // must be explicitly defined
    void process() {
        switch (type) {
            case TYPE8: pattern8.process(); break;
            case TYPE16: pattern16.process(); break;
        }
    }
    enum { TYPE8, TYPE16 } type;
    union {
        Pattern8 pattern8;
        Pattern16 pattern16;
    };
};

void setup() {
    AnyPattern patterns[2];
    patterns[0].type = AnyPattern::TYPE8;
    patterns[0].pattern8.set_param(21);
    patterns[1].type = AnyPattern::TYPE16;
    patterns[1].pattern16.set_param(42);
    Serial.begin(9600);
    patterns[0].process();
    patterns[1].process();
}

void loop(){}

```

---
Tags: arduino-mega, memory-usage, memory
---


# Question
Title: Arduino Pro Mini (3.3V version) input voltage range / tolerance
I have a few Arduino Pro Mini clones (cheap Chinese stuff) and would like to power them with 12V power supply (same as fan voltage). According to the Arduino Pro Mini spec the RAW pin can take 3.35-12V (3.3V model). In practice this means a 12V PSU cannot be used as they are almost always over 12V with low load. I read that the voltage regulator in this board is capable up to 16V input. I tried plugging in a cheap 12V power adapter that read 15.1V with no load but a component on the arduino clone board actually exploded instantly. The board seems to work still when powered from usb programmer. Component that burned out is just above VCC, RST and GND pins.

Why did this happen? What did I just damage and most importantly what is a safe voltage level to use? I already have a few 12V switching power supplies it would be a shame if I could not use them.

Solution:

In the end it seems to have been a faulty arduino clone, faulty or poor quality power adapter or the fact that I powered the power supply before plugging it to the board's RAW input pin. The cheap 12V switching power supplies work just fine even though my multimeter registers a voltage spike as high as 30V during power up.

# Answer
> 19 votes
The genuine Pro Mini's use a MIC5205 regulator which should accept up to 16V at it's input normally, with an absolute maximum of 20V. It's unlikely that the regulator would be damaged by 15.1V.

However, the component you have indicated that has blown is a capacitor. SMD capacitors are available in different voltage ratings, typically 4V, 6.3V, 10V, 16V, 25V, 35V and 50V (and above, but let's ignore them for this). It's rare to see any intermediate values.

SMD capacitors are very intolerant of being used at a higher voltage than specified. This is especially true of electrolytic and tantalum capacitors. The blown capacitor on the genuine Pro Mini's is polarised (the grey band not he package and the schematic indicates this), so we can infer it is either electrolytic or tantalum. A 10µF SMD electrolytic is unlikely to be in this package, so it is almost certainly a tantalum.

Sparkfun sell 10µF tantalums, and they are rated at 16V. It's quite likely these are the same ones used on the Pro Mini. 15.1V is very close to 16V - in fact, if this is a poorly smoothed power supply, the meter might show 15.1V but the peaks could well be 16V or even 20V. It is recommended that you de-rate the voltage ratings on tantalums by 50% at least.

It's really important to realise that most low-cost DC power supplies are not regulated and produce a very bumpy output voltage with no regulation:

Tantalums also have no tolerance for reverse voltage, so if you did apply reverse voltage, it would pop.

So it is quite likely that you over-volted the cap and blew it. You could replace them with higher rated capacitors - I would go for 35V ones if you want to supply 15.1V. Desoldering and desoldering a single capacitor is relatively easy as long as the pads haven't been damaged. Realistically, you could use a normal leaded 10uF electrolytic between RAW and GND instead of the SMD one.

**EDIT:** However, looking at the data sheet for the regulator, it shouldn't really matter if that 10uF is there or not:

> A 1μF capacitor should be placed from IN to GND if there is more than 10 inches of wire between the input and the ac filter capacitor or if a battery is used as the input.

Some regulators absolutely require an input capacitor, with others it is just advisable. This looks like it is just advisable. So if it isn't working on external power now, you may have blown the regulator as well.

Even if the clone board uses a different SMD regulator, their characteristics are all very similar. As stated, some do need a capacitor on the input to work, so replacing it might fix it.

There is a further consideration that dropping from 15.1V to 3.3V on a SMD regulator is not a great idea. You will need to burn off a lot of power.

The MC5205 can dissipate 455mW with a minimal PCB footprint (which the Pro Mini has) with a 25°C ambient:

So, we know the maximum power we can dissipate, and we know the voltage drop - we can then calculate the current:

P = (Vin - Vout) * I

0.455 / (15.1 - 3.3) = I

I = 38.5mA

This isn't very much at all. You might want to consider regulating off the board, and probably with a switching regulator rather than linear regulator.

I also note your PS:

> the ground of the 12V PSU is shared with Arduino ground pin, not sure if this might be the cause.

If they weren't shared, there would be no way that this could work. They need to be shared otherwise the Vcc from the power supply is not referenced to anything and may as well not be there.

# Answer
> 3 votes
The component that exploded during your test is a capacitor.

According to the position on the board you mentioned, it is one of the 2 electrolytic capacitors used on both sides of the 3.3V regulator (I would say that's probably the upstream capcitor).

There are a few reasons why a capacitor may explode:

* apply an inverted voltage to it (polarized capacitors only)
* apply a voltage above its rating
* apply a current above its rating

Your situation is probably the 2nd one: too high voltage applied.

According to Sparkfun original schematics, this capacitor must be polarized with 10uF capacity. Unfortunately the schematics do not mention the maximum voltage.

According to the specification for the original board, the maximum voltage for this cap should be at least 12V, but there is no guarantee that it is anthing above than 12V. Hence, you have to consider **12V is the maximum voltage applicable** to your board (on the RAW pin).

In addition, you have mentioned you are using a cheap chinese clone, it is perfectly possible (although not expected, as it would make the board operate differently than the original specs) that this one uses a lower voltage cap (eg 10V) which would be a bit cheaper.

If you do want to reuse your 12V PSU, you will have to ensure that its output voltage never exceeds 12V, for this you are left with a few options:

* use a voltage divider made of 2 resistors: you must first know the max voltage output of your PSU and then calculate resistance values to get 12V based on that max voltage. That's easy but it can waste a lot of energy
* use a 12V Zener diode outside your PSU
* use a 12V voltage regulator circuit after your PSU: that one is the safest, but also the most expensive solution

**Edit:**

Of course, if you have already done it and are equipped for it, you can find replacements for the capacitor that has exploded and buy a higher-voltage one, then replace it on your boards; that will reauire good soldering/desoldering equipement usable for surface-mounted components.

# Answer
> 2 votes
Although this thread is old, people has to be aware that some clone boards uses 4B2X regulator and they support maximum 10v (https://epstik.com/p744820729-xc6204b332mr-4b2x-stabilizator.html , https://www.mcucity.com/product/3240/xc6204b332mr-g-3-3v-4b2x-4b2y-positive-voltage-regulator). Theses clones are extremely common on ebay and another marketplaces.

---
Tags: clones, voltage-level, arduino-pro-mini
---


# Question
Title: Arduino Pico doesn't work with ST7735 screen
I am attempting to get the graphicstest example bundled with the Adafruit ST7735 library for the 0.96 inch LCD screen.

The example runs fine and serial communication is up and running. However, nothing outputs on the screen. I verified that the code works with other Arduino boards and that I have it properly wired -\> SCK to SCL, MOSI to SDA, etc.

I'm not sure if I am doing something wrong, or if this is a limitation of the board.

Edit: I added the modified graphicstest code to the Internet, it can be found here: https://drive.google.com/file/d/1cFOgQXhhH1vou0KUrFzBDMp0iiIp1Yuy/view?usp=sharing

I also added a crude diagram of how the screen is wired up to the Pico. Note that the LCD is powered externally since the Pico cannot handle the current draw of powering the LCD. https://drive.google.com/file/d/1RmZSHBcelwC9caLoQC9iE5Lb4eHG9S2O/view?usp=sharing

# Answer
> 1 votes
I found out the problem. I was trying to connect to the SCK and MOSI pins on the back of the Pico. Later research shows that these are meant for programming and burning a bootloader onto the microprocessor.

The Adafruit library allowed me to define my own pins for SCK and MOSI. Once I switched to using the `Adafruit_ST7735(int8_t cs, int8_t dc, int8_t mosi, int8_t sclk, int8_t rst)` constructor, it worked after that.

# Answer
> 0 votes
From a comment on the question:

> I am going directly off of what's on their website. mellbell.cc/products/pico What they show on the link you provided is a prototype.

The "link you provided" refers to this, which despite being described as for a "prototype", shows *correct* information with regard to the SPI related pins.

As it turns out **the documentation in the images you referenced at mellbell.cc/products/pico is incorrect**, both under the product shots and in the pin-outs section under "Documentation". You can tell this by looking right at their image of their board and their diagram, and comparing that with the pinout of the ATMega32U4 itself:

Interestingly, in the pinout on 8 of their PDF in the documentation section, they have it correct again and closer to the prototype:

Or at least it is with respect to the SPI signals. The diode is in the wrong and orientation. In fact, the whole board seems to be left-right reversed.

Again, from the same comment:

> Additional research also shows that the SCK and MISO pins I'm connected to seem to be for programming only

It is true that these pins are used for ISP programming. However, they also carry the data for the SPI bus peripheral when you're not doing ISP programming. So they are "for programming" just not "only" for programming. This is down to how the ATMega32U4 is, and not something tha the Pico makers have much control over.

This is also the case for UNO and basically all of the other popular AVR based Arduinos that can be programmed using the ISP method, as opposed to uPDI and others. What *slightly* less common is to have these pins only available as unpopulated pads or only available on the ISP header.

I can see why you might want to not deal with those contacts because of the form factor of the Pico board. However, because those pins are actually 32u4's SPI interface, and they should perform better than the bit-banging that Adafruit library would need to resort to in order to use other (non-SPI) pins. So there is an incentive to use them.

So, your solution is a solution, but not for the reasons you think. The pins you were previously trying to use will work when your efforts aren't being undermined by bad documentation, and you get them in the right order.

---
Tags: lcd, arduino-leonardo
---


# Question
Title: How to run multiple DC motors in different patterns?
I am a complete novice in programming and I hope someone could guide me here. I am doing a haptic research project, where 8 DC coin vibrating motors would be fitted on the fingers of subjects (excluding thumbs), and the subject has to respond the number of fingers they feel the vibrations on.

Every trial has to have a different pattern of outputs, say: in first trial, 4 motors are activated-motor 1, motor5, motor8 and motor 3. In a single trial, the motors have to have a common delay of 150 ms and 4 seconds break after next one starts.

**My question is, that in 8 motors, there are 255 different activation patterns possible. How do I define all these 255 patterns and randomise their sequence? I am using the mega board and connecting each motor to a PWM pin and all having a common ground.**

Here is a sample code with 3 such combinations (only seven motors are connected here):

```
#define viboutpin 2
#define viboutpin1 3
#define viboutpin2 4
#define viboutpin3 5
#define viboutpin4 6
#define viboutpin5 7
#define viboutpin6 8

void setup() {
     pinMode(viboutpin,OUTPUT);// define a pin as output
     pinMode(viboutpin1,OUTPUT);
     pinMode(viboutpin2,OUTPUT);
     pinMode(viboutpin3,OUTPUT);
     pinMode(viboutpin4,OUTPUT);// define a pin as output
     pinMode(viboutpin5,OUTPUT);
     pinMode(viboutpin6,OUTPUT);
}

void loop() {
    digitalWrite(viboutpin,HIGH);
    digitalWrite(viboutpin1,HIGH);
    digitalWrite(viboutpin2,HIGH);
    digitalWrite(viboutpin3,HIGH);
    digitalWrite(viboutpin4,HIGH);
    digitalWrite(viboutpin5,HIGH);
    digitalWrite(viboutpin6,HIGH);
    delay(150);
    digitalWrite(viboutpin, LOW);
    digitalWrite(viboutpin1,LOW);
    digitalWrite(viboutpin2,LOW);
    digitalWrite(viboutpin3,LOW);
    digitalWrite(viboutpin4,LOW);
    digitalWrite(viboutpin5,LOW);
    digitalWrite(viboutpin6,LOW);
    delay(2000);

    digitalWrite(viboutpin2,HIGH);
    digitalWrite(viboutpin6,HIGH);
    delay(150);
    digitalWrite(viboutpin2,LOW);
    digitalWrite(viboutpin6,LOW);
    delay(2000);

    digitalWrite(viboutpin4,HIGH);
    delay(150);
    digitalWrite(viboutpin4,LOW);
    delay(2000);
}

```

# Answer
> 1 votes
Why not generate a psuedo random number from 0 to 255 and use it as a code for which motors are to be activated - bit 0 == viboutputpin0, etc.? Then one function can look at each bit in turn and activate that motor if the bit is set, delay, and stop the motors.

You'll probably want to test your code with a few pre-defined test patterns instead of the random ones, and once you're satisfied that it works, randomly seed the random number generator so your project will generate a different pattern each time. One way to do that is to ask via terminal for the operator to click the 'Send' button (or tap the space bar if you're using a separate terminal emulator that sends key by key). Measure the time from the request to the response in microseconds, discard the 2 or 3 least significant bits of the result and keep the next 8. The micros() function's resolution is 4 usec at 16 MHz, is the reason for discarding those 2 lower bits.

---
Tags: arduino-mega, motor
---


# Question
Title: send and recieve analog data from one arduino to another arduino via web/ethernet
i am able to send audio signal through mic and send it via arduino and receive it on speaker.

i need two things

1.) The voice i am hearing on speaker has on speaker has lots of noise with it. i need to reduce it 2.) I need to send that analog signal received from the mic via Ethernet/web to another arduino. i have Ethernet shield i am able data from switch but not from mic.

let me start from the beginning, i have attached mic to the audio amplifier and have attached output of the amplifier to the a0 pin of the arduino. The arduino is connected to the DAC(PCF8519) with a5 and a4 pin of the aurdino. The output of the dac is connected to the LM386 audio amplifier module and its output is connected speaker. when i speak via mic i am able to hear it on speaker but it has has some noise attached to it. IF you can suggest solution for that it will be great.

now i want to send the data of the mic to another arduino via web/Ethernet. i am able to get the data of the switch but not been able to get proper data from the mic.So pls help out with that.

here is my audio amplifier circuit:

here is my code for one arduino code that worked

```
`#include "Wire.h"`
 #define PCF8591 (0x90 >> 1)
 void setup()
  {
    Wire.begin();
    pinMode(0,INPUT);
   }
 void loop()
   {
     Wire.beginTransmission(PCF8591);
     Wire.write(0x40);
     Wire.write(analogRead(0));
     Wire.endTransmission();
   }

```

I need to reduce the noise on the speaker and i want to send the data of the mic via web/Ethernet to another arduino.

# Answer
> 1 votes
ADC input has 100Mohm impedance. By placing C4 the signal at the ADC input has no DC path, is just floating between -0.7v and 5.7v , limited only by the input clamping diodes.

ADC can convert only voltages between 0 and the voltage reference, I suppose you use the default 5V reference.

But your signal is floating, and the ADC will cut any peaks outside of the conversion area giving the noise you hear.

Another issue I see here is that the data sheet of LM386 specifies a load between 4ohm and 32ohm. There is no warrantee that it will work without a load as in your case. Most likely not.

So you might want to connect C4 to a proper load and take the signal for ADC straight from pin 5 of LM386 which is auto balanced at half of the voltage supply.

simulate this circuit – Schematic created using CircuitLab

Later edit after I found the source of the schematic, there are also comments there that the schematic will never work with Arduino with the capacitor connected, the only working application was a sound detector where the signal distortion does not matter.

Please do not trust the content of any unknown website published by an anonymous just because it looks like a tutorial made by somebody who knows something.

Edit to add some info on how to debug the issue.

First, in the above schematic replace the resistor with a speaker and see if the sound is good. If not than see what is wrong with your amplifier.

If it's good and loud without any distortion then put the resistor back.

Use a binary mode serial monitor like Realterm to see how your data looks, the Arduino serial monitor works only in Ascii mode which turns a byte into three ascii chars which is slow.

Something like that

```
void setup() {
    Serial.begin(230400); // opens serial port, sets data rate to or maximum supported by your board to minimize latency
}

void loop()
   {
     unsigned int temp;
     temp = analogRead(0);
     temp = temp>>4; //strip low bits to fit in a single byte
     Serial.write(temp);
   }

```

Then see how your data looks, if you have to many 00 or to many FF than you know that your data us upper or lower limited or what is wrong with your signal.

I hope you are aware that the ADC conversion takes 100us and the wire transmission also around 200us the maximum sample rate you can expect is around 3khz and a maximum bandwidth of the audio signal of 1.5kHz which is half of the telephony bandwidth, you might want to use a faster DAC and use some non blocking ADC reading to use the time while ADC is working like in this article

---
Tags: arduino-uno, arduino-ide, code-optimization, ethernet-shield, analog
---


# Question
Title: Why do I need to use latin-1 instead of utf-8 when using python with arduino?
When reading and writing with a python serial port connection to arduino, if I don't use latin-1 ('ISO-8859-1'), the results are not as expected. Like if I have

```
int outP = 5;
//...
int outV = Serial.read();
analogWrite(outP, outV);

```

While with python I have

```
serial_port.write(chr(255).encode())

```

I read 3.78 V from the pin, whereas if I use

```
serial_port.write(chr(255).encode(encoding = 'latin-1'))

```

I get 5.04 V. I have read latin-1 and utf-8 don't always match, but is there something about arduino that requires using latin-1? Of course, these return different values when testing each encoding, using 255 gives b'\xc3\xbf' (from 'Ã¿') with utf-8 or b'\xff' from ('ÿ') with latin-1, but why does arduino work with latin-1?

FYI other options that work are

```
v = 255

serial_port.write(v.to_bytes(1, byteorder = 'big'))

serial_port.write(bytes[v])

```

# Answer
> but is there something about arduino that requires using latin-1?

No, not really.

What it comes down to is that `Serial.read()` reads bytes, irrespective of whatever encoding they may be being used with. ISO-8859 only encodes character code points in the 0-255 range, so when you choose a 0-255 code point and send it as ISO-8859, it gets sent as 1 byte, which is how you're code has been written to receive it.

A 255 code point as utf-8 would require multiple bytes to encode and so would result in multiple `Serial.read()` calls for a given value.

If you open a python3 REPL and put `chr(255).encode()` or more explicitly `chr(255).encode('utf-8')` you will see it results in `b'\xc3\xbf'`. So on the Arduino side you will see this as two separate `Serial.read()` results, `0xC3` and `0xBF`.

When you're just taking in strings and UTF-8 and splatting them out via `Serial.println()`, the Arduino is blissfully unaware of that they're UTF-8 and not ISO-8859. Really you could use any encoding you wanted, the the caveat being that if you're using c-strings to store them, the encoding would need to be one that doens't allow for a single null byte to be in the middle of the string.

---

You may want to look into using struct.pack rather than cobbling together python bytestrings with sequences of `chr()` and `.encode(whatever)`. `struct.pack` will also result in a bytestring, but it's more purpose built for doing this.

You can `import struct` and then `struct.pack('B', 255)` will result in `b'\xff` same as `chr(255).encode('iso8859-1')`, but at least expresses intent. `'B'` here signifies an `unsigned char` range, you'll find the format specifiers in the documentation. You'll get a greater benefit when you begin using multiple fields where `struct.pack` will be a lot less unwieldy than the `chr` and `encode` and string concatenation.
> 2 votes

---
Tags: arduino-uno, serial, programming, python, analogwrite
---


# Question
Title: Control DC motor in both directions with two relays
I am using an Arduino and two relays to control 12V DC motor. I need to rotate the motor in both directions.

For the first trials it worked fine. Finally one next switching fried my Arduino.

I think there is something wrong in the schematic. I believe that Arduino was killed by reverse voltage spike produced by motor.

I already know that I need a diode across the motor. However, I have two directions here.

So, what is the proper schematic for my task?

# Answer
In short, you're probably overloading your regulator.

It's difficult to say for sure, but I have a suspicion and can give a framework for thinking about it with some very crude numbers.

If you're powering the Nano from a 12 V source, you are dropping 7 V across the regulator. If you do the math on this 7 V drop, it means every 14 mA drawn through the regulator induces nearly a tenth Watt of heat in the regulator. 7 V * 0.014 A = 0.098 W. I'm guessing you have a budget of perhaps 300mW based on the way the Nano's regulator is set up.

The ATmega328P says it uses 5.2 mA (typical) or 9 mA (maximum) at 5 V and active at 8 MHz. But really it will use more at the 16 MHz frequency. For sake of argument, I'm just going to say it's using 14 mA, because it makes the math easy and because power usage scales somewhat linearly with frequency.

Just the power led will use about 3 mA, if it's an official Nano, but for simplicity sake, I'll call it 7 mA, being half of 14 mA and we'll ignore the fact that there are other loads on the board like the serial transceiver.

Your relay coils will use *at least* 30 mA, but likely more, perhaps a lot more. But for ease of calculation lets go optimistic and say they only use 28 mA (cause 2 * 14 mA).

So we have the ATMega328P inducing 100 mW in the regulator, the power led and some extras adding 50 mW. at at least one relay coil energized for another 200 mW. So right there you're already at 350 mW. If you screwed up and managed to energize both relays, 550 mW. Hopefully the regulator will enter thermal shutdown when this happens, in which case all you need to do is let it cool down and, you know, stop doing that. But it may also just die,which is more likely if you have a clone that happens to use a crappier regulator.

But, I think these numbers are conservative. For example, a datasheet for a Songle SRD-05VDC-SL-C relay that a lot of these modules use seems to say it will use closer **70 mA** each, rather than 28 mA. This means operating just one of these coils by itself, nevermind the rest of the Arduino, will cause nearly half a Watt to be dissipated in the regulator if you're powering from 12 V. If you managed to turn on both coils well... nothing good.

If this is not *the* problem you're having, it is *a* problem. You can save yourself a fair bit of trouble by powering your Nano from USB with a powered hub or reasonable quality USB-output wall adapter. Doing so bypasses your regulator altogether.

If you're going to continue staging down 12 V to 5 V for the relay coils, then you may need an external regulator to operate the relay modules, just to unload the the Nano's regulator. Exactly how you'd go about that depends somewhat on the construction of the relay module. Some of them make it a bit easier on you and are design to accept voltage from a second source for the coils.
> 2 votes

---
Tags: motor, relay
---


# Question
Title: Unable to compile c++11 libraries despite having added -std=c++11 in platform.txt
I want to use c++ data structures such as vectors, arrays, map... in my Arduino sketch. I made sure to **add -std=c++11 and -std=gnu++11 in platform.txt**, I am still getting the following error message:

> fatal error: unordered\_map: No such file or directory #include \<unordered\_map\> compilation terminated. exit status 1 unordered\_map: No such file or directory

Here's a snapshot from ~/arduino-nightly/hardware/arduino/avr/platform.txt:

Versions:

* Arduino ide: 1.8.14
* g++: 5.4.0
* avr-g++: 4.9.2

**What else should I set up?**

# Answer
The AVR-based Arduinos don't come with anything close to a full C++ standard library implementation. They have avr-libc which is fairly complete to at least the C99 standard, that is the C standard from 1999, not C++. What you're doing with `-std=c++11` is influencing the standard used by the compiler to interpret the C++ language itself. This does work fine on AVR based Arduinos, but is not going to give you the sort of C++ containers you may be used to on a desktop or larger embedded system, like an ESP8266.

Much of the C++ standard library would be completely out of place on an AVR based Arduino, particularly those parts that make use of dynamic allocation like `unordered_map` in your error message.

There are *some* parts of the C++ library implemented via Arduino STL. Whether or not you *should* be using containers from it is another question.

If you do try to use Arduino STL, I'd encourage you to use more conservative parts of it. Something like an `unordered_map`, but with less (or no) dynamic allocation could be implemented by using Arduino STL's `std::array` and functions from its `<algorithm>` header, like their `std::find` or `std::lower_bound`, etc. Trying to use a C++ `map` or `vector` container or something of that sort is kind of asking for trouble, more so on the more common AVR-based Arduinos with only roughly 2 Kbyte of RAM.
> 3 votes

---
Tags: arduino-ide, c++, compilation-errors
---


title: 4x4 matrix keypad not working

text:
# Question
Title: 4x4 matrix keypad not working
I'm working on a research project that allows me to press a button on a matrix that then outputs a parameter like temperature, humidity etc. But I cannot find out what is wrong with the buttons, when I press them nothing is happening. Thank you very much! I've attached what the connection between the Arduino and the keypad looks like.

```
#include <EEPROM.h>
#include <GravityTDS.h>
#include "DHT.h"
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <Servo.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Keypad.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
#define DHTPIN 7
#define DHTTYPE DHT11   // DHT 11
#define SensorPin A0            //pH meter Analog output to Arduino Analog Input 0
#define Offset 0.00            //deviation compensate
#define LED 13
#define samplingInterval 20
#define printInterval 800
#define ArrayLenth  40    //times of collection
#define PUMPPIN 9
#define ONE_WIRE_BUS 4
int pHArray[ArrayLenth];   //Store the average value of the sensor feedback
int pHArrayIndex = 0;
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
Servo myservo;
GravityTDS gravityTds;
DHT dht(DHTPIN, DHTTYPE);

char incomingByte;
String inputString;
int pump = 9; // Output for pump Control
double avg;
int h;
float t;
float tdsValue;
float temperature = t;
static unsigned long samplingTime = millis();
static unsigned long printTime = millis();
static float pHValue, voltage;

const byte ROWS = 4;
const byte COLS = 4;

char hexaKeys[ROWS][COLS] = {
  {'A', 'B', 'C', 'D'},
  {'E', 'F', 'G', 'H'},
  {'I', 'J', 'K', 'L'},
  {'M', 'N', 'O', 'P'}
};

byte rowPins[ROWS] = {44, 42, 40, 38};
byte colPins[COLS] = {36, 34, 32, 30};

Keypad customKeypad = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);

void setup() {

  lcd.begin();
  pinMode(pump, OUTPUT); //sets the digital pin as output
  digitalWrite(pump, LOW); // Initial state of the pump
  Serial.begin(9600);
  gravityTds.setPin(A1);
  gravityTds.setAref(5.0);
  gravityTds.setAdcRange(1024);
  gravityTds.begin();
  dht.begin();
  sensors.begin();
}

double averagearray(int* arr, int number) {
  int i;
  int max, min;
  long amount = 0;
  if (number <= 0) {
    Serial.println("Error number for the array to avraging!/n");
    return 0;
  }
  else if (number < 5) { //less than 5, calculated directly statistics
    for (i = 0; i < number; i++) {
      amount += arr[i];
    }
    avg = amount / number;
    return avg;
  } else {
    if (arr[0] < arr[1]) {
      min = arr[0]; max = arr[1];
    }
    else {
      min = arr[1]; max = arr[0];
    }
    for (i = 2; i < number; i++) {
      if (arr[i] < min) {
        amount += min;      //arr<min
        min = arr[i];
      } else {
        if (arr[i] > max) {
          amount += max;  //arr>max
          max = arr[i];
        } else {
          amount += arr[i]; //min<=arr<=max
        }
      }//if
    }//for
    avg = (double)amount / (number - 2);
  }//if
  return avg;
}

void loop() {
  lcd.print("working so far. test1");
  delay(5000);
  char customKey = customKeypad.getKey();
  int pumptime = 1000;
  switch (customKey) {
    case 'A':
      // pump
      digitalWrite(pump, HIGH); // on pump
      delay(pumptime);
      digitalWrite(pump, LOW);//off pump
      break;
    case 'B':
      // add pump time
      pumptime += 500;
      break;
    case 'C':
      // less pump time
      pumptime -= 500;
      break;
    case 'D':
      // reset pump time
      pumptime = 1000;
      break;
    case 'E':
      //temp
      sensors.requestTemperatures();
      lcd.setCursor(0, 0);
      lcd.print("Celsius temperature: ");
      lcd.print(sensors.getTempCByIndex(0));
      lcd.print((char)223);
      lcd.print("C");
      delay(5000);
      lcd.clear();
      break;
    case 'F':
      // Temperature & humidity
      h = dht.readHumidity();
      t = dht.readTemperature();
      lcd.setCursor(0, 0);
      lcd.print("Humidity:");
      lcd.print(h);
      lcd.print("%");
      lcd.setCursor(0, 1);
      lcd.print("Temperature:");
      lcd.print(t);
      lcd.print((char)223);
      lcd.print("C");
      delay(5000);
      lcd.clear();
      break;
    case 'G':
      // TDS
      h = dht.readHumidity();
      t = dht.readTemperature();
      temperature = t;
      gravityTds.setTemperature(temperature);
      gravityTds.update();
      tdsValue = gravityTds.getTdsValue();
      lcd.setCursor(0, 0);
      lcd.print("TDS: ");
      lcd.print(tdsValue);
      lcd.print("ppm");
      delay(5000);
      lcd.clear();
      delay(5000);
      lcd.clear();
      break;
    case 'H':
      // pH
      lcd.clear();
      lcd.setCursor(0, 0);
      if (millis() - samplingTime > samplingInterval)
      {
        pHArray[pHArrayIndex++] = analogRead(SensorPin);
        if (pHArrayIndex == ArrayLenth)pHArrayIndex = 0;
        voltage = averagearray(pHArray, ArrayLenth) * 5.0 / 1024;
        pHValue = 3.5 * voltage + Offset;
        samplingTime = millis();
      }
      if (millis() - printTime > printInterval)  //Every 800 milliseconds, print a numerical, convert the state of the LED indicator
      {
        lcd.print("Voltage:");
        lcd.print(voltage, 2);
        lcd.print("    pH value: ");
        lcd.println(pHValue, 2);
        digitalWrite(LED, digitalRead(LED) ^ 1);
        printTime = millis();
      }
      delay(5000);
      lcd.clear();
      break;
    case 'I':
      // test buttons
      lcd.print("buttons are working");
      delay(5000);
      lcd.clear();
      break;
    case 'J':
      //
      lcd.print("buttons are working");
      delay(5000);
      lcd.clear();
      break;
    case 'K':
      //
      lcd.print("buttons are working");
      delay(5000);
      lcd.clear();
      break;
    case 'L':
      //
      lcd.print("buttons are working");
      delay(5000);
      lcd.clear();
      break;
    case 'M':
      //
      lcd.print("buttons are working");
      delay(5000);
      lcd.clear();
      break;
    case 'N':
      //
      lcd.print("buttons are working");
      delay(5000);
      lcd.clear();
      break;
    case 'O':
      //
      lcd.print("buttons are working");
      delay(5000);
      lcd.clear();
      break;
    case 'P':
      //
      lcd.print("buttons are working");
      delay(5000);
      lcd.clear();
      break;
  }//switch
  lcd.print("working so far. test2");
  myservo.write(0);
  delay(10000);
  myservo.write(90);

  delay(1800000);

```

}

# Answer
> 1 votes
Imho, your delay function in loop() is a root cause. First, you should remove the below code

```
  myservo.write(0);
  delay(10000);
  myservo.write(90);

  delay(1800000);

```

Then,please reduce delay(5000) -\> delay(200). Build and execute your code. Press and hold a single button and take a look what happen in LCD. At least, you able to confirm the keypad hardware works well or not.

---
Tags: programming
---


title: No "Huge APP partition scheme" (ESP32)

text:
# Question
Title: No "Huge APP partition scheme" (ESP32)
I recently downloaded the expressif ESP32 library and I'm trying to run the CameraWebServer example. Attempting to compile it results in the following error:

```
Sketch uses 2529577 bytes (192%) of program storage space. Maximum is 1310720 bytes.
Sketch too big; see http://www.arduino.cc/en/Guide/Troubleshooting#size for tips on reducing it.

```

I can reduce this number (192%) to 120% by changing partition scheme from "Default" to "No OTA (Large APP)". Online I've seen people using a partition scheme called "Huge APP", which I believe would solve my problem, but I don't see that option in Tools. Only "Default", "Large App" and "Minimal SPIFFS" (which doesn't work either).

How can I get the "Huge APP" partition scheme option in Arduino IDE?

# Answer
> 5 votes
I was able to fix the issue by editing the boards.txt file and adding the following lines:

```
lolin32.menu.PartitionScheme.huge_app=Huge APP (3MB No OTA/1MB SPIFFS)
lolin32.menu.PartitionScheme.huge_app.build.partitions=huge_app
lolin32.menu.PartitionScheme.huge_app.upload.maximum_size=3145728

```

This will add a "Huge APP" partition scheme to WEMOS Lolin32.

---
Tags: esp32, partition
---


# Question
Title: How to identify Arduino Mini Pro 5v vs 3.3v
I have many Arduino Mini Pro, every from different seller. Few are 3.3v and most 5v.

I had to clean table for Xmas and now I do not have any idea how to identify 3.3v Arduinos.

They do not have any marks. I bought them on ebay.

I know 3.3v has 8mhz clock but only one my arduino has big crystal with 16.000-30.

# Answer
> 23 votes
The regulator should be marked K850(5.0V) or K833(3.3V).

A 5 volt part has a 16MHz resonator may be marked with "A1" or "A'N"
A 3.3 volt part has a 8MHz resonator may be marked with "80'0"

As others have indicated, you can apply up to 12V at the RAW pin, and measure the output of the regulator.

# Answer
> 33 votes
**Consideration** (go down for the actual solution)

If you have a lot of different China-Arduino-clones, the easiest way will be to just test it. The cloned Arduinos use a lot of different voltage regulators and often you won't even be able to find datasheets for them on Google.

Someone here provided an Arduino sketch which helps you identify the frequency with which the Atmel is running and the comments say "it is the safest method". But why? It is complicated (you need to connect the USB-TTL-converter to each of the different Arduinos and sometimes they have different pinouts, so it's error-prone - you could easily fry your Arduino if you connect the wires to the wrong pins)...

---

**Solution**

I think the safest way is just connecting a voltage in the range of `6V-12V` to the `RAW`-pin and measuring the (regulated) output of the `VCC`-pin.

There is *no reason* why this would kill your Arduino (in case your Arduino isn't broken - which would be good to know anyway; and of course you shouldn't short anything).

I've done a short sketch of how you should connect your Arduino Pro Mini:

* `RAW` \<---\> `6V-12V`
* `VCC` \<---\> multimeter (`5V = 5V Arduino`, `3.3V = 3.3V Arduino`)
* One `GND` pins to the `GND` of the power source and one `GND` pins to the `GND` of the multimeter (you can take any of the Arduino pins labeled with `GND`)

Don't worry if your Arduino looks a little bit different, just look for the pin labels. For instance, one of my 5V Arduino Pro Minis looks like this, but also has `RAW`-, `VCC`\- and `GND`-labels (just one of the `GND` pins is at a different position, make sure you check your Arduino pin-labels):

---

**Alternative**

You don't want to use the method above for some reasons? Then you need sharp eyes and some luck that the following list includes you components (some of these are collected from the other posts, some of them from my Arduinos):

* 3.3V:
    + Voltage regulators: `KB33`, `S20K`, `F34V`, `L0RA`, `L0RB`
    + Oscillators: `80e.`, `80'0`
* 5V:
    + Voltage regulators: `KB50`, `L05`, `L0UA`, `L0UB`
    + Oscillators: `R160JAC6s`, `16.000-30`, `A1`, `A'N`, `A'a`

(no limit or warranty for these details...)

---

**More Suggestions**

Some of the Arduino Pro Minis come with `MHz` and `V` markings on the back. In my case, none of these were checked. Make sure you check them as your new Arduinos arrive, so you won't have any problems identifying them later!

# Answer
> 7 votes
The safe way (i tested it). First connect to 3.3V USB-TTL output first (also 5V Mini can work with 3.3V). Now prepare this sketch:

```
void setup() {
  pinMode(13, OUTPUT);
}

void loop() {
  digitalWrite(13, HIGH);
  delay(10000);
  digitalWrite(13, LOW);
  delay(10000);
}

```

Choose "Arduino Pro/Mini" with 5v/16MHz board and upload sketch. If you see that the blinking is correct (10 sec ON/10sec OFF) - you have 5V/16MHz Arduino. Otherwise it will blink at 5 sec intervals instead of 10 sec.

# Answer
> 5 votes
Plug it in and measure the voltage on pin 4 of the MCU.

# Answer
> 4 votes
Check the label of the voltage regulator, KB50 for 5V and KB33 for 3.3

# Answer
> 3 votes
The only difference would be the regulator and crystal (8MHz on 3.3V). As @IgnacioVazquez-Abrams suggest supply power to the "raw" and measure Vcc.

# Answer
> 1 votes
On my board the regulator is marked L0UA which is the code for a 5V regulator type LP2985, L0UB is also 5V.

A 3.3V regulator would be marked L0RA or L0RB.

# Answer
> 1 votes
Some clones on ebay labeled "the simple" come with 4B2X. They are 3.3v but the maximum voltage is 10v instead of 12v so beware to not burn it out.

# Answer
> 0 votes
AVR isn't specified to work at 16MHz at a 3.3V supply; it only can work at this high frequency at 5V supply. So you'll be able to tell them apart from reading the crystal. (It's possible, but unlikely, that you have a 5V version working with an 8MHz crystal. In any case 16MHz is safe for 5V.)

# Answer
> 0 votes
On my board, the voltage regulator is marked F34V. On the back is listed "The Simple" and Arduino-Pro-Mini" I purchased it as a 3.3 v board off e-Bay, and I assume it is. I have not yet applied vcc to it and measured the output.

---
Tags: voltage-level
---


# Question
Title: Arduino stopped showing up in /dev and dmesg without response
Arduino suddenly stopped being recognized. It is not listed in `/dev` and `dmesg -w` shows no activity at all when un/plugged.

I'm on Fedora 33. The Arduino is MKR-Zero. The cable is ok - other devices work well. I tried it on windows machine - same result - in Arduino IDE the option for port is greyed out.

Very weird thing happened before this issue- when I was trying to flash sketch, audio connected to docking station switched to speakers in laptop and keyboard + mouse connected to the docking station powered down (back light on keyboard went off and could not be turned on) however the Num lock light was on.

I'm afraid that I burned the Arduino - how do I verify if that is the case. The "ON" LED is lit up when plugged in

# Answer
Ok, I have no idea what the hell is this, but when I double-press the reset button (while connected/powered on ofc) it works again. This can be seemingly cycled - press once and it goes wrong, press twice and it's ok again... round and round. Seems more like some retarded "feature"
> -1 votes

---
Tags: mkrzero
---


title: How to break connection HM10 Bluetooth?

text:
# Question
Title: How to break connection HM10 Bluetooth?
I have 2 HM10 Bluetooth modules connected to 2 Arduino Teensy running the following code.

```
void setup() {
  Serial.begin(9600);
  Serial1.begin(9600);
  // If the baudrate of the HM-10 module has been updated,
  // you may need to change 9600 by another value
  // Once you have found the correct baudrate,
  // you can update it using AT+BAUDx command
  // e.g. AT+BAUD0 for 9600 bauds
}

void loop() {
  char c;
  if (Serial.available()) {
    c = Serial.read();
    Serial1.println(c);
  }
  if (Serial1.available()) {
    c = Serial1.read();
    Serial.print(c);
  }
}

```

By pairing them using the AT commands I was able to send messages back and forth by writing to Serial1. However now when I try to send AT commands it will just send the string to the other module instead of replying OK etc. How do I break the connection and make the AT commands work again?

The tutorial I used to pair the modules.

# Answer
> 1 votes
I was able to break the connection with: AT

The data sheet says to use AT+PWRM1, but it didn't work for me. Instead the above command dropped the connection to the remote device.

From the Datasheet:

2. Execute “AT+PWRM1” command, Module will auto into sleep mode when power on or disconnect from remote device.

# Answer
> 1 votes
To Break Connection via BT Commands, I do the following (programmatically):
command 1: `AT`
command 2: `AT+IMME1`
When the BT is in Work Mode it does not recognize regular BT commands. The exception to this is the AT command by itself. But, it must be followed by another command (#2) within the Supervision Timeout Period which is fairly quick. IMME1 takes the BT back to AT Mode where it is no longer connected and will recognize your AT\[+...\] commands. If the Save Setting is enabled, it will attempt auto-reconnect too quickly...

# Answer
> 0 votes
From the device datasheet:

System KEY function (PIO0) if Low \> 1000ms:

7.3.1 If Module is in sleep mode Module will wake up immediately, if AT+NOTI value is “1”, module will send “OK+WAKE” string through UART.

**7.3.2 If Module has already connected to remote device Module will disconnect from remote device.**

7.3.3 If Module is standby mode Module will reset to default configuration. Then restart.

# Answer
> 0 votes
Somehow I ended up in such an endless auto-reconnect loop after activating AT+ROLE1 without setting AT+IMME1 first. Nothing seemed to help, not even pulling PIO0 low for 1s. I still don't even know which device my HM-10 was connecting to. It just autoconnected to something on boot...

The only way I could find to break out of this endless loop was using this sketch below. The trick was that I had to wait for "OK" response after "AT" before issuing the follow-up command "AT+RENEW" to restore factory settings.

```
#include <SoftwareSerial.h>

SoftwareSerial BTserial(8, 9);

void waitForOK()
{
  while (!BTserial.available());

  char c = BTserial.read();
  Serial.write(c);
  c = BTserial.read();
  Serial.write(c);
}

void setup()
{
  Serial.begin(9600);
  BTserial.begin(115200); // fw v700 changed default to 115200, otherwise use 9600
  Serial.println("BTserial started at 115200");

  BTserial.write("AT");
  waitForOK();
  BTserial.write("AT+RENEW");
  waitForOK();
  BTserial.write("AT+IMME1");
  waitForOK();
}

```

---
Tags: serial, programming, bluetooth, teensy
---