# Question
Title: Need assistance decyphering agriculture systems control code created by absent team member
I'm working on an agriculture system and one of my partners (who was taking care of the automation side of things) has gone MIA and we are left with arduino code running our systems that we have a basic understanding of. We're in a bit of a pickle until we can get another person on board who has this kind of expertise and would greatly appreciate any help from anyone who can assist us in modifying a few parameters of the program.

The arduino is controlling one of the generic 8 relay boards hooked up to mains voltage and 8 outlets. The outlets control lights, cO2, water pumps, and fans (which are programmed to activate when temp/humidity reaches certain levels).

We presently understand how to alter how long the relays are activated for, but what we are trying to understand is how to modify the interval at which these relays are activated (cO2/water is every 150 minutes, we would like to alter this). So for example, how would I alter the code to release cO2 every 90 minutes and activate the water pump every 5 minutes?

Any help on this matter would be greatly appreciated! Thank you so much!

```
#include <dht.h>
#include <dht.h>

dht DHT;
#define dataPin 7
//#define DHT11_PIN 7

#define CH1 1   // Connect Digital Pin 8 on Arduino to CH1 on Relay Module
#define CH2 2   // Connect Digital Pin 7 on Arduino to CH3 on Relay Module
#define CH3 3   // Connect Digital Pin 8 on Arduino to CH1 on Relay Module
#define CH4 4   // Connect Digital Pin 7 on Arduino to CH3 on Relay Module
#define CH5 5   // Connect Digital Pin 8 on Arduino to CH1 on Relay Module
#define CH6 6   // Connect Digital Pin 7 on Arduino to CH3 on Relay Module
#define CH7 9   // Connect Digital Pin 8 on Arduino to CH1 on Relay Module
#define CH8 8   // Connect Digital Pin 7 on Arduino to CH3 on Relay Module
int seconds = 0;
int minutes = 1;
int hours = 0;
int days = 0;
int temp = 28; // not used
int tempset = 25; // turn on fan temp
int minmil = 1000; //clock 60000
int watertime = 8000; //water for 8 seconds =8000
int co2time = 8000; //water for 8 seconds =8000

void setup() {
  //Setup all the Arduino Pins
  pinMode(CH1, OUTPUT);//Lights
  pinMode(CH2, OUTPUT);//Water
  pinMode(CH3, OUTPUT);// CO2
  pinMode(CH4, OUTPUT);//FAN
  pinMode(CH5, OUTPUT);//FAN
  pinMode(CH6, OUTPUT);//FAN
  pinMode(CH7, OUTPUT);//FAN
  pinMode(CH8, OUTPUT);
}

void loop() {
  int readData = DHT.read11(dataPin); // Reads the data from the sensor
  float t = DHT.temperature; // Gets the values of the temperature
  float h = DHT.humidity; // Gets the values of the humidity
   Serial.print(minutes,2);
 Serial.print(" minutes  ");
 Serial.print(hours,2);
 Serial.print(" hours ");
 Serial.print(days,2);
 Serial.print(" days ");
 Serial.println();

//int chk = DHT.read11(DHT11_PIN);
 seconds=seconds+1;
   if (seconds >= 59) {
 minutes = minutes + 1;//adds to count
    seconds = 0;
  }
  if (minutes >= 59) {
    hours = hours + 1;
    minutes = 0;
  }
  if (hours >= 23) {
    days = days + 1;
    hours = 1;
  }
  if (days >= 31) {
    days = 1;
  }
  if ((days <= 3) && (hours < 19)) {

    digitalWrite(CH1, LOW);//Lights on for first 3 days 12 hours per Day

  }
  if ((days <= 3) && (hours >= 19)) {

    digitalWrite(CH1, HIGH);//Lights on for first 3 days 12 hours per Day

  }

  if ((days > 3) && (hours < 16)) {

    digitalWrite(CH1, LOW);//Lights on for first 3 days 12 hours per Day

  }
  if ((days > 3) && (hours >= 16)) {

    digitalWrite(CH1, HIGH);//Lights on for first 3 days 12 hours per Day

  }

  if (tempset < t) { // TURN ON FANS IF ABOVE TEMP SET POINT
    digitalWrite(CH4, LOW);//Lights on for first 3 days 12 hours per Day
    digitalWrite(CH5, LOW);//Lights on for first 3 days 12 hours per Day
    digitalWrite(CH6, LOW);//Lights on for first 3 days 12 hours per Day
    digitalWrite(CH7, LOW);//Lights on for first 3 days 12 hours per Day
  }
  if (tempset >= t) { // TURN ON FANS IF ABOVE TEMP SET POINT
    digitalWrite(CH4, HIGH);//Lights on for first 3 days 12 hours per Day
    digitalWrite(CH5, HIGH);//Lights on for first 3 days 12 hours per Day
    digitalWrite(CH6, HIGH);//Lights on for first 3 days 12 hours per Day
    digitalWrite(CH7, HIGH);//Lights on for first 3 days 12 hours per Day
  }

 // if (( (hours % 2) == 0) && (minutes == 30)) { //Water every 2 hours @ 30 minute Mark
if (minutes == 3) { //Water every 2 hours @ 30 minute Mark
    digitalWrite(CH2, LOW);//
    delay(watertime); //how long water pump is engaged
    minutes = minutes + 1;
  }
  else {
    digitalWrite(CH2, HIGH);//
  }
 // if (( (hours % 2) == 0) && (minutes == 45)) { //CO2 Released every 2 hours @ 45 minute Mark
 if  (minutes == 5) { //CO2 Released every 2 hours @ 45 minute Mark
    digitalWrite(CH3, LOW);//CO2
    delay(co2time); //how long CO2 is released
    minutes = minutes + 1;
  }
  else {
    digitalWrite(CH3, HIGH);// no CO2
  }
  delay(minmil);  // (60000) - 1 minute Delay
}

```

Question: how could we alter the code in order to release co2 every 90 minutes?

# Answer
**Straight answer to the question as asked:**

To make it do this every 90 minutes would be

```
if ((hours / 60 + minutes) % 90) == 0) {

```

---

If you want something to happen every 5 minutes you would write it like this:

```
if ((minute % 5) == 0) {

```

---

I hope you can find someone who can make some improvements on this. There are much better ways to do it, beginning with a DS3231 Real-Time Clock module.

Good luck with this.
> 3 votes

# Answer
Just about all the comments are lying, mostly from copy paste-code-edit where the comment wasn't edited. It's a great example of why comments should not be used to explain code.

The timing code is full of off-by-one errors. The seconds go from 0 to 58, minutes also goes from 0 to 58, hours goes from 1 to 22, and days goes from 1 to 30.

The comments say that it runs the `loop()` once every minute but instead it's once a second.

There is no hysteresis on the fan control. Which means that in the worst case the fans can cycle on and off every time it runs through `loop()`.

The `CH1`, `CH2`, etc. can be named much better like `RELAY_LIGHT`, `RELAY_WATER`, `RELAY_CO2`, etc. After you do that you won't need the comment on each `digitalWrite`.

Turning off the water and CO2 after they have been activated can be done by setting a timestamp of when to turn it off in the globals and then checking that:

```
if (((hours % 3 == 0 && minutes == 0)  ||
    (hours % 3 == 1 && minutes == 30)) && seconds == 0) {
    digitalWrite(RELAY_CO2, LOW);
    CO2RelayOffDays = days;
    CO2RelayOffHours = hours;
    CO2RelayOffMinutes = minutes
    CO2RelayOffSeconds= seconds + CO2_ON_TIME;
    if(CO2RelayOffSeconds >= 60){
        CO2RelayOffSeconds -= 60;
        CO2RelayOffMinutes++;
    }
    if(CO2RelayOffMinutes >= 60){
        CO2RelayOffMinutes -= 60;
        CO2RelayOffHours++;
    }
    if(CO2RelayOffHours >= 24){
        CO2RelayOffHours -= 24;
        CO2RelayOffDays++;
    }
    if(CO2RelayOffDays >=30){
        CO2RelayOffDays -= 30;
    }
}

if(days == CO2RelayOffDays && hours == CO2RelayOffHours && minutes == CO2RelayOffMinutes && seconds == CO2RelayOffSeconds){
    digitalWrite(RELAY_CO2, HIGH);
}

```

Every 90 minutes means when `hours:minutes` (modulo 3 hours) is equal to `0:00` or `1:30`. But another option is keeping a timestamp of when to turn it on next by adding 1 hour and 30 seconds each time to it you turn it on.

Every 5 minutes is when `minutes%5 == 0`.

You can collect the various timestamps I suggest into a struct each and then provide a function that will wrap everything appropriately.

```
void wrapTimestamp(TimeStamp *timestamp){
    if(timestamp->seconds >= 60){
        timestamp->seconds = timestamp->seconds%60;
        timestamp->minutes += timestamp->seconds/60;
    }
    if(timestamp->minutes >= 60){
        timestamp->minutes = timestamp->minutes%60;
        timestamp->hours +=timestamp->minutes/60;
    }
    if(timestamp->hours >= 24){
        timestamp->hours = timestamp->hours%24;
        timestamp->days +=timestamp->hours/24;
    }
    if(timestamp->days >=30){
        timestamp->days = timestamp->days%30;
    }
}

```

You should consider adding a real-time-clock module that will have much less drift than delay.
> 4 votes

# Answer
There is nothing that happens every 150 minutes!

The `(hours % 2) == 0` would be true every 2 hours.

NOTE this is terrible code! I hope nothing is to dependent on things happening at a definite time, because the internal clock will drift and no allowance is made for the time other code takes to execute.
> 2 votes

# Answer
The sketch has so many issues that it's better to start afresh. Dump it. It's worthless. Anyone can rewrite it in 30 minutes while under the influence.

See: you are controlling a grow room with what seems to be 1 KW or more in HID. You can't simply switch ON an HID; you have to be sure that the HID is cold (a waiting period of 5-15 minutes).

The sketch doesn't get time from anywhere. Every time you reset the board, time goes back to zero. Kiss your light schedule goodbye.

You need to control room temperature. If the grow room goes over 30°C, you are in trouble. The minimum you can do is switch OFF the HID to cool things. And if the temp is lower than 20°, better switch OFF the extractor for a while to heat up the room. *Girls* don't like cold.

The sketch has no user interface, no way to set the light schedule, temp limits (among other things).

Replace it with a wall timer:
> 2 votes

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


# Question
Title: Interrupt volatile variable doesn't work as expected
Please examine the following code.

```
volatile uint8_t myVar;

void setup() {
  attachInterrupt(digitalPinToInterrupt(2), isr, FALLING);
  Serial.begin(115200);
}

void loop() {
  myVar = 0;
  while (myVar != 5) {
  }
  Serial.println("ISR called");
}

void isr() {
  myVar = 5;
}

```

From this code, I expect that every time the pin 2 is falling, I get one single print statement `ISR called`.

However, when dropping the voltage on pin 2 ONCE, the serial monitor shows `ISR called` TWICE.

Why is this? This is a simplified, stripped-down example of the problem I am facing with my current project.

Edit: After reading the comments, here is a bit more info. I am using a 64-button shield that is triggering the interrupt. The process is time critical since I am measuring the time it takes for the button to be pressed (I am testing people's reflexes). I will add a print statement in the interrupt to see how many times it gets called. However, I believe the interrupt is only getting called once per buttonPressed.

Thank you for your help!

# Answer
> 0 votes
Turns out, the 64 button shield calls the interrupt TWICE. Once when the button is pressed and once when it is released.

Thank you for everyone's help!

---
Tags: arduino-uno, interrupt, variables
---


# Question
Title: View Arduino M0 SD card content on a computer
Recently I bought an Arduino M0 board and I'm using it in one of my projects, which logs GPS data into an SD card.

Can an Arduino M0 be programmed as a USB SD Card reader? So that I don't have to remove the SD card from the system and use the same USB port from M0 to see the contents of the SD card directly on my computer.

# Answer
Yes, in at least some way, but what is realizable and best depends on a few things.

* A traditional "card reader" is a USB Mass Storage device which basically exports the logical blocks of the card to the USB host computer. While this is active, nothing on the embedded system may interact with the card. The embedded system will need a USB device port which can operate in this mode, suitable software, and whatever data is recorded on the card will need to be a in a filesystem (FAT or whatever) that the host PC can read, and a data format in the files that existing or custom software for that PC can make sense of.
* A different option would be to still store data on the card in a way that would be PC-compatible if the card were removed and placed in a PC, but not to be a USB Mass Storage device. Instead, you might use the existing quasi-serial interface that is the typical role of an Arduino-type board's USB port, to send or summarize the data, either directly or by interpreting it first. This could either flow into a simple terminal program, or into something custom. Typically this means less work on the Arduino side, more but more work on the PC side. Additionally, since there is never a direct export of the card's block, the embedded system continues to have access to the card the whole time, rather than having to surrender control of the card to the PC operating system as USB Mass Storage requires.
* A variation of the above could leverage the fact that if only the Arduino ever reads the card for its own purposes or to report the data to a PC, it doesn't necessarily need to store things in a PC compatible file system, or even in a file system at all.
> 2 votes

---
Tags: arduino-uno, arduino-due, sd-card
---


title: Current Arduino STL Libraries

text:
# Question
Title: Current Arduino STL Libraries
I was going to update this question but I thought that this was different.

I have been trying to get std::vector to work with the latest Arduino. I have tried downloading several libraries found online but I can not get one of them to compile correctly. So here is my question, does anyone CURRENTLY know of a Arduino STL Library that is working?

StandardCplusplus: As stated above I tried to use this library but run into problems with the new/delete functions.

Andy Brown's AVR-STL Library doesn't even seem to come close to compiling.

If anyone has a working copy of these two I would love to have a copy or if you can tell me how to get them to compile. Otherwise I really need to find a way to get Vectors working, does anyone have any ideas?

## **Edit**

I didn't want to answer this question so it is still active as I am sure there will be additions to this. Anyways I FINALLY got a library to work (for now, so far). I downloaded the StandardCplusplus library and found that in order to get any of the stl functions to work you have to add an include to the "StandardCplusplus.h" file before EVERY use, not just in the first file as stated in the Wiki on the Project page.

So I was able to get vectors to work using the following:

```
#include "StandardCplusplus.h"
#include <iterator>
#include <vector>

vector<int> test;

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

   test.push_back(1);
   test.push_back(2);
   test.push_back(3);
   test.push_back(4);
}

void loop(){
   for (int i = 0; i < test.size(); i++){
      Serial.println(test[i]);
   }
}

```

I would still like to know of other working STL Libraries as it seems that there are tons of outdated and old libraries out there.

# Answer
I maintain an Arduino plugin that's a port of uClibc++ (just like the defunct StandardCplusplus library). It's available in the Arduino library manager for Arduino versions 1.6.10 and higher. It's called ArduinoSTL.
> 6 votes

# Answer
pay you attention which kind of arduino do you use. it can compile for Mega but not for Leonardo for example
> -1 votes

---
Tags: c++, vector, stl
---


# Question
Title: Can the Leonardo Arduino be used as a USB HOST for CDC Com devices?
I am trying to connect a CDC communication device to the Leonardo USB port and have communication with it via the TTL com port. Basically I want to echo to the TTL port whatever is transmitted over USB and vice-versa.

ASCII data is transmitted out the USB from the CDC device into the USB port of the Leonardo Aurduino. The Arduino needs to *xtransfer* this info over to the UART pins D0 (RX) and D1 (TX) that are connected to the UART of another micro-controller. I should be able to test it by connecting an FTDI TTL-RS232 cable and see results and have comms in my terminal program.

I came across this sketch that appears to be basically what I want, but I think the "hosting" portion is not being set up:

```
void setup() {
  Serial.begin(9600);  // rx/tx pins
  Serial1.begin(9600); // USB port
  Serial1.write("2nd Version");
}

void loop() {
  // copy from virtual serial line to UART and vice-versa
  if (Serial.available()) {
    char c = (char)Serial.read();
    Serial1.write(c);
  }
  if (Serial1.available()) {
    char c = (char)Serial1.read();
    Serial.write(c);
  }
}

```

What am I missing? Note I am NOT trying to do HID but CDC. Basically I want to eliminate using a PC as a Host device and use the "bridge" between my CDC device and another micro-controller.

# Answer
No, the Leonardo cannot be a USB Host. You may be able to use a USB Host Shield in conjunction with the Leonardo, though I have never tried it and cannot vouch for compatibility with the Leonardo.

USB is a host-\>device protocol, not a peer-to-peer protocol. You cannot just connect two devices together. Only a USB Host can communicate with a USB device.
> 2 votes

---
Tags: arduino-leonardo
---


title: Arduino stop the loop

text:
# Question
Title: Arduino stop the loop
i have a problem with my code, i basically move a motor with the help of 3 relays, when a sensor does not detect the presence of an object part of a call, everything works perfectly, if it was after having called the function CHIAMATA() the arduino loop() stop unexplains, i certainly made a mistake, but i do not understand which.

thanks for your help this is the code....

```
#include <swRTC.h>
#include <SoftwareSerial.h>
#include <String.h>

swRTC rtc; //create a new istance of the lib
SoftwareSerial mySerial(3, 2);

const int buttonPin = 19;
const int sensorPin = 9;
const int allarmPin =  13;

int buttonState = 0;
int sensorState = 0;
int relay1 = 8;
int relay2 = 7;
int relay3 = 6;
int var = 0;

// initialize the stepper library on pins 8 through 11:

void setup() {
    rtc.stopRTC(); //stop the RTC
    rtc.setTime(12,0,0); //set the time here
    rtc.setDate(4,6,2012); //set the date here
    rtc.startRTC(); //start the RTC
  Serial.begin(19200); //choose the serial speed here
  mySerial.begin(19200);
  pinMode(allarmPin, OUTPUT);
}

void loop() {

while(mySerial.available()!=0);{}delay(10);

    Serial.print(rtc.getHours(), DEC);
    Serial.print(":");
    Serial.print(rtc.getMinutes(), DEC);
    Serial.print(":");
   Serial.print(rtc.getSeconds(), DEC);
    Serial.println(" ");

//stato riserva croccantini
sensorState = digitalRead(sensorPin);

if (sensorState == HIGH) {
    // turn LED on:
    digitalWrite(allarmPin, HIGH);
    Serial.println("Croccantini esauriti");
    Serial.println("Spia allarme ACCESA");
    Serial.println("Tramoggia DISABILITATA");
    Serial.println("Imposto la chiamata");
    while(sensorState == HIGH) {CHIAMATA(); break;}
  } else {
    // turn LED off:
    digitalWrite(allarmPin, LOW);
    Serial.println("Croccantini OK");
  }
if (sensorState == LOW && rtc.getHours()== 12 && rtc.getMinutes()== 00 && rtc.getSeconds()== 5) {startmotor();}
  //start manuale carico/scarico
  // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin);
  // check if the pushbutton is pressed.
  // if it is, the buttonState is HIGH:
    if (buttonState == 1) {
      Serial.print("Pulsante alimentazione manuale ATTIVO");
    // turn on:
  // singlestartmotor();
  }

      }

void startmotor(){
//numero di cicli di carico da eseguire (5)
 while(var < 5){
 pinMode(relay1, OUTPUT);
  pinMode(relay2, OUTPUT);
    pinMode(relay3, OUTPUT);

 digitalWrite(relay3, LOW); //ABILITA TUTTO
 //AVANTI
 digitalWrite(relay1, LOW);
 digitalWrite(relay2, LOW);
 Serial.print("AVANTI");
 delay(1000); // wait 2 seconds

 digitalWrite(relay3, HIGH);//STOP TUTTO
 digitalWrite(relay1, HIGH);
 digitalWrite(relay2, HIGH);
 delay(1000); //ATTESA PER INVERSIONE MARCIA

 //INDIETRO
 digitalWrite(relay3, LOW);//ABILITA TUTTO
 digitalWrite(relay1, HIGH);
 digitalWrite(relay2, HIGH);
 Serial.print("INDIETRO");
 delay(1000); // wait 2 seconds

  digitalWrite(relay3, HIGH);//STOP TUTTO
  delay(5000); // wait 2 seconds

  var++;
}}

void CHIAMATA() {
 mySerial.println("ATD329xxxxx135;");//dial the number, xxxx ix the phone number.
 delay(100);
 Serial.print("Chiamata in corso..."); return loop();}

```

# Answer
> 1 votes
Don't do `return loop();` With that you enter into a never ending recursion. No system can resist that.

See: `return loop();` means "evaluate loop() and return whatever it returns". Well, `loop` is `void`; it doesn't return anything.

Even worse is the recursion problem: you call `loop()`, which calls CHIAMATA, which calls `loop` ... never ending. You blow out the stack.

I don't look any further than that. Probably there are more errors.

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


# Question
Title: Arduino's Serial Monitor Showing Constant Value
I have a breadboard Arduino; made with ATMega328PU and a UART connector using a CT2102 breakout board. With the help of this site I created a simple IR sensor, now the problem is that in the Serial Monitor I'm getting a constant value of **1023**. Even on removing the receiver (photodiode), the value's starts dropping like a capacitor discharges, and then stabilizes at some value (around 260-300).

When everything was working correctly, the value dropped to a sudden **zero** on removing the receiver, but now it isn't.

The "robot" was working perfectly and was reading the values correctly, but suddenly, the values dropped; we checked it and the Serial Monitor showed the same values. To check if the connections are working, I removed a wire from the Analog Pin of the Breadboard-Duino, and the values started to drop: like a periodic function.

The following code was used:

```
int pd=2;                      //Photodiode to digital pin 2
int buzz=13;                   //piezo buzzer to digital pin 13
int senRead=0;                 //Readings from sensor to analog pin 0  or A0
int limit=850 / 4;                 //Threshold range of an obstacle
void setup()
{
  pinMode(pd,OUTPUT);
  pinMode(buzz,OUTPUT);
  digitalWrite(pd,HIGH);       //supply 5 volts to photodiode
  digitalWrite(buzz,LOW);      //set the buzzer in off mode (initial condition)
  Serial.begin(9600);          //setting serial monitor at a default baund rate of 9600
 }
void loop()
{
  int val=analogRead(senRead) / 4;  //variable to store values from the photodiode
  Serial.println(val);          // prints the values from the sensor in serial monitor
  if(val <= limit)              //If obstacle is nearer than the Threshold range
  {
   digitalWrite(buzz,HIGH);     // Buzzer will be in ON state
   delay(20);
  }
  else if(val > limit)          //If obstacle is not in Threshold range
  {
   digitalWrite(buzz,LOW);      //Buzzer will be in OFF state
       delay(20);
  }
}

```

Any help will be appreciated.

**EDIT**

The phototransistor/diode is a standard 2pin component which came with the IR sensor.

# Answer
In your initialisation where you declare each variable and 'connecting' them to a pin you make a mistake. Now you say that senRead is a digital pin instead of a analog pin. Change the value to A0 so you will get

int senRead = A0;

Also in your void Setup() you forget to declare your analog pin as an input. Add a pinMode command that sets senRead as an input.

If this doesn't fix your problem then it is probably hardware related. Check the connections on your breadboard will most of the times solve alot of problems.
> 1 votes

# Answer
I guess your ir emitter is blown.Test it with a multimeter.Apply 5v from Arduino and check the voltage between two pins or just use phone's camera.If multimeter shows anything more than 3v or it just plainly shows applied voltage the led failed or it is open.If it is not,then use phone camera and watch the led through the camera. You should see a blue light emitting from it( if it's working).
> 1 votes

# Answer
If the circuit worked perfectly, as is, and suddenly stopped working, without changing any hardware configuration, it must be a hardware related problem.

Assuming your Arduino Uno is functioning properly and the pins behave accordingly (you can test blink.ino on the pin in doubt), it's either the IR sensor went bad or a the IR LED stopped working properly. Test each component individually. For the IR sensor, you could use any remote control to emit IR light on it and see if values change.

Another way to test bad pins are to switch from A0 to A1 and from PB2 to PB3 or similar.
> 0 votes

---
Tags: led, serial, uart
---


# Question
Title: Problems with I2C connection on ESP8266 - 12F, which pins should I use?
Previously I had pined the temp/hum sensor HDC1080 with an Arduino using this sketch and everything worked fine. Now I want to run it over an ESP-12F, I uploaded it but it has issues at the time of establishing I2C connection. Basically, I'm not sure if at the end of setup() the I2C connection has actually begun, because I get this at the serial monitor:

As far as I see, the code skips everything related to Wire library. I blame it on the SDA/SCL pins, but actually none of the pins are working for me. I found that default I2C GPIO's are 2 and 14, I tried with them and got no result; later I tried with 12/16, as the commented Wire.begin line says, but it was the same. I even read some possible solutions in this post but I not even have the mentioned libraries.

Could you give me any suggestion, please? This is the sketch I'm using:

```
#include <Wire.h>

#define HDC 0x40 //B1000000 MSB
#define cociente 65536 //2^16

uint16_t humrawvalue;  //Raw data value, MS byte = valmsb, LS byte = vallsb
uint16_t temrawvalue;  //Raw data value, MS byte = valmsb, LS byte = vallsb
uint8_t humvalmsb, humvallsb;  //Raw 8-bit byte of humidity
uint8_t temvalmsb, temvallsb;  //Raw 8-bit byte of temperature
int incomingByte = 0; //Action input
float humidity, temperature;

void setup() {
  delay(100);
  Serial.begin(9600);
  delay(100);
  Serial.println("Hello");
  //Wire.begin(12,16);
  Wire.begin();
  Wire.setClockStretchLimit(1500);
}

void loop() {
  if (Serial.available() > 0) {    //User presses 1 to start sensor reading
    // read the incoming byte:
    incomingByte = Serial.read();
    yield();
    // say what you got:
    Serial.print("I received: ");
    Serial.println(incomingByte, DEC);
  }

  Serial.println("---g-");  //Just guideline

  if (incomingByte == 49){
    Serial.println("IIIII");  //Just guideline
    Wire.beginTransmission(HDC);
    Wire.write(0x00);
    Wire.endTransmission(true);
    delay(200);

    Wire.requestFrom(HDC,4,true); //It asks for 4 bytes, 2 bytes per register
    if(Wire.available()){
      Serial.println("     ");
      Serial.println("Measuring: ");
      temvalmsb = Wire.read();
      temvallsb = Wire.read();
      humvalmsb = Wire.read();
      humvallsb = Wire.read();

      Serial.println("====TEMPERATURE====");
      Serial.print("MSB: "); Serial.println(temvalmsb, BIN);
      Serial.print("LSB: "); Serial.println(temvallsb, BIN);
      temrawvalue = temvalmsb <<8| temvallsb; //Locates each byte in its proper place
      Serial.print("Temp: "); Serial.println(temrawvalue, BIN);
      temperature = ((float)temrawvalue/(float)cociente)*165.0-40.0;
      Serial.print("Temperatura [C]: "); Serial.println(temperature);

      Serial.println("====HUMIDITY====");
      Serial.print("MSB: "); Serial.println(humvalmsb, BIN);
      Serial.print("LSB: "); Serial.println(humvallsb, BIN);
      humrawvalue = humvalmsb <<8| humvallsb;
      Serial.print("Hum: "); Serial.println(humrawvalue, BIN);
      humidity = ((float)humrawvalue/(float)cociente)*100.0;
      Serial.print("Humidity [%]: "); Serial.println(humidity);

      Serial.println("     ");
      delay(3000);
    }
  }
  Serial.println("++++"); //Just guideline
  delay(3000);
}

```

Regards!

# Answer
Unlike most Arduinos, the ESP8266 doesn't have a hardware TWI, so I²C is bit-banged in software. This means that you can use any GPIO pins. By default, `Wire.begin()` initializes pins 4 (SDA) and 5 (SCL), but you can specify other pins using `Wire.begin(int sda, int scl)`.

Documentation

(Note: the datasheet specifies GPIO2 as SDA and GPIO14 as SCL, but that doesn't matter, AFAIK, it's just a convention.)
> 5 votes

# Answer
Are you referring the I2C pins on the Arduino? You could just skip the Arduino and wire it direct to the ESP8266 and in your code define which pins you are using for I2C or amend the library accordingly. If you go down this route, make sure you use the correct I2C scanner for the ESP8266. Which can be found on this Instructable, otherwise your I2C won't be detected.

http://www.instructables.com/id/ESP8266-I2C-PORT-and-Address-Scanner/

If you do stick with the Arduino, make sure the library is using the right address, again checking using the Arduino I2C scanner sketch to find which I2C address it is using.

https://playground.arduino.cc/Main/I2cScanner
> 0 votes

---
Tags: sensors, esp8266, i2c, temperature-sensor, port-mapping
---


# Question
Title: Stepper motor is not working according to code
```
#include <Stepper.h>
#define STEPS_PER_MOTOR_REVOLUTION 32
#define STEPS_PER_OUTPUT_REVOLUTION 32 * 480  //2048
Stepper small_stepper(STEPS_PER_MOTOR_REVOLUTION, 8, 10, 9, 11);
int Steps2Take;
int dirpin=8;
int steppin=9;
int buttonApin=2;
int buttonBpin=3;

void setup() {
  pinMode(dirpin,OUTPUT);
  pinMode(steppin,OUTPUT);
  pinMode(buttonApin,INPUT);
  pinMode(buttonBpin,INPUT);
}

void loop() {
  int valA=digitalRead(buttonApin);
  int valB=digitalRead(buttonBpin);
  if(valA==HIGH) {
    digitalWrite(steppin,HIGH);
    digitalWrite(dirpin,LOW);
    small_stepper.step(40000);
    delay(1000);
  }
  if(valB==HIGH) {
    digitalWrite(steppin,HIGH);
    digitalWrite(dirpin,LOW);
    small_stepper.step(-40000);
    delay(1000);
  }
  if((valA==LOW)&&(valB==LOW)) {
    digitalWrite(steppin,HIGH);
    digitalWrite(dirpin,LOW);
    small_stepper.step(0);
  }
}

```

Here I have written this code to rotate stepper motor. When the input on digital pin 2 becomes high, then the motor should rotate clockwise. When the digital pin 3 becomes high, it should rotate in a different direction. When the input on both pins is low, the motor should not move.

But with this code the motor is moving continuously even if you apply high input to digital pins.

Please suggest how to fix this problem. For input signal I am taking signal from relays: if relay is in on condition, it should give a high signal and vice versa.

# Answer
> 1 votes
I think its better to use count function .. you need to test yor stepepr motor first ..here the code to test .. i hope its will help :)

```
#define IN1  50
#define IN2  51
#define IN3  52
#define IN4  53
int Steps = 4096; //4096(full rotation 360 degree )
int cstep = 0;

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

 Serial.println("Enter character for control option:");
 Serial.println("h : anticlockwise");
 Serial.println("i : clockwise");
 }

 void loop()
{

   if (Serial.available()>0)
   switch(Serial.read())
 {
   case 'h':
   Serial.println("anticlockwise");
   for(int x=0;x<Steps;x++)
{

     step1();
     delayMicroseconds(1000);
}
  break;

   case 'i':
   Serial.println("clockwise");
     for(int x=0;x<Steps;x++)
   {

       step2();
       delayMicroseconds(900);
   }

   //delay(1000);
    break;

  }

  }

   void step1()
  {
    //stepp
    switch(cstep)
 {
   case 0:
 digitalWrite(IN1, LOW);
 digitalWrite(IN2, LOW);
 digitalWrite(IN3, LOW);
 digitalWrite(IN4, HIGH);
 break;
 case 1:
 digitalWrite(IN1, LOW);
 digitalWrite(IN2, LOW);
 digitalWrite(IN3, HIGH);
 digitalWrite(IN4, HIGH);
 break;
 case 2:
 digitalWrite(IN1, LOW);
 digitalWrite(IN2, LOW);
 digitalWrite(IN3, HIGH);
 digitalWrite(IN4, LOW);
 break;
 case 3:
 digitalWrite(IN1, LOW);
 digitalWrite(IN2, HIGH);
 digitalWrite(IN3, HIGH);
 digitalWrite(IN4, LOW);
 break;
 case 4:
 digitalWrite(IN1, LOW);
 digitalWrite(IN2, HIGH);
 digitalWrite(IN3, LOW);
 digitalWrite(IN4, LOW);
 break;
 case 5:
 digitalWrite(IN1, HIGH);
 digitalWrite(IN2, HIGH);
 digitalWrite(IN3, LOW);
 digitalWrite(IN4, LOW);
 break;
 case 6:
 digitalWrite(IN1, HIGH);
 digitalWrite(IN2, LOW);
 digitalWrite(IN3, LOW);
 digitalWrite(IN4, LOW);
 break;
 case 7:
 digitalWrite(IN1, HIGH);
 digitalWrite(IN2, LOW);
 digitalWrite(IN3, LOW);
 digitalWrite(IN4, HIGH);
 break;
 default:
 digitalWrite(IN1, LOW);
 digitalWrite(IN2, LOW);
 digitalWrite(IN3, LOW);
 digitalWrite(IN4, LOW);
 break;
 }

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

  void step2()
{
//stepp
switch(cstep)
{
 case 0:
 digitalWrite(IN1, LOW);
 digitalWrite(IN2, LOW);
 digitalWrite(IN3, LOW);
 digitalWrite(IN4, HIGH);
 break;
 case 1:
 digitalWrite(IN1, HIGH);
 digitalWrite(IN2, LOW);
 digitalWrite(IN3, LOW);
 digitalWrite(IN4, HIGH);
 break;
 case 2:
 digitalWrite(IN1, HIGH);
 digitalWrite(IN2, LOW);
 digitalWrite(IN3, LOW);
 digitalWrite(IN4, LOW);
 break;
 case 3:
 digitalWrite(IN1, HIGH);
 digitalWrite(IN2, HIGH);
 digitalWrite(IN3, LOW);
 digitalWrite(IN4, LOW);
 break;
 case 4:
 digitalWrite(IN1, LOW);
 digitalWrite(IN2, HIGH);
 digitalWrite(IN3, LOW);
 digitalWrite(IN4, LOW);
 break;
 case 5:
 digitalWrite(IN1, LOW);
 digitalWrite(IN2, HIGH);
 digitalWrite(IN3, HIGH);
 digitalWrite(IN4, LOW);
 break;
 case 6:
 digitalWrite(IN1, LOW);
 digitalWrite(IN2, LOW);
 digitalWrite(IN3, HIGH);
 digitalWrite(IN4, LOW);
 break;
 case 7:
 digitalWrite(IN1, LOW);
 digitalWrite(IN2, LOW);
 digitalWrite(IN3, HIGH);
 digitalWrite(IN4, HIGH);
 break;
 default:
 digitalWrite(IN1, LOW);
 digitalWrite(IN2, LOW);
 digitalWrite(IN3, LOW);
 digitalWrite(IN4, LOW);
 break;

 }

  cstep=cstep+1;
 if(cstep==8)
 {
  cstep=0;
  //Serial.println("habis");

  }
 }

```

# Answer
> 0 votes
Disclaimer: I've never used this library. The following is my thoughts from looking at the code.

This example seems to do basically what you want. It doesn't seem to be necessary to do any `digitalWrite`s yourself - you just need to call call `.step(x)`.

There also doesn't seem to be any need to anything in the "do nothing" case - you don't need to tell it not to step, as far as I can see.

I couldn't work out why you were stepping 40000 steps at a time. I've changed it to 1. You can change it back if I missed something.

Also note I've used `else if` so that if both inputs are high, the motor doesn't go forward AND backwards. Maybe that's the behaviour you want, and if not, again, you can change it.

```
#include <Stepper.h>
#define STEPS_PER_MOTOR_REVOLUTION 32
Stepper small_stepper(STEPS_PER_MOTOR_REVOLUTION, 8, 10, 9, 11);
int buttonApin=2;
int buttonBpin=3;

void setup()
{
    pinMode(buttonApin,INPUT);
    pinMode(buttonBpin,INPUT);
}

void loop()
{
    int valA=digitalRead(buttonApin);
    int valB=digitalRead(buttonBpin);
    if(valA==HIGH)
    {
        small_stepper.step(1);
        delay(1000);
    }
    else if(valB==HIGH)
    {
        small_stepper.step(-1);
        delay(1000);
    }
}

```

# Answer
> 0 votes
Does the relay actually connect the pin to ground when it is off? Or does it leave the input floating? If it leaves it floating then you should use a pull-down resistor to make sure the pin actually sees ground and not stray interference.

If you can rewire the relays you can use an active low configuration and save the resistor since the Arduino has built-in pullup resistors.

---
Tags: arduino-uno
---


title: HM-10 only works when holding button

text:
# Question
Title: HM-10 only works when holding button
My HM-10 bluetooth module is behaving weird.

In order to have it operate normally, I have to keep holding the small black button on it. If I ever release the button, it just disconnects from my phone (if it was connected) and doesn't show on the bluetooth devices list anymore, and its red LED light becomes low, not bright as usual.

It operated normally before.

How can I fix this?

What would some possibles causes be for this weird behavior?

UPDATE: picture showing the button on lower right corner.

# Answer
**I just had to connect the RX/TX jumpers. There was no real issue.**

I though connecting the power jumpers was enough to just see HM-10 on my phone, since I didn't care about any data. Turns out if the RX/TX jumpers are not connect, the module behaves weird.
> 0 votes

---
Tags: bluetooth
---


# Question
Title: Powering arduino sensors - what resistor should I use?
Recently I have asked a question, why my sensors do not work on external power supply (link). I have found out, that I was limiting the current too much with the resistors. I have tried using two sensors:

My logic is, if they are rated at that current, I should put a resistor in the Vin, to restrict the current to given value. But it turned out that I was wrong, because they started working only after I removed my resistors.

My questions is - should I put a resistor in there? If yes, then how do I know what resistance should I have, if the data sheet values are misleading?

# Answer
You should have NO resistor.

The datasheet states the current values the device will *pull* from the supply. Supplies DO NOT PUSH CURRENT.

Remove all resistors.

As long as the voltage is correct and the supply can provide *at least as much current as all devices combined want to use* then it will work.
> 3 votes

---
Tags: arduino-uno, sensors, current, resistor
---


# Question
Title: Arduino WiFi/ESP8266 WiFi Password Changed
I am working on a project for a friend who is not very tech savvy involving an ESP8266. It will need to be connected to his WiFi network.

The issue is that he occasionally changed the password to his WiFi network. Since I will not be able to access this device at a moments notice, it needs to be able to adapt to a change in the password. Is this possible with the ESP8266, or should I switch to an Arduino WiFi board, or is something more powerful necessary?

# Answer
The WiFiManager library was written for exactly this purpose.
> 1 votes

# Answer
Yes that's possible.

Just don't hard-code the password: store it in EEPROM.

A common way of doing it if for the ESP to present a wifi access point which serves a configuration page when it cannot successfully connect to another access point. Store the SSID and password in EEPROM.
> 0 votes

---
Tags: esp8266, wifi
---


# Question
Title: Is there a way to define an alias for a hardware Serial
I'm porting some code from Arduino Uno over to a Mega and I want to replace a SoftwareSerial defined in the previous code with one of the built-in UARTs.

Rather than go through and replace all references to the serial port, I'd prefer to create an alias for Serial1. The alias can be a constant.

In my old code, I setup the Software Serial as follows:

```
//SoftwareSerial HMI(HMIRX, HMITX); // Define software serial for the HMI adapter (RX, TX)

```

I"m not even sure where to start.

# Answer
> 2 votes
it is simple `#define HMI Serial1`

---
Tags: serial, softwareserial
---


title: My sketch is not working as intended

text:
# Question
Title: My sketch is not working as intended
I am a beginner with Arduino. I am doing something to cool down my room temperature using an exhaust fan and cooler through relays. I am trying to reduce the temperature initially using an exhaust fan and wait for 10 minutes to see if the temperature reduced to a set range. If not, the exhaust fan is turned off and the rest of the cooling is done by the cooler.

At the beginning of the program all goes well: it turns on the exhaust fan and waits 10 minutes and if it's not dropping, it transfers the job to the cooler. But after one cycle, when the temperature increases, the cooler is turned on directly, without the exhaust fan urning on, or waiting for 10 minutes and things. I tried a lot but I can't understand what is happening. Please suggest something to solve the problem.

```
#include <dht.h>

dht DHT;

#define DHT1_PIN 7 // dht11 connected to pin 7

int exhaustpin = 4; // set pin for exhaust fan relay
int coolerpin = 5; // set pin for cooler relay
boolean exhaust;
void setup(){
   Serial.begin(9600);
    pinMode(exhaustpin, OUTPUT);
  pinMode(coolerpin, OUTPUT);
  digitalWrite(exhaustpin,HIGH );
  digitalWrite(coolerpin,HIGH );
  exhaust= LOW;

}
void loop()
{

    DHT.read11(DHT1_PIN);
  Serial.print(" MY Room Temperature = ");
  Serial.println(DHT.temperature);
  Serial.print("MY Room Humidity = ");
  Serial.println(DHT.humidity);
 delay(500);
  int  roomtemp =DHT.temperature;
  static unsigned long interval;
  long interval;
  if (exhaust== LOW){
  if ((roomtemp>=30)&&(digitalRead(coolerpin)==HIGH )){
    digitalWrite(exhaustpin,LOW ); // if temperature increses above 30 the exhaust starts to work
     interval = millis();
  }
  }
   if (digitalRead(exhaustpin)==LOW){
     exhaust= !exhaust;
 if ((millis()-interval) >= 600000){
    digitalWrite(coolerpin,LOW );
    digitalWrite(exhaustpin,HIGH );   // after the starting of exhaust fan it wait for 10 minutes ,then it turn
                                      // on the cooler and turns off the exhaust fan
       }
   }
  if (roomtemp<28){
    digitalWrite(coolerpin,HIGH );
     digitalWrite(exhaustpin,HIGH );
     exhaust= !exhaust;
   // i am trying here to start cooling the room with my exhaust fan
   // then wait 10 minutes ,if it is still not less than 28 degrees turn on the cooler to do the cooling
   // and turn off the exhaust fan
   }
  }

```

# Answer
```
  if (digitalRead(exhaustpin) == LOW) {
    static unsigned long interval = millis();
    if ((millis() - interval) >= 600000) {
      digitalWrite(coolerpin, LOW);
      digitalWrite(exhaustpin, HIGH);
      // after the starting of exhaust fan it wait for 10 minutes, then it turns on
      // the cooler and turns off the exhaust fan
    }
  }

```

`interval` is only ever set once. So 10 minutes after it is first set it will remain over 10 minutes.

The simplest fix is to set `interval` to `millis()` when you set `exhaustpin` to low:

```
if ((roomtemp>=30)&&(digitalRead(coolerpin)==HIGH)) {
  digitalWrite(exhaustpin,LOW );
  // if temperature increses above 30 the exhaust starts to work
  interval = millis();
}

```
> 2 votes

---
Tags: programming
---


# Question
Title: Minimum number of Pins to use for multiplexing LEDs
whats the minimum number of pins to use when multiplexing 6 LEDs?

is there some kind of formula that can be applied to `n` LEDs?

Or in other words, how many LEDs can an Arduino Uno control without the help of a separate IC?

# Answer
> 1 votes
It depends on the style of multiplexing.

For basic Row-Column multiplexing you have N=RC - the number of LEDs is the number of rows multiplied by the number of columns. The LEDs, of course, don't have to be arranged physically in rows and columns, those are purely logical wiring concepts.

For Charlieplexing (used by the LOL shield) it's slightly more complex. The formula is: N = n² - n, where `n` is the number of pins, and `N` is the number of LEDs they can drive.

Charlieplexing can multiplex far more LEDs than traditional R/C multiplexing, but is harder to program for and wire up.

---
Tags: led, multiplexer
---


# Question
Title: Menu with switch case not behaving correctly
I hope this the right place to post this question :)

I'm trying to display a menu on a SSD1351 OLED display, to which I communicate with U8glib. I'm trying to obtain an Init screen, then, with a long press on a button (Menu), get in to a menu with 3 options (let's say option1, option2 and back). I got it working this way:

```
#include <Button.h>  // https://github.com/JChristensen/Button.git
#include "U8glib.h"
#include <Wire.h>

#define PULLUP true
#define INVERT true
#define DEBOUNCE_MS 20

Button ok(2, PULLUP, INVERT, DEBOUNCE_MS);
Button menu(5, PULLUP, INVERT, DEBOUNCE_MS);
Button down(3, PULLUP, INVERT, DEBOUNCE_MS);
Button up(4, PULLUP, INVERT, DEBOUNCE_MS);
U8GLIB_SSD1351_128X128_332 u8g(8, 9, 7);
uint8_t screen = 0;
uint8_t menu_current = 0;
void setup() {
  u8g.setFont(u8g_font_unifont);
  u8g.setDefaultForegroundColor();
  drawScreen();
}

void loop() {
  ok.read();
  menu.read();
  up.read();
  down.read();
  if (menu.pressedFor(1000) && screen == 0) {
    screen = 1;
    menu_current = 0;
    drawScreen();
  }
  if (screen == 1) {
    if (up.wasReleased()) {
      if (menu_current > 0) {
        menu_current--;
        drawScreen();
      }
    }
    if (down.wasReleased()) {
      if (menu_current < 2) {
        menu_current++;
        drawScreen();
      }
    }
    if (ok.wasReleased()) {
      switch (menu_current) {
        case 0:
          screen = 2;
          break;
        case 1:
          screen = 3;
          break;
        case 2:
          screen = 0;
          break;
          break;
      }
      drawScreen();
    }
  }
  if (screen == 2 || screen == 3) {
    if (menu.wasReleased()) {
      screen = 1;
      menu_current = 0;
      drawScreen();
    }
  }
}

void drawScreen() {
  u8g.firstPage();
  do {
    whatToDraw();
  } while (u8g.nextPage());
}

void whatToDraw() {
  switch (screen) {
    case 0: {
        u8g.drawStr(0, u8g.getFontLineSpacing(), F("Init"));
      } break;
    case 1: {
      const char *menu_strings[3] = { "option1", "option2", "Back" };
      uint8_t i, h;
      u8g_uint_t w, d;
      u8g.setFontRefHeightText();
      u8g.setFontPosTop();
      h = u8g.getFontAscent() - u8g.getFontDescent();
      w = u8g.getWidth();
      for ( i = 0; i < 3; i++ ) {
        d = (w - u8g.getStrWidth(menu_strings[i])) / 2;
        u8g.setDefaultForegroundColor();
        if ( i == menu_current ) {
          u8g.drawBox(0, i * h + 1, w, h);
          u8g.setDefaultBackgroundColor();
        }
        u8g.drawStr(d, i * h, menu_strings[i]);
      }
    }
    break;
    case 2: {
      u8g.drawStr(0, u8g.getFontLineSpacing(), F("Option1"));
    }
    break;
    case 3: {
      u8g.drawStr(0, u8g.getFontLineSpacing(), F("Option2"));
    }
    break;
    break;
  }
}

```

Everything seems to be working except the back option: when I select it, the display gets blanked instead of visualizing screen 0 ("Init"). Variables seem to be set correctly. Does anybody have an idea why this isn't working?

Thank you :)

Dario

EDIT: copied the whole sketch as requested :)

# Answer
> 1 votes
Summary: I tested @noospy project (with some modifications) and it works flawlessly.

I had to rename Button.h to ButtonM.h due name conflict with another button library. Also, I'm using new version U8g2, so I had to change some types and eliminate some calls. Finally, I used the I2C version of the OLED screen.

This is my adapted code:

```
#include <ButtonM.h>  // https://github.com/JChristensen/Button.git
#include "U8g2lib.h"
#include <Wire.h>

#define PULLUP true
#define INVERT true
#define DEBOUNCE_MS 20

Button ok(2, PULLUP, INVERT, DEBOUNCE_MS);
Button menu(5, PULLUP, INVERT, DEBOUNCE_MS);
Button down(3, PULLUP, INVERT, DEBOUNCE_MS);
Button up(4, PULLUP, INVERT, DEBOUNCE_MS);

//U8GLIB_SSD1351_128X128_332 u8g(8, 9, 7);
// Screen
U8G2_SSD1306_128X64_NONAME_1_HW_I2C u8g(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);

uint8_t screen = 0;
uint8_t menu_current = 0;

void setup() {
    u8g.begin(); // Added
    u8g.setFont(u8g_font_unifont);
//  u8g.setDefaultForegroundColor();

    drawScreen();
}

void loop() {
    ok.read();
    menu.read();
    up.read();
    down.read();

    if (menu.pressedFor(1000) && screen == 0) {
        screen = 1;
        menu_current = 0;
        drawScreen();
    }

    if (screen == 1) {
        if (up.wasReleased()) {
            if (menu_current > 0) {
                menu_current--;
                drawScreen();
            }
        }

        if (down.wasReleased()) {
            if (menu_current < 2) {
                menu_current++;
                drawScreen();
            }
        }

        if (ok.wasReleased()) {
            switch (menu_current) {
                case 0:
                    screen = 2;
                    break;
                case 1:
                    screen = 3;
                    break;
                case 2:
                    screen = 0;
                    break;
                break;
            }
            drawScreen();
        }
    }

    if (screen == 2 || screen == 3) {
        if (menu.wasReleased()) {
            screen = 1;
            menu_current = 0;
            drawScreen();
        }
    }
}

void drawScreen() {
    u8g.firstPage();
    do {
        whatToDraw();
    } while( u8g.nextPage() );
}

void whatToDraw() {
    switch (screen) {
        case 0: {
            u8g.drawStr(0,getFontLineSpacing(),"Init");
        } break;
        case 1: {
            const char *menu_strings[3] = { "option1", "option2", "Back" };
            uint8_t i, h;
            int w, d;

            u8g.setFontRefHeightText();
            u8g.setFontPosTop();

            h = u8g.getFontAscent()-u8g.getFontDescent();
            w = u8g.getWidth();
            for( i = 0; i < 3; i++ ) {
                d = (w-u8g.getStrWidth(menu_strings[i]))/2;
//                u8g.setDefaultForegroundColor();
                if ( i == menu_current ) {
                    u8g.drawBox(0, i*h+1, w, h);
//                    u8g.setDefaultBackgroundColor();
                }
                u8g.drawStr(d, i*h, menu_strings[i]);
            }
         } break;

         case 2: {
             u8g.drawStr(0,getFontLineSpacing(),"Option1");
         } break;

         case 3: {
             u8g.drawStr(0,getFontLineSpacing(),"Option2");
         } break;

         break;
    }
}

int getFontLineSpacing() {
  return 24;
}

```

**Hardware**

1. Arduino Pro Mini 3.3v 8MHz
2. 1306 0.96 inch White Color I2C IIC Communication 128 * 64 OLED Display.
3. 4x push buttons with 1K pullup resistors.

So, I don't know what your problem is, but your code is impecable.

# Answer
> 0 votes
You can consider using one of the existing menu libraries, there are some available on github. Just pick the one that best fits your needs

https://github.com/search?utf8=%E2%9C%93&q=arduino+menu&type=

---
Tags: switch, u8glib
---


# Question
Title: How to avoid odd naming rules for Arduino when writing a library?
I'm building a small library that will be used and production and released open source. I'm paying a lot of attention to the "best practices" to make sure this code is reliable and easy to use. I also would also like to make this easy to edit. I'm having an issue with the naming scheme of the whole project.

There are a few Arduino naming quirks. If I have a sketch called `mylib`:

* ...I can't create a tab called `mylib.cpp`. However, I *can* create a file called `mylib.h`...
* ...The folder and main sketch file **must** be the same name as the folder it is in
* ...The sketch name (and folder) cannot contain any spaces.

*Well, why are you creating a sketch for a library?* The Arduino IDE won't open a `.cpp` file unless there's a sketch in that folder (and you have to open the `.ino`/`.pde` file in that folder). I'm trying to get this to work with the Arduino IDE so, if users need to edit the library, then can just open the file and go to the correct tab. If they use an external editor, they won't be able to compile it to see if there are any errors.

I'd ideally just do this structure:

```
my_lib
   |- my_lib.ino
   |- mylib.cpp
   |- mylib.h

```

However, a user might see that the folder is called `my_lib` and try including the file `my_lib.h`.

I think this is a major oversight in the Arduino IDE, but I need to have this work with the Arduino IDE. If it was just me working on this code, I might consider making the library directly in a project directory, but that isn't ideal. Is there anything that I can do to bypass this/make it easy for users to edit? Is there any "standard"/"convention" that defines how to do this?

# Answer
> 5 votes
Yep, the Arduino IDE kinda sucks eventually. There is no best practise really, as Arduino `*.ino` files aren't proper c / c++ anyway. I would hope that people who know how to write C++ classes (as opposed to Arduino) would be able to do it outside the IDE.

My suggestion would be to make the \*.ino file a test file. That is, it runs a set of functions to check that the library behaves as desired. It could also include example code, so people who use the library know how to include it in their programs.

All that being said, time to fly Penguin... Ditch the Arduino IDE and go with embedXcode or some other third party IDE template :P

(I just wanted to put a pic of a penguin)

# Answer
> 3 votes
For anyone curious what I did, I ended up doing a naming convention like this:

```
my_lib_v1_2
   |- my_lib_v1_2.ino
   |- mylib.cpp
   |- mylib.h

```

Then, the user could include `mylib.h` still, and people with the Arduino IDE could edit it.

# Answer
> 0 votes
The Arduino IDE's restriction of not allowing you to create a .cpp tab with the same name as the sketch has been removed since the 1.6.12 release.

In fact, older IDE versions would happily open and save sketches that contained, e.g., mylib.ino and mylib.cpp. You just needed to create the .cpp file outside of the Arduino IDE.

The reason for this restriction in previous IDE versions was that the file in the temporary build folder generated from the preprocessed sketch was named {build.project\_name}.cpp, which would be overwritten by the other .cpp "tab" file of the same name. Of course that is not an issue for your desired usage of the Arduino IDE simply to edit library source files. Later, the Arduino developers changed to the much more sensible system of naming the preprocessed file {build.project\_name}.ino.cpp. Thus the restriction was no longer necessary.

---
Tags: library
---


# Question
Title: home automation - What's a compact way to control a light switch with Arduino without interacting with high voltage?
To be clear, this question is not about physically wiring into the light switch to control the lights - simply pressing on the switch from the outside. I apologize in advance if my electrical vocabulary isn't up to par - I'm very new to this.

I have been developing an Android app that allows me to control Particle Photon boards over the internet, and I have already installed a board that turns my computer on and off. However, I am researching ways to automate the lights (ceiling lights, not lamps) without interacting with high voltage. I have not been able to find any good information.

Does anybody have any advice?

# Answer
> 1 votes
you can glue an LED controlled by an MCU into the sensor hole of a dusk to dawn sensor. these are available in socket and outlet shapes, are UL certified, and require no messy wiring. I've been able to switch an outlet model by duct-taping an ESP8266's built-in LED against the window; can it get any simpler?

Here's a working example's parts, exploded for easy identification.

You can spot an inline socket-to-outlet adapter, a dusk-to-dawn sensor, a bulb, a cheap nodeMCU ESP8266 devboard, a short micro usb cable, a USB wall wort, and an RGB LED module attached to dupont wires. I'm wiling to bet anyone here can figure out how these pieces fit together to make a $10 "smart bulb". You can get most of these parts at the local home center, and everything shown on amazon/ebay.

Of course you won't get a lot of respect from EEs, but you will get the job done quickly and safely, and the opto-isolated controls work with any platform. I have cheaper/smaller build i've moved onto, but i still have several of these switch builds in-place for years and they work great.

I would recommend getting a dusk-to-dawn switch that is labeled as being compatible with LED bulbs; they tend to use a lower-"bleed" IGBT instead of the older/cheaper diac/triac combo which causes some low-energy bulbs to flicker when off.

# Answer
> 1 votes
I have built a 'switch-flip' controller that just attach to the regular light switch. The controller has both RFM69 radio and Bluetooth module in it so it can use iPhone (iOS app only for now) to control the switch on/off.

# Answer
> 0 votes
Walmart and others sell battery-operated units that can flip switches to turn lights off or on. Example: AutoChron Wireless Light Switch Timer, as seen in following picture.

You could buy one of these (for about $25) then hack into it and attach wires to the *On* and *Off* buttons to allow an Arduino to simulate presses of those buttons. The unit would move the switch handle accordingly.

# Answer
> 0 votes
A clumsy way would be to use a servo motor connected to the mechanics of the switch, somehow. Or in a dimmer, replace the rotating knob with the output of a servo, thus simulating it turning. Not sure if that's what you were after.

---
Tags: arduino-uno, home-automation
---


title: Sensors go crazy on external power

text:
# Question
Title: Sensors go crazy on external power
For few days, I am trying to figure out, why my sensors do not work on external power. I bought NodeMCU along with couple different sensors etc. I was happily working with them, connecting them one by one to the 3.3v pin in the NodeMCU board, programming each of them. Everything was working as expected. After I have finished, I decided it's time to use them all at once, but I knew, that for that to work, I need to provide them with enough power, as USB probably won't be enough (plus, when I'm done, I don't plan to use USB to power the system anyway). I have a module that converts 230v AC into 5v DC, and then I am stepping it down to 3.3v in order to power the sensors. After checking with multimeter, the voltages are ok, and so is the current.

My problem is, that the sensors give completely random data (most of the time they don't give any information, but once in a while they send something like 1000 times the normal value). Below you can see the schematic that I use. Can you please help me figure this out?

**Edit:** I would just like to add - I did try to run NodeMCU solely on the Ext. Power - the circuit looked exactly as below, I just connected positive output of 3.3v power source, to the 3.3v connector on NodeMCU. The board was working (I was able to control the onboard LED via WiFI), but the sensor did not. I then reconnected the sensor from external power, to NodeMcu 3.3v, and it (the sensor) worked... I have no idea why.

simulate this circuit – Schematic created using CircuitLab

# Answer
> 0 votes
I have fiddled with it a little more. Turns out, that the resistor I was putting in the circuit was the cause of failure - the sensor did not have enough power.

Now this is very weird to me, as the sensor is rated at 190uA max, and it is not working on this current. Only after I removed the resistor (so the current was around 800mA) it started operating as it should have.

# Answer
> 1 votes
Sorry I don't have reputation for a comment but this might be of help.

You didn't specify if the sensor was a breakout board. If it is then the board may already have the resistor in place, which is why removing it worked.

Now if you had the resistor in place when it was also connected to the nodeMCU, then perhaps power from it was high enough to still generate a stable operating condition (not familiar with nodeMCU) but more likely you have a power supply issue.

* Is it a module and does it have resistor on board.
* was the 27k resistor only in circuit on external power.

If the answer was yes to the above that is probably the issue.

If they are not the cause, my next check would be your external power. It could need calibration, power spikes/ripples etc but the easiest thing to do is put in a smoothing capacitor in circuit after your power supply.

Probably about 20-30% of my sensor issues are resolved by this. Another 60% are solved by fixing my screw ups and assumptions.

---
Tags: arduino-uno, sensors, esp8266, voltage-level, nodemcu
---


# Question
Title: Arduino program to Blink L LED when input matches a set pattern
I have written a code that is supposed to blink the LED on PB5 pin, when a sequence of input matches a 4 digit password input from a keypad.But the program doesn't appears to be working as expected.

keypadGetKeyPressed() returns a char output of the keypad and I want to blink led on PB5 /13 PIN

lcd.h has used PORTB is it because of that

```
        #include <avr/io.h>
        #include <util/delay.h>

        #include "lcd.h"
        #include "keypad.h"

        #include <string.h>

        int main(void) {

            // Password
            char password[4]="5678";

            char keyPressed, oldKeyPressed = 0;
            lcdInit();
            keypadSetupPins();

            lcdWriteCommand(DISPLAY_ON | BLINK | UNDERLINE);
            lcdWriteCommand(CLEAR_DISPLAY);

            char p1 = '1';
            char p2 = '2';
            char p3 = '3';
            char p4 = '4';
            char p5 = '5';

            //Sets the digital pin Pb5 or 13 as Output
            DDRB |= (1<<PB5);
            //Sets LED initially as ON, put ~ before the ( to set it off initially
        //  DDRB |= (1<<PB5);

            // to count matched character
            int count=0;
            char message[]="Logged In";
            while (1) {

                keyPressed = keypadGetKeyPressed();
                if(keyPressed==password[count]){
                    count+=1;
                }
                else{
                    //if next char doesn't match reset counter
                    count= (keyPressed==password[0])?1:0;
                }
                if(count==4){
                    //Call the required function to toggle LED
                     count=0;

                     PORTB |= ~(1<<PB5);
                    _delay_ms(1000);
                    // Turn led off by setting corresponding bit low in the PORTB register.
                    PORTB |= ~(1<<PB5);

                    _delay_ms(500);
                    lcdWriteString(message);

                }

                if (keyPressed != 0 && (keyPressed != oldKeyPressed))

                {
                    lcdWriteChar(keyPressed);
                }

                oldKeyPressed = keyPressed;

                _delay_ms(20);

                if (keyPressed == p1 ) {

                    lcdWriteString("done");
                }

            }

        }

```

keypad.h file

```
            #ifndef KEYPAD_H_
            #define KEYPAD_H_

            #include <avr/io.h>

            #define NUM_COLS    3
            #define NUM_ROWS    4

            #define COL_DIR     DDRB
            #define COL_PORT    PORTB
            #define COL_1_PIN 2
            #define COL_2_PIN   3
            #define COL_3_PIN   4

            //NB it is important that the row pins all trigger the same
            //Pin change interrupt - see p70 of the datasheet
            #define ROW_DIR     DDRC
            #define ROW_INPUT   PINC
            #define ROW_PORT    PORTC  //for pullups

            #define ROW_1_PIN   0
            #define ROW_2_PIN   1
            #define ROW_3_PIN   2
            #define ROW_4_PIN   3

            /*
             * Set up the keypad pin directions, enable the pin change interrupt
             * and drive the column pins low.
             */
            void keypadSetupPins(void);

            /*
             * Scan the keypad to determine which key is pressed.
             * Returns 0 if no key pressed and returns ascii code if key pressed.
             * Sets all the cols to low when done.
             */
            char keypadGetKeyPressed(void);

            #endif /* KEYPAD_H_ */

```

keypad.c file

```
         * Set up the keypad pin directions, pull up resistors
         * and drive the column pins low.
         */
        void keypadSetupPins(void)
        {
            //Set column pins as output pins
            COL_DIR |= ( (1<<COL_1_PIN) | (1<<COL_2_PIN) | (1<<COL_3_PIN) );

            //Set rows pins to be inputs
            ROW_DIR &= ~( (1<<ROW_1_PIN) | (1<<ROW_2_PIN) | (1<<ROW_3_PIN) | (1<<ROW_4_PIN) );

            //Enable Pullups on row pins
            ROW_PORT |= ( (1<<ROW_1_PIN) | (1<<ROW_2_PIN) | (1<<ROW_3_PIN) | (1<<ROW_4_PIN) );

            //Send out three 0's on COLs
            COL_PORT &= ~( (1<<COL_1_PIN) | (1<<COL_2_PIN) | (1<<COL_3_PIN) );

        }

        /*
         * Scan the keypad to determine which key is pressed.
         * Returns 0 if no key pressed and returns ascii code if key pressed.
         * Sets all the cols to low when done.
         */
        void passwordString(char string[])
        {
            int i = 0;

        }

        char keypadGetKeyPressed(void)
        {
            char retVal = 0;
            uint8_t rowPins;

            //Send 011 on the cols
            //Send out 0 on col 1

            COL_PORT &= ~(1<<COL_1_PIN);
            //Send out 11 on cols 2 and 3
            COL_PORT |= ( (1<<COL_2_PIN) | (1<<COL_3_PIN) );

            //CRUCIAL - delay to allow values to propagate to the rows
            _delay_us(1);

            //Read PIN reg and copy into var
            rowPins = ROW_INPUT;

                //Test row 1
                if( !(rowPins & (1<<ROW_1_PIN)) ) //if the ROW_1_PIN in the ROW_INPUT reg is NOT high
                {
                //there is a 0 on row 1 pin => Key 1 is pressed
                retVal = '1';
                }

                //Test row 2
                if( !(rowPins & (1<<ROW_2_PIN)) ) //if the ROW_2_PIN in the ROW_INPUT reg is NOT high
                {
                //there is a 0 on row 1 pin => Key 4 is pressed
                retVal = '4';
                }

                //Test row 3
                if( !(rowPins & (1<<ROW_3_PIN)) ) //if the ROW_1_PIN in the ROW_INPUT reg is NOT high
                {
                    //there is a 0 on row 1 pin => Key 7 is pressed
                    retVal = '7';
                }

                //Test row 4
                if( !(rowPins & (1<<ROW_4_PIN)) ) //if the ROW_1_PIN in the ROW_INPUT reg is NOT high
                {
                    //there is a 0 on row 1 pin => Key 7 is pressed
                    retVal = '*';
                }

            COL_PORT &= ~(1<<COL_2_PIN);
            //Send out 011 on cols 2 and 3
            COL_PORT |= ( (1<<COL_1_PIN) | (1<<COL_3_PIN) );

            //CRUCIAL - delay to allow values to propagate to the rows
            _delay_us(1);

            //Read PIN reg and copy into var
            rowPins = ROW_INPUT;

                //Test row 1
                if( !(rowPins & (1<<ROW_1_PIN)) ) //if the ROW_1_PIN in the ROW_INPUT reg is NOT high
                {
                    //there is a 0 on row 1 pin => Key 1 is pressed
                    retVal = '2';
                }

                //Test row 2
                if( !(rowPins & (1<<ROW_2_PIN)) ) //if the ROW_2_PIN in the ROW_INPUT reg is NOT high
                {
                    //there is a 0 on row 1 pin => Key 4 is pressed
                    retVal = '5';
                }

                //Test row 3
                if( !(rowPins & (1<<ROW_3_PIN)) ) //if the ROW_1_PIN in the ROW_INPUT reg is NOT high
                {
                    //there is a 0 on row 1 pin => Key 7 is pressed
                    retVal = '8';
                }

                //Test row 4
                if( !(rowPins & (1<<ROW_4_PIN)) ) //if the ROW_1_PIN in the ROW_INPUT reg is NOT high
                {
                    //there is a 0 on row 1 pin => Key 7 is pressed
                    retVal = '0';
                }

            COL_PORT &= ~(1<<COL_3_PIN);
            //Send out 011 on cols 2 and 3
            COL_PORT |= ( (1<<COL_1_PIN) | (1<<COL_2_PIN) );

            //CRUCIAL - delay to allow values to propagate to the rows
            _delay_us(1);

            //Read PIN reg and copy into var
            rowPins = ROW_INPUT;

                //Test row 1
                if( !(rowPins & (1<<ROW_1_PIN)) ) //if the ROW_1_PIN in the ROW_INPUT reg is NOT high
                {
                    //there is a 0 on row 1 pin => Key 1 is pressed
                    retVal = '3';
                }

                //Test row 2
                if( !(rowPins & (1<<ROW_2_PIN)) ) //if the ROW_2_PIN in the ROW_INPUT reg is NOT high
                {
                    //there is a 0 on row 1 pin => Key 4 is pressed
                    retVal = '6';
                }

                //Test row 3
                if( !(rowPins & (1<<ROW_3_PIN)) ) //if the ROW_1_PIN in the ROW_INPUT reg is NOT high
                {
                    //there is a 0 on row 1 pin => Key 7 is pressed
                    retVal = '9';
                }

                //Test row 4
                if( !(rowPins & (1<<ROW_4_PIN)) ) //if the ROW_1_PIN in the ROW_INPUT reg is NOT high
                {
                    //there is a 0 on row 1 pin => Key 7 is pressed
                    retVal = '#';
                }

                return retVal;
          }

```

lcd.h file

```
            #ifndef LCD_H_
            #define  LCD_H_

            #include <avr/io.h>
            #include <util/delay.h>

            //If nibble mode is enabled it is assumed that D4->D7 on the LCD
            //are connected to pins 0->3 of the data port.
            #define USE_NIBBLE_MODE    0  //0 for false, 1 for true
            #define LINE_MODE          0 //0 for ONE line mode, 1 for TWO line mode

            #define LCD_CONTROL_PORT   PORTB
            #define LCD_CONTROL_DIR    DDRB
            #define RS_PIN             PORTB0
            #define E_PIN              PORTB1

            #define LCD_DATA_PORT      PORTD
            #define LCD_DATA_DIR       DDRD

            #define CLEAR_DISPLAY       0x01
            #define DISPLAY_CURSOR_HOME 0x02
            #define DISPLAY_ON          0x0C
            #define DISPLAY_OFF         0x08
            #define UNDERLINE           0x02    //OR this with DISPLAY_ON
            #define BLINK               0x01    //OR this with DISPLAY_ON
            #define ONE_LINE_MODE       0x34
            #define TWO_LINE_MODE       0x38
            #define SET_ADDRESS         0x80    //You must OR the appropriate address with this
            #define DISPLAY_SHIFT_LEFT  0x18
            #define DISPLAY_SHIFT_RIGHT 0x1C
            #define CURSOR_SHIFT_LEFT   0x10
            #define CURSOR_SHIFT_RIGHT  0x14

            void lcdInit(void);

            void lcdWriteCommand(uint8_t command);

            void lcdWriteChar(char ch);

            void lcdWriteString(char string[]);

            #endif  /* LCD_H */

```

lcd.c file

```
            #include "lcd.h"

            /***********************************************************
             * This function sets th direction of the pins that are
             * connected to the LCD.
             * The code makes use of the #defined names in lcd.h so that
             * if the pins connected to the LCD change only lcd.h needs
             * to be changed and not the code in this file.
             *
             * This function is complete.
             **********************************************************/
            void lcdInit(void)
            {
                //set direction of control pins to be outputs
                LCD_CONTROL_DIR |= (1<<RS_PIN);
                LCD_CONTROL_DIR |= (1<<E_PIN);

                //Set direction of data port pins to be outputs
                LCD_DATA_DIR |= 0xFF;
            }

            /****************************************************
             * Sends a a single command to the LCD
             * Takes care of the register selection,
             * placing data on the data pins and toggle of E pin
             *****************************************************/
            void lcdWriteCommand(uint8_t command)
            {
                PORTB &= ~(1<<RS_PIN);

                PORTD = command;

                PORTB |= (1<<E_PIN);

                _delay_us(2); //lcd boot delay

                PORTB &= ~(1<<E_PIN);

                _delay_ms(2);
            }

            /****************************************************
             * Sends a a single ascii char to the LCD
             * Takes care of the register selection,
             * placing data on the data pins and toggle of E pin
             *****************************************************/
            void lcdWriteChar(char ch)
            {
                PORTB |= (1<<RS_PIN);

                PORTD = ch;

                PORTB |= (1<<E_PIN);

                _delay_us(2); //lcd boot delay

                PORTB &= ~(1<<E_PIN);

                _delay_ms(2);
            }

            /****************************************************
             * Writes a string to the LCD
             * Steps through the string passed as a parameter and
             * calls lcdWriteChar() to send each character of the
             * string
             *****************************************************/
            void lcdWriteString(char string[])
            {
                int i = 0;

                while (string[i] != '\0')
                {
                    lcdWriteChar(string[i]);
                    i++;
                }
            }

```

# Answer
> 1 votes
The following proposed code:

1. corrects the worst of the logic problems
2. eliminates unused/unnecessary local variables
3. performs the desired function
4. keeps data declarations local to where they are used
5. expects the keypad input function to perform the majority of the key debouncing.

and now the proposed code:

```
    #include <avr/io.h>
    #include <util/delay.h>

    #include "lcd.h"
    #include "keypad.h"

    #include <string.h>

    int main(void)
    {
        // Password
        char password[5]="5678";  // 5 to allow for trailing NUL byte

        char oldKeyPressed = 0;

        lcdInit();
        keypadSetupPins();

        lcdWriteCommand(DISPLAY_ON | BLINK | UNDERLINE);
        lcdWriteCommand(CLEAR_DISPLAY);

        //Sets the digital pin Pb5 or 13 as Output
        DDRB |= (1<<PB5);
        //Sets LED initially as ON, put ~ before the ( to set it off initially
        //  DDRB |= (1<<PB5);

        size_t count = 0;

        for( size_t i=0; i< strlen( password ); i++ )
        {
            char keyPressed = keypadGetKeyPressed();

            if(keyPressed==password[count])
            {
                count+=1;
            }

            else
            {
                count = 0;
            }

            if( count == strlen( password ) )
            {
                char message[] = "Logged In";

                //Call the required function to toggle LED
                PORTB |= ~(1<<PB5);
                _delay_ms(1000);
                // Turn led off by setting corresponding bit low in the PORTB register.
                PORTB &= ~(1<<PB5);

                _delay_ms(500);
                lcdWriteString(message);
            }

            // this code block should (probably) only be for debug
            if (keyPressed != 0 && (keyPressed != oldKeyPressed))
            {
                lcdWriteChar(keyPressed);
            }

            // debounce the keypad
            oldKeyPressed = keyPressed;
            _delay_ms(20);

            // method of exiting the program before fully logged in
            if (keyPressed ==  '1' )  // so '1' cannot be part of the password
            {
                lcdWriteString("done");
                break;
            }
        }
    }

```

---
Tags: arduino-uno, c, avr
---


# Question
Title: How to call 5 different functions in a loop based on serial input?
I have 5 types of such functions with different input parameters.

```
blink(int a,char* b, int c);
fade(int a,int b,int c);
split(int a,int d);

```

and so on from serial input what i want is to call this three functions in any combinations that can be later executed in a loop. For example my serial input is this ..

```
[blink(a,b,c),fade(a,b,c),blink(a,b,c),fade(a,b,c),split(a,d),blink(a,b,c)]

```

The Code should also be saved in memory so that when a person reset Arduino. The order of functions execute without waiting for serial input.The order of functions would get change only when person enter serial data to arduino. I have no clue where to begin please help me out.

# Answer
> 2 votes
This answer isn't going to give you the code to solve your problem, it is just ideas that you can look at and see what suits you best.

You should be able to find an example on how to read from a serial connection, I'm sure there is at least one example in the IDE.

You need to work out how to encode your data, having it in nice human friendly format (like you have above) is great if you are processing it on a PC but on a processor that is slow and have very limited memory using A,B,C... as the function names might be more practical. It will be smaller to store and quicker to compare.

You want to store the input so it can be read back later. There are a number of ways you can do this but they all need a non-volatile storage medium. You could use an SD card, obviously you'd need an SD reader and the type of reader you get will affect the code you need, but these can be problematic. You can also use EEPROM chips that, you can get little I2C interfaced modules, they have less space than an SD card, but are generally faster (they also have a shorter lifespan, but don't worry I don't you'll ware one out). You can also use the EEPROM that is in the Arduino itself (I've never done this).

It is best to build you program up in small parts, get the reading from serial working, then calling functions, then saving and loading. That way you only have to debug a small bunch of issues at once. If you wanted you could abstract the storage device away from the code by writing a base class that has virtual save and load functions. You could then inherit from this class for the EEPROM or the SD card and changing wouldn't affect the rest of the code.

Like I said at the start I appreciate this answer hasn't given you a step by step guide on how to solve your problem, but hopefully it has given you a few pointers on what you could do and you can research the options from there. Remember when you get stuck on one particular aspect just post a minimal example of what you have tried and explain what you expect it to be doing and people will be more than willing to help.

# Answer
> 1 votes
This answer isn't going to give you the code to solve your problem either, it is just tricks that you can look at and see what suits you best.

\[I'm assuming your serial input is all readable text (no binary data).\]

Made serial input fixed format: Every function name is 3 letter long, all parameters the same length, and if possible, all function the same number of parameter. That's make parsing things easy, later you can upgrade to variable length parameters.

Know you can write two small functions that read Serial and returns a single element:

```
String getFunction();
int    getArgument();

```

Each function will take care of commas and other delimiters. Also, `getArgument` will convert values as text to binary values.

You loop will look like (pseude-code, don't compile).

```
void loop() {
  String fn = getFunction();

  if (fn.equals("blink")) {
    doBlink();
  }
  if  (fn.equals("fade")) {
    doFade();
  }
 ....
 }
 void doBlink() {
    int val1 = readArgument();
    int val2 = readArgument();
    int val3 = readArgument();
    // Do some blink.
    }
 void doFade() {
    // same thing.
    }
  }

```

Now, if you want to transmit char data (strings, texts), put them at the as last parameter. You will need a third function to read a variable length string until end of the line (or some marker you choose).

---
Tags: serial, serial-data
---


title: Display values from a function on GLCD

text:
# Question
Title: Display values from a function on GLCD
I am new to Arduino and I'm trying my first Pro Mini. I was able to find DS1302 code from github that runs perfectly. My problem is trying to add some LM35 code to also display temperature data as well as the time data.

The code doesn't seem to run the Celsius and Fahrenheit functions. I have attached my code. Any help will be appreciated.

```
//Required library - http://www.rinkydinkelectronics.com/library.php?id=5
//Blog Post - http://overskill.alexshu.com/ds1302-real-time-clock-w-arduino/

#include "U8glib.h"
#include <DS1302.h>
#include <PreciseLM35.h>
//int float pinLM35 = A0;
const int pinLM35 = A0;
PreciseLM35 lm35(pinLM35, DEFAULT);

DS1302 rtc(2, 3, 4);
U8GLIB_ST7920_128X64 u8g(13, 11, 12, U8G_PIN_NONE);

void setup(void) {
  rtc.halt(false);
  rtc.writeProtect(false);

  // The following lines can be commented out to use the values already stored in the DS1302
  // Once you flash the Arduino with the correct time.

  //rtc.setDOW(FRIDAY); // Set Day-of-Week to FRIDAY
  //rtc.setTime(12, 0, 0); // Set the time to 12:00:00 (24hr format)
  //rtc.setDate(6, 8, 2010); // Set the date to August 6th, 2010

  // assign default color value
  if (u8g.getMode() == U8G_MODE_R3G3B2)
    u8g.setColorIndex(255); // white
  else if (u8g.getMode() == U8G_MODE_GRAY2BIT)
    u8g.setColorIndex(3); // max intensity
  else if (u8g.getMode() == U8G_MODE_BW)
    u8g.setColorIndex(1); // pixel on
}

void draw(void) {
  u8g.setFont(u8g_font_04b_03);
  u8g.drawStr( 2,5, "******************************");
  u8g.drawStr( 13,10, "Arduino Pro Mini Control ");
  u8g.drawStr( 24,20, (rtc.getTimeStr()));
  u8g.drawStr( 1,20, "TIME: ");
  u8g.drawStr(70,20,  "Temp (C): ");
  u8g.drawStr (80,20, (lm35.readCelsius()));
  u8g.drawStr( 25,30, rtc.getDOWStr());
  u8g.drawStr(70,30, "Temp (F): ");
  u8g.drawStr(3,30, "DAY: ");
  u8g.drawStr(80,30, (lm35.readFahrenheit()));
  u8g.drawStr( 24,40, rtc.getDateStr());
  u8g.drawStr(1,40, "DATE: ");
  u8g.drawStr(70,40, "AREF : ");
  u8g.drawStr(80,40, (lm35.readPreciseAref()));
  u8g.drawStr( 15,55, "DS1302 Real Time Clock");
  u8g.drawStr( 2,65, "********************************");
}

void loop(void) {
  // picture loop
  u8g.firstPage();
  do {
    draw();
  } while(u8g.nextPage()); //u8g.nextPage()
  // rebuild the picture after some delay
  delay(500);
}

```

# Answer
> 1 votes
Use an DS3231 RTC instead. It include a temperature sensor with digital output. No need to read an analog value and it means less component in your PCB.

---
Tags: arduino-uno
---


# Question
Title: Help setting up Dust sensor with Arduino Mega
So I wired Sharp Dust Sensor with Arduino Mega with below fritzing:

the connector cable only connects to the dust sensor as you can seee the image below:

however looking at other example projects the same dust sensor has wiring inverted. I followed the hookup and the code as given here: https://www.elecrow.com/wiki/index.php?title=Dust\_Sensor-\_GP2Y1010AU0F

but I get the result without having to connect the green wire to **A0** and Yellow wire connected to **D2**

```
Raw Signal Value (0-1023): 346.00 - Voltage: 1.69 - Dust Density: 0.19
Raw Signal Value (0-1023): 394.00 - Voltage: 1.92 - Dust Density: 0.23
Raw Signal Value (0-1023): 398.00 - Voltage: 1.94 - Dust Density: 0.23
Raw Signal Value (0-1023): 408.00 - Voltage: 1.99 - Dust Density: 0.24
Raw Signal Value (0-1023): 433.00 - Voltage: 2.11 - Dust Density: 0.26
Raw Signal Value (0-1023): 468.00 - Voltage: 2.29 - Dust Density: 0.29

```

if I connect the yellow to **A0** And green to **D2** then I get below result.

```
Raw Signal Value (0-1023): 1023.00 - Voltage: 5.00 - Dust Density: 0.75
Raw Signal Value (0-1023): 1020.00 - Voltage: 4.98 - Dust Density: 0.75
Raw Signal Value (0-1023): 1020.00 - Voltage: 4.98 - Dust Density: 0.75
Raw Signal Value (0-1023): 1023.00 - Voltage: 5.00 - Dust Density: 0.75
Raw Signal Value (0-1023): 1023.00 - Voltage: 5.00 - Dust Density: 0.75
Raw Signal Value (0-1023): 1022.00 - Voltage: 4.99 - Dust Density: 0.75
Raw Signal Value (0-1023): 1023.00 - Voltage: 5.00 - Dust Density: 0.75
Raw Signal Value (0-1023): 1020.00 - Voltage: 4.98 - Dust Density: 0.75
Raw Signal Value (0-1023): 1023.00 - Voltage: 5.00 - Dust Density: 0.75
Raw Signal Value (0-1023): 1023.00 - Voltage: 5.00 - Dust Density: 0.75
Raw Signal Value (0-1023): 1022.00 - Voltage: 4.99 - Dust Density: 0.75
Raw Signal Value (0-1023): 1023.00 - Voltage: 5.00 - Dust Density: 0.75
Raw Signal Value (0-1023): 1023.00 - Voltage: 5.00 - Dust Density: 0.75
Raw Signal Value (0-1023): 1023.00 - Voltage: 5.00 - Dust Density: 0.75
Raw Signal Value (0-1023): 1023.00 - Voltage: 5.00 - Dust Density: 0.75
Raw Signal Value (0-1023): 1023.00 - Voltage: 5.00 - Dust Density: 0.75
Raw Signal Value (0-1023): 1005.00 - Voltage: 4.91 - Dust Density: 0.73
Raw Signal Value (0-1023): 952.00 - Voltage: 4.65 - Dust Density: 0.69
Raw Signal Value (0-1023): 712.00 - Voltage: 3.48 - Dust Density: 0.49
Raw Signal Value (0-1023): 631.00 - Voltage: 3.08 - Dust Density: 0.42
Raw Signal Value (0-1023): 559.00 - Voltage: 2.73 - Dust Density: 0.36
Raw Signal Value (0-1023): 504.00 - Voltage: 2.46 - Dust Density: 0.32
Raw Signal Value (0-1023): 463.00 - Voltage: 2.26 - Dust Density: 0.28
Raw Signal Value (0-1023): 431.00 - Voltage: 2.10 - Dust Density: 0.26
Raw Signal Value (0-1023): 409.00 - Voltage: 2.00 - Dust Density: 0.24
Raw Signal Value (0-1023): 430.00 - Voltage: 2.10 - Dust Density: 0.26
Raw Signal Value (0-1023): 413.00 - Voltage: 2.02 - Dust Density: 0.24
Raw Signal Value (0-1023): 377.00 - Voltage: 1.84 - Dust Density: 0.21
Raw Signal Value (0-1023): 453.00 - Voltage: 2.21 - Dust Density: 0.28
Raw Signal Value (0-1023): 368.00 - Voltage: 1.80 - Dust Density: 0.21
Raw Signal Value (0-1023): 367.00 - Voltage: 1.79 - Dust Density: 0.20
Raw Signal Value (0-1023): 364.00 - Voltage: 1.78 - Dust Density: 0.20
Raw Signal Value (0-1023): 361.00 - Voltage: 1.76 - Dust Density: 0.20
Raw Signal Value (0-1023): 357.00 - Voltage: 1.74 - Dust Density: 0.20
Raw Signal Value (0-1023): 356.00 - Voltage: 1.74 - Dust Density: 0.20
Raw Signal Value (0-1023): 358.00 - Voltage: 1.75 - Dust Density: 0.20
Raw Signal Value (0-1023): 357.00 - Voltage: 1.74 - Dust Density: 0.20
Raw Signal Value (0-1023): 345.00 - Voltage: 1.68 - Dust Density: 0.19
Raw Signal Value (0-1023): 309.00 - Voltage: 1.51 - Dust Density: 0.16
Raw Signal Value (0-1023): 375.00 - Voltage: 1.83 - Dust Density: 0.21
Raw Signal Value (0-1023): 395.00 - Voltage: 1.93 - Dust Density: 0.23
Raw Signal Value (0-1023): 421.00 - Voltage: 2.06 - Dust Density: 0.25
Raw Signal Value (0-1023): 441.00 - Voltage: 2.15 - Dust Density: 0.27
Raw Signal Value (0-1023): 343.00 - Voltage: 1.67 - Dust Density: 0.18
Raw Signal Value (0-1023): 352.00 - Voltage: 1.72 - Dust Density: 0.19
Raw Signal Value (0-1023): 341.00 - Voltage: 1.67 - Dust Density: 0.18
Raw Signal Value (0-1023): 339.00 - Voltage: 1.66 - Dust Density: 0.18
Raw Signal Value (0-1023): 342.00 - Voltage: 1.67 - Dust Density: 0.18
Raw Signal Value (0-1023): 307.00 - Voltage: 1.50 - Dust Density: 0.15
Raw Signal Value (0-1023): 335.00 - Voltage: 1.64 - Dust Density: 0.18
Raw Signal Value (0-1023): 343.00 - Voltage: 1.67 - Dust Density: 0.18
Raw Signal Value (0-1023): 348.00 - Voltage: 1.70 - Dust Density: 0.19
Raw Signal Value (0-1023): 351.00 - Voltage: 1.71 - Dust Density: 0.19
Raw Signal Value (0-1023): 355.00 - Voltage: 1.73 - Dust Density: 0.19
Raw Signal Value (0-1023): 359.00 - Voltage: 1.75 - Dust Density: 0.20
Raw Signal Value (0-1023): 456.00 - Voltage: 2.23 - Dust Density: 0.28
Raw Signal Value (0-1023): 477.00 - Voltage: 2.33 - Dust Density: 0.30
Raw Signal Value (0-1023): 392.00 - Voltage: 1.91 - Dust Density: 0.23
Raw Signal Value (0-1023): 443.00 - Voltage: 2.16 - Dust Density: 0.27
Raw Signal Value (0-1023): 419.00 - Voltage: 2.05 - Dust Density: 0.25
Raw Signal Value (0-1023): 379.00 - Voltage: 1.85 - Dust Density: 0.21
Raw Signal Value (0-1023): 292.00 - Voltage: 1.43 - Dust Density: 0.14
Raw Signal Value (0-1023): 341.00 - Voltage: 1.67 - Dust Density: 0.18
Raw Signal Value (0-1023): 311.00 - Voltage: 1.52 - Dust Density: 0.16
Raw Signal Value (0-1023): 307.00 - Voltage: 1.50 - Dust Density: 0.15
Raw Signal Value (0-1023): 284.00 - Voltage: 1.39 - Dust Density: 0.14
Raw Signal Value (0-1023): 322.00 - Voltage: 1.57 - Dust Density: 0.17
Raw Signal Value (0-1023): 309.00 - Voltage: 1.51 - Dust Density: 0.16
Raw Signal Value (0-1023): 331.00 - Voltage: 1.62 - Dust Density: 0.17
Raw Signal Value (0-1023): 326.00 - Voltage: 1.59 - Dust Density: 0.17
Raw Signal Value (0-1023): 304.00 - Voltage: 1.48 - Dust Density: 0.15
Raw Signal Value (0-1023): 340.00 - Voltage: 1.66 - Dust Density: 0.18
Raw Signal Value (0-1023): 385.00 - Voltage: 1.88 - Dust Density: 0.22
Raw Signal Value (0-1023): 399.00 - Voltage: 1.95 - Dust Density: 0.23
Raw Signal Value (0-1023): 420.00 - Voltage: 2.05 - Dust Density: 0.25
Raw Signal Value (0-1023): 448.00 - Voltage: 2.19 - Dust Density: 0.27
Raw Signal Value (0-1023): 479.00 - Voltage: 2.34 - Dust Density: 0.30
Raw Signal Value (0-1023): 424.00 - Voltage: 2.07 - Dust Density: 0.25
Raw Signal Value (0-1023): 438.00 - Voltage: 2.14 - Dust Density: 0.26
Raw Signal Value (0-1023): 438.00 - Voltage: 2.14 - Dust Density: 0.26
Raw Signal Value (0-1023): 330.00 - Voltage: 1.61 - Dust Density: 0.17
Raw Signal Value (0-1023): 352.00 - Voltage: 1.72 - Dust Density: 0.19
Raw Signal Value (0-1023): 350.00 - Voltage: 1.71 - Dust Density: 0.19
Raw Signal Value (0-1023): 343.00 - Voltage: 1.67 - Dust Density: 0.18
Raw Signal Value (0-1023): 314.00 - Voltage: 1.53 - Dust Density: 0.16
Raw Signal Value (0-1023): 305.00 - Voltage: 1.49 - Dust Density: 0.15
Raw Signal Value (0-1023): 306.00 - Voltage: 1.49 - Dust Density: 0.15
Raw Signal Value (0-1023): 317.00 - Voltage: 1.55 - Dust Density: 0.16
Raw Signal Value (0-1023): 341.00 - Voltage: 1.67 - Dust Density: 0.18
Raw Signal Value (0-1023): 361.00 - Voltage: 1.76 - Dust Density: 0.20
Raw Signal Value (0-1023): 384.00 - Voltage: 1.88 - Dust Density: 0.22
Raw Signal Value (0-1023): 417.00 - Voltage: 2.04 - Dust Density: 0.25
Raw Signal Value (0-1023): 435.00 - Voltage: 2.12 - Dust Density: 0.26
Raw Signal Value (0-1023): 446.00 - Voltage: 2.18 - Dust Density: 0.27
Raw Signal Value (0-1023): 310.00 - Voltage: 1.51 - Dust Density: 0.16
Raw Signal Value (0-1023): 462.00 - Voltage: 2.26 - Dust Density: 0.28
Raw Signal Value (0-1023): 432.00 - Voltage: 2.11 - Dust Density: 0.26
Raw Signal Value (0-1023): 391.00 - Voltage: 1.91 - Dust Density: 0.22
Raw Signal Value (0-1023): 339.00 - Voltage: 1.66 - Dust Density: 0.18
Raw Signal Value (0-1023): 324.00 - Voltage: 1.58 - Dust Density: 0.17
Raw Signal Value (0-1023): 306.00 - Voltage: 1.49 - Dust Density: 0.15
Raw Signal Value (0-1023): 294.00 - Voltage: 1.44 - Dust Density: 0.14
Raw Signal Value (0-1023): 283.00 - Voltage: 1.38 - Dust Density: 0.13
Raw Signal Value (0-1023): 274.00 - Voltage: 1.34 - Dust Density: 0.13

```

If I connect the green wire to **A0** and Yellow wire to **D2** I get below result

```
Raw Signal Value (0-1023): 0.00 - Voltage: 0.00 - Dust Density: -0.10
Raw Signal Value (0-1023): 0.00 - Voltage: 0.00 - Dust Density: -0.10
Raw Signal Value (0-1023): 0.00 - Voltage: 0.00 - Dust Density: -0.10
Raw Signal Value (0-1023): 0.00 - Voltage: 0.00 - Dust Density: -0.10
Raw Signal Value (0-1023): 0.00 - Voltage: 0.00 - Dust Density: -0.10
Raw Signal Value (0-1023): 0.00 - Voltage: 0.00 - Dust Density: -0.10

```

I am not really sure whether I am getting the correct result or not, and have I hooked up correctly.

# Answer
The outline diagram shows the connection order:

As you can see from the image in the second row pin 1 is closest to the edge of the unit. In your image that is red. So following those down and matching them to the "Terminal Configuration":

1. V-LED = Red (Connect to 5V via resistor)
2. LED-GND = Black (GND)
3. LED = Yellow (D2)
4. S-GND = White (GND)
5. Vo = Green (A0)
6. Vcc = Blue (Connect direct to 5V)
> 1 votes

---
Tags: arduino-mega, sensors
---


# Question
Title: RadioHead Library custom configuration for RFM96 LoRa
I have a pair of Adafruit RFM96W LoRa Transceiver Breakouts and want to use them with the RadioHead library.

My pair of radios works if I use the example sketches from the adafruit tutorial, but I want to change their default configuration.

From the Datasheet of RFM96:

> For maximum flexibility the user may decide on the spread spectrum modulation **bandwidth (BW)**, **spreading factor (SF)** and **error correction rate (CR)**.

I want to configure the BF, SF and CR. I also want to be sure that the radios are working with the LoRa Modulation and that CRC is enabled. And how to set Header-Settings?

I did find the method rf.setModemConfig() which gives the capability to change the configuration to library-pre-defined ones, which is not what I want. I want to try different combinations of settings.

I did find the method rf.setModemRegisters() but I did not understand how to use it.

Any solution is welcome.

# Answer
Parameter in RH\_RF95.h

```
const RH_RF95::ModemConfig myProfile =  {
  RH_RF95_BW_62_5KHZ | RH_RF95_CODING_RATE_4_5,
  RH_RF95_SPREADING_FACTOR_1024CPS};

rf95.setModemRegisters(&myProfile);

```
> 2 votes

---
Tags: programming, communication, spi, rf
---


title: Powering 12V keypad through Arduino Uno

text:
# Question
Title: Powering 12V keypad through Arduino Uno
Arduino Uno

I'm currently working on a project which will involve entering a sequence on a 12V keypad. The keypad and its documentation can be found here: https://www.jaycar.com.au/digital-keypad-with-rfid-access-control/p/LA5353

They keypad wants 9-18V AC/12~24V DC. I'll be using the keypad to output 26 bit Wiegand to the Arduino. I'm just wondering the best way to power this system. The schematics included with the keypad show that the keypad and the controller (Arduino) should be sharing a power source. See image attached.

How can I power the 12-24V keypad through the arduino without frying it?

# Answer
> How can I power the 12-24V keypad through the arduino without frying it?

If you power the Arduino with slightly more than 12V (through the barrel jack) then you can get 12V (or slightly less than you power the Arduino with) from the VIN pin.

However the Arduino's on-board voltage regulator does tend to get a little hot when such a high voltage is used to power it. Better is just to power the keypad separately from the correct power source.

*And don't forget to connect the grounds together.*
> 1 votes

---
Tags: arduino-uno
---