title: How to optimise TX power for ESP8266?

text:
# Question
Title: How to optimise TX power for ESP8266?
I have multiple ESP8266 units programmed using Arduino SDK and I would like each one of them to adjust the transmission power to lower the power requirements.

Arduino allows setting the TX power of the ESP8266 using the function WiFi.setOutputPower(), however it is not clear to me how to choose that value.

I know that RFM69 using the LowPower library has automatic gain control using the ACK packet sent by another RFM69 module. However, with ESP8266 there is a standard AP and a similar approach would not be obvious.

How can I perform optimal gain control?

This question is independent from the choice of the WiFi mode b/g/n using WiFi.setPhyMode().

**Edit**

An idea could be to detect AP station signal strength and transmit at a power level offset by a fixed amount, decreasing that delta by one tick at every wake up, until no connection is achievable. At that point the delta should be increased by an amount corresponding to a sort of hysteresis, to jump above the no-connection threshold, and kept.

After a predefined amount of successful wake ups, for example 100, the process of decreasing the calculated delta would be tried again.

For example: AP strength -60 dB, transmission +12 dB: success -\> delta 48 dB is good.

Next wake up, delta 48.25 dB: is AP is at -55 dB, transmission would be 55-48.25 dB = 6.75 dB. If success, delta increased to 48.50 dB.

# Answer
> I would like ... to adjust the transmission power to lower the power requirements.

Is your goal to reduce overall/average power consumption, or peak current draw? If the former, then because of the high-level nature of the wifi API exposed by the ESP system, you may get a greater level of success by optimizing the time you are connected, rather than the power consumption.

That is, make sure WiFi radio is disabled while you are preparing whatever data you may wish to send over WiFi, then turn the radio on, connect+send, go back to sleep.

This blog post gives experimental details, but the gist is

*In `Setup()`:*

```
WiFi.mode( WIFI_OFF );
WiFi.forceSleepBegin();
delay( 1 );

```

*Just before you choose to connect:*

```
WiFi.forceSleepWake();
delay( 1 );

// Bring up the WiFi connection
WiFi.mode( WIFI_STA );
WiFi.begin( WLAN_SSID, WLAN_PASSWD );

```

*And, when you go to sleep, tell the system to keep the radio off by default:*

```
WiFi.disconnect( true );
delay( 1 );

// WAKE_RF_DISABLED to keep the WiFi radio disabled when we wake up
ESP.deepSleep( SLEEPTIME, WAKE_RF_DISABLED );

```

Part 3 of this blog also notes that if you will continually be connecting to the same WiFi network, you can tell the ESP8266 to not spend the time loading the previous connection's details from flash memory, but requiring you to provide them in the connection call:

```
WiFi.forceSleepWake();
delay( 1 );

// Disable the WiFi persistence.  The ESP8266 will not load and save WiFi settings in the flash memory.
WiFi.persistent( false );

WiFi.mode( WIFI_STA );
WiFi.begin( WLAN_SSID, WLAN_PASSWD );

```
> 2 votes

---
Tags: esp8266, power
---


# Question
Title: Where can I find the complete list of Arduino Serial Command & Query Strings?
I am planning to use the Arduino as a replacement for a USB-Controlled Digital I/O device, which will be integrated into an existing C++ software package that I created. I understand that the Arduino acts like a Serial device to a PC. Every serial device can be controlled by its own set of commands and queries. However, the only commands and queries that I've found for the Arduino involve flashing one-time programming to it from the "inside" rather than providing real-time automated control from the "outside."

Can anyone tell me where can I find the complete list of Arduino serial command & query strings? Thanks.

# Answer
The Arduino has no "standard" serial commands.

It is a programmable device which you have to program yourself. The only serial commands it can respond to are the serial commands you yourself program it to respond to.

There are projects around that provide a serial interface, but they are generally designed for one specific purpose, and the commands or protocol they implement are unique to that project.

The closest to what you are asking for is the Firmata firmware, which comes with the IDE, and can be used to control the Arduino through the serial port using programs on your PC.
> 2 votes

# Answer
Arduino is a computer. It is designed to run programs that interact with real world via multiple digital and analog pins.

It has a USB port (Arduino UNO) to connect with a desktop computer. You develop programs for Arduino with your Windows/Mac/Linux computer and download them to Arduino vía USB port.

So, Arduino do only what you program it to do. No command or query string involved.

An Arduino sketch access use the USB port as a Serial port. It's normally used for debugging purposes (sending back information to the PC) or for configuration/control, if you want not to add a keypad and display to your project.

Some Arduinos doesn't comes with a USB interface.
> 1 votes

---
Tags: serial, usb, communication, string, digital
---


title: Using While Loop For Accurate Delays

text:
# Question
Title: Using While Loop For Accurate Delays
I was trying to get the timing in between events right, (Event time is around 150ms and i need it to be accurate within +-1ms) and came upon this implementation. The actual application will not be affected by the roll over, but would like to see if any of you guys (experts) can point out any flaws in using an empty while loop for time events, besides slightly higher power consumption.

This implementation gave me very accurate time spacings:

```
unsigned long previousMillis = millis();
Serial.print("ONE: ");
Serial.println(millis());
while(millis() - previousMillis < 1000);
Serial.print("SECOND: ");
Serial.println(millis());

```

compared with...

```
Serial.print("ONE: ");
Serial.println(millis());
delay(1000);
Serial.print("SECOND: ");
Serial.println(millis());

```

Which yields some errors after every step.

# Answer
> 2 votes
There are many options for executing a task periodically. The most straightforward is to use a slight variation of code given in the Blink Without Delay\[\] Arduino tutorial:

```
const uint32_t PERIOD = 150000;  // 150 ms

void loop() {
    static uint32_t last_time;
    if (micros() - last_time >= PERIOD) {
        last_time += period;
        do_periodic_task();
    }
    do_other_tasks();
}

```

Note two changes relative to the code in the tutorial:

1. This is using `micros()` instead of `millis()`. This way the timing resolution is 4 µs instead of 1 to 2 milliseconds.
2. `last_time` is updated as `last_time += period` instead of `last_time = micros()`. This way, even if the periodic task got delayed by the other tasks, these delays don't add up.

The timing will not be perfect: you will have both drift and jitter. The drift comes from the inaccuracy of the ceramic resonator clocking the microcontroller. These resonators have typically 0.5% frequency tolerance, although the typical frequency error is more likely to be around ±0.1% (i.e. 0.15 ms error in a 150 ms period). Note that a poorly written code would add it's own drift, e.g. if you do `last_time = micros()`, but this does not.

The jitter comes from the fact that the clock is checked only once per loop iteration, and your periodic task can then be delayed by the other tasks. The amplitude of the jitter is the maximum time taken by a loop iteration.

Despite these imperfections, this would be my first choice unless I really needed better timing accuracy.

If you need lower drift, one option is to calibrate your Arduino clock. You measure how fast or slow it is, and you tweak the `PERIOD` constant accordingly. For example, if you measure the clock to be 700 ppm slow, you would fix it like this:

```
const uint32_t NOMINAL_PERIOD = 150000;  // 150 ms

// Adjust the period to account for clock drift.
const float FREQUENCY_OFFSET = -700e-6;  // -700 ppm
const uint32_t PERIOD = NOMINAL_PERIOD * (1 + FREQUENCY_OFFSET);

```

This technique allows you to tune the frequency with about 6.7 ppm resolution, for a period of 150 ms. You cannot reasonably expect anything better, as the frequency of the ceramic resonator is not very stable anyway.

If you need lower jitter, one option is to perform a *blocking wait*: you ask the processor to do nothing but wait until it's time to perform the periodic task. This is similar to the code you posted in your question:

```
void loop() {
    static uint32_t last_time;
    while (micros() - last_time < PERIOD) ;  // busy wait
    last_time += period;
    do_periodic_task();
}

```

This will not completely suppress the jitter, but it will reduce it to just the time taken by the `while` loop. However, there is a big issue with this way of coding: now your processor does *nothing* but the periodic task. It may not be a problem right now, but as your project grows, it is more than likely that at some point you will want to handle extra tasks like, e.g. responding to some user input.

If you want to avoid completely blocking the processor on the busy wait, yet you want the smallest possible jitter, you could try some sort of compromise: you let the processor take care of other tasks until it is *almost* time to perform the periodic task. Then you switch to the blocking mode where the processor does nothing but wait for the clock. Here, “almost time” would be defined by the maximum time your loop can take:

```
const uint32_t MAX_LOOP_TIME = 2000;  // assume 2 ms

void loop() {
    static uint32_t last_time;
    if (micros() - last_time >= PERIOD - MAX_LOOP_TIME) {
        while (micros() - last_time < PERIOD) ;  // busy wait
        last_time += period;
        do_periodic_task();
    }
    do_other_tasks();
}

```

Another option, that has been mentioned in comments, is to trigger the task by a timer. This will work if it is a very short task that can safely be run with interrupts disabled. You have four 16-bit timers on your Mega, so you can presumably spare one for timing this task. This could be done with Timer 1 as follows (warning: untested code):

```
const int TIMER_PRESCALER = 64;
const float F_TIMER = F_CPU / TIMER_PRESCALER;
const float PERIOD = 150e-3;
const uint16_t TIMER_PERIOD = F_TIMER*PERIOD + 0.5;  // round to nearest

void setup() {
    TCCR1B = 0;            // stop the timer
    OCR1A  = TIMER_PERIOD - 1;
    TIFR1 |= _BV(OCF1A);   // clear TIMER1_COMPA interrupt flag
    TIMSK1 = _BV(OCIE1A);  // enable TIMER1_COMPA interrupt
    TCCR1A = 0;            // no PWM
    TCCR1B = _BV(WGM12)    // CTC mode, TOP = OCR1A
           | _BV(CS10)     // clock at F_CPU / 64
           | _BV(CS11);    // ditto
}

ISR(TIMER1_COMPA) {
    do_periodic_task();
}

```

Note that `TIMER_PERIOD` will be 37500. If you want to tune it to account for an inaccurate clock frequency, your tuning resolution will be about 26.7 ppm.

The interrupt technique should get you sub-microsecond jitter *most of the time*. However, every now and then the Timer 0 interrupt (the one responsible for updating the `millis()` counter) will delay your interrupts for a few microseconds. Beware also that some libraries can delay interrupts for excessive amounts of time. Software Serial is an infamous offender.

# Answer
> 0 votes
Those two are not the same "program". The first one start counting before `Serial.print`. The other first print and then delay for a second.

We have two piece of code:

* The first take 1000ms to reach "SECOND" (plus some overhead).
* The second take 1000ms + time needed for two Serial.prints and a millis() call to reach "SECOND" (plus the same overhead).

The first approach is better, because you start counting before doing operations of undetermined length. So, it's immune to any factor affecting running time, like time spent in interrupts. And you don't need to retune it if you change the sketch.

# Answer
> 0 votes
For better accuracy, you should not be "delaying until it's time to do something", but instead "checking if it's time to do it yet".

It's all very well saying you want something to happen every 150ms and delaying between actions for 150ms, but that won't yield you an event that happens every 150ms - it yields you an event that takes X amount of time with a delay of Y between each event, resulting in an overall period of X+Y, which is not what you want.

I cover the proper ways to deal with timing of regular events in this existing answer:

---
Tags: arduino-mega
---


# Question
Title: Arduino Vending Machine to monitor coin slot input while waiting for user input
I have this project called Onionskin Vending machine. The function should be: when a coin is inserted, the pulses from the coin acceptor (which is not accurate sometimes so i didn't use attachInterrupt) is recorded by the Arduino and is shown to the user as Credits. then while still waiting for coin input, it will ask the user to select a product.

EX. Scenario 1: The user drops a 1cent coin, then the machine will show the user its credit as 1cents and will ask to press a button. the user will press a button then the machine will turn on a motor for (X) seconds to dispense product and say thank you then resets again.

EX. Scenario 2: The user drops a 5cent coin, then the machine will show the user its credit as 5cents and will ask to press a button. then the user will drop again a 1cent coin so the machine will show its credit as 6cents and will again ask to press a button. the user will press a button then the machine will turn on a motor for (6X) seconds to dispense product and say thank you then resets again.

Here is the code I wrote so far, but the problem is when activated, it only records the first cent/pulse then goes on waiting for user input to press a button, even if I drop more coins, it will not count the new coins inserted, only always the 1cent / 1 Credit is displayed.

**EDIT:** There is no target credit, 1cents would do. but if user drop 2cents, then 2 Sets of product should be dispensed upon user selection of product. ***So target is the arduino should wait for coin slot input while waiting for user input at same time.***

```
#include <Wire.h>  // Comes with Arduino IDE, Required for I2C
#include <LiquidCrystal_I2C.h>  //Call LCD I2C Library

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);   // Set the LCD I2C address Set up data transmission from microcontroller to LCD

int coinPin = 2;            //Defined as the receiving pin from the coin machine.
int coinState = 0;          //Determine the status of coinPin
int credits = 0;            //Define a variable to display the credit.
int delayTime = 0;          //Define delay variable for number of onionskin sheet feed duration
int resetPin = 12;          //Define reset pin for resetting after complete function
int sensorPin = A0; // select the input pin for LDR
int sensorValue = 0; // variable to store the value coming from the sensor
const int laserPin = 6;
const int shortSizeFeedTime = 5000;  //Duration for 2pc onionskin to pass feeder
const int longSizeFeedTime = 7500;   //Duration for 3pc onionskin to pass feeder
const int ledpin = 13;      //define LED Pin at pin13
const int ButtonS = 8;      //Define button for short onionskin
const int ButtonL = 7;      //Define button for long onionskin
const int shortSize = 9;    //Define pin for motor pin shortSize
const int longSize = 10;    //Define pin for motor pin longSize

void setup()
{
  digitalWrite(resetPin, HIGH);
  delay(200);
  pinMode(coinPin, INPUT);     //Determine the function of the buttton pin to the input pin.
  pinMode(resetPin, OUTPUT);  //Set Reset PIN as OUTPUT
  pinMode(shortSize, OUTPUT);
  pinMode(longSize, OUTPUT);
  pinMode(laserPin, OUTPUT);         //Laser PIN
  /*
    lcd.begin(16, 2);         //Schedule your columns and rows. LCD
    lcd.setCursor(4,0);         //Set the cursor's starting position at position(4,0)
    lcd.print("WELCOME");      //Display screen text LCD
    lcd.setCursor(0,1);         //Set the cursor's starting position at position(0,1)
    lcd.print("PLZ  INSERT COIN");      //Display screen text LCD
  */
  Serial.begin(9600);  // Begin Serial Connection to PC

  lcd.begin(16, 2);  // initialize the lcd for 16 chars 2 lines, turn on backlight
  pinMode(ButtonS, INPUT_PULLUP);
  pinMode(ButtonL, INPUT_PULLUP);
  digitalWrite(laserPin, HIGH);// used as a laser trip wire sensor
  start(); //GOTO Start FUNCTION
  //delay(8000);
  // Wait and then tell user they can start the Serial Monitor and type in characters to
  // Display. (Set Serial Monitor option to "No Line Ending")
  //lcd.clear();
  //lcd.setCursor(0,0); //Start at character 0 on line 0
}

void start()
{
  //-------- Write characters on the display ------------------
  // NOTE: Cursor Position: (CHAR, LINE) start at 0
  lcd.clear();
  lcd.setCursor(4, 0); //Start at character 4 on line 0
  lcd.print("WELCOME!");
  delay(1000);
  lcd.setCursor(0, 1);
  lcd.print(" ->Insert Coin<-");
  loop();
}

void loop()
{
  sensorValue = analogRead(sensorPin);//read the status of the LDR attached to the analog pin for laser trip wire
  coinState = digitalRead(coinPin);   //coinPin value In the coinState
  lcd.setCursor(0, 0);        //Set the cursor's starting position at position(0,0)
  while (analogRead(sensorPin) < 1000)
  {
    lcd.clear();
    lcd.print("PLS. REMOVE ANY");
    lcd.setCursor(0, 1);
    lcd.print("OBJECT FRM TRAY!");
    delay(2000);
    start();
  }
  if (coinState == LOW)         //Condition
  {
    credits += 1;          //Calculate the value of the variable. It will increase each time. 5
    delay(500);                        //Delay schedule 500ms.
    lcd.clear();            //Clear command all LCD screen
    lcd.print("CREDIT:");         //Display LCD Display Message
    lcd.setCursor(8, 0);        //Set the cursor's starting position at position(8,0)
    lcd.print(credits);            //Displays the value of variable "credit" on the LCD screen.
    lcd.setCursor(12, 0);        //Set the cursor's starting position at position(8,0)
    lcd.print("PHP");          //Display screen text LCD
    lcd.setCursor(0, 1);
    lcd.print("PRESS TO PROCEED");

    //Wait for button input from user
    while (digitalRead(ButtonS) == HIGH || digitalRead(ButtonL) == HIGH) {

      //---------Servo A----------------
      if (digitalRead(ButtonS) == LOW && sensorValue > 1000)  {
        lcd.clear();
        lcd.setCursor(4, 0);
        lcd.print("VENDING:");
        lcd.setCursor(0, 1);
        lcd.print("LONG ONIONSKIN");
        delayTime = credits * longSizeFeedTime;
        digitalWrite(longSize, HIGH);//Turn on the feeder motor
        delay(delayTime); //calculation time for 2pc of onionskin
        digitalWrite(longSize, LOW);//Turn off the feeder motor
        lcd.clear();
        lcd.setCursor(3, 0);
        lcd.print("THANK YOU!");
        lcd.setCursor(0, 1);
        lcd.print("PLS. COME AGAIN!");
        credits = 0;//set the credits back to zero
        delay(3000);
        digitalWrite(resetPin, LOW);//optional for activation harware reset pin
        start();//GO to start function, kind of reset
        break;//this never actually happens :)
      } // when item is dispensed exit loop and return to wait for coin

      //---------Servo B-------------
      else if (digitalRead(ButtonL) == LOW && sensorValue > 1000) {
        lcd.clear();
        lcd.setCursor(4, 0);
        lcd.print("VENDING:");
        lcd.setCursor(0, 1);
        lcd.print("SHORT ONIONSKIN");
        delayTime = credits * shortSizeFeedTime;//calculation time for 2pc of onionskin
        digitalWrite(shortSize, HIGH);//Turn on the feeder motor
        delay(delayTime);
        digitalWrite(shortSize, LOW);//Turn off the feeder motor
        lcd.clear();
        lcd.setCursor(3, 0);
        lcd.print("THANK YOU!");
        lcd.setCursor(0, 1);
        lcd.print("PLS. COME AGAIN!");
        credits = 0;
        delay(3000);
        digitalWrite(resetPin, LOW);//optional for activation harware reset pin
        start();//GO to start function, kind of reset
        break;//Again, this never happens :)
      }
    }//End While Loop
  }//End If coin detect loop
}//End void loop()

```

PS: I have read somewhere that using millis could help solve the dual running problem or by using the correct while or switch-case loop. I'm not familiar much about how while, do-while, for, switch loops work.

# Answer
After several research here is the final working code and solution to the problem.

```
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// Constants

bool userSelect = false;
const int coinPin = 2;      // Defined as the receiving pin from the coin machine.
int coinState = 0;          // Determine the status of coinPin
volatile int credits = 0;   // Define a variable to display the credit.
int delayTime = 0;          // Define delay variable for number of onionskin feed duration
int resetPin = 12;          // Define reset pin for resetting after complete function
int sensorPin = A0;         // select the input pin for LDR
int sensorValue = 0;        // variable to store the value coming from the sensor
const int laserPin = 6;
const int shortSizeFeedTime = 5000;  // Duration for 2pc OnionSkin to pass feeder
const int longSizeFeedTime = 7500;   // Duration for 3pc OnionSkin to pass feeder
const int ledpin = 13;      // Define LED Pin at pin13
const int ButtonS = 4;      // Define button for short Size OnionSkin
const int ButtonL = 5;      // Define button for long Size OnionSkin
const int shortSize = 6;    // Define pin for motor pin shortSize
const int longSize = 7;    // Define pin for motor pin longSize

//I2C pins declaration for LCD
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

//CoinInterrupt counter function
void coinInterrupt() {

  // Each time a pulse is sent from the coin acceptor, interrupt main loop to add 1 cent and flip on the LED
  credits += 1;
  digitalWrite(ledpin, HIGH);
  digitalWrite(ledpin, LOW);
}

//Long OnionSkin Feeder function
void longSkinServe() {
  lcd.clear();
  lcd.setCursor(4, 0);
  lcd.print("VENDING:");
  lcd.setCursor(0, 1);
  lcd.print("LONG ONION SKIN");
  delayTime = credits * longSizeFeedTime;
  digitalWrite(longSize, HIGH);
  delay(delayTime);
  digitalWrite(longSize, LOW);
  lcd.clear();
  lcd.setCursor(3, 0);
  lcd.print("THANK YOU!");
  lcd.setCursor(0, 1);
  lcd.print("PLS. COME AGAIN!");
  delay(3000);
  digitalWrite(resetPin, LOW);
  credits = 0;
  userSelect = false;
}

//Short OnionSkin Feeder function
void shortSkinServe() {
  lcd.clear();
  lcd.setCursor(4, 0);
  lcd.print("VENDING:");
  lcd.setCursor(0, 1);
  lcd.print("SHORT ONION SKIN");
  delayTime = credits * shortSizeFeedTime;
  digitalWrite(shortSize, HIGH);
  delay(delayTime);
  digitalWrite(shortSize, LOW);
  lcd.clear();
  lcd.setCursor(3, 0);
  lcd.print("THANK YOU!");
  lcd.setCursor(0, 1);
  lcd.print("PLS. COME AGAIN!");
  delay(3000);
  digitalWrite(resetPin, LOW);
  credits = 0;
  userSelect = false;
}

void setup() {
  Serial.begin(9600);  // Begin Serial Connection to PC
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);  // initialize the lcd for 16 chars 2 lines, turn on backlight
  lcd.print("STARTING UP...");
  attachInterrupt(digitalPinToInterrupt(coinPin), coinInterrupt, RISING);
  pinMode(ledpin, OUTPUT);
  pinMode(resetPin, OUTPUT);  //Set Reset PIN as OUTPUT
  pinMode(shortSize, OUTPUT);
  pinMode(longSize, OUTPUT);
  //  pinMode(laserPin, OUTPUT);         //Laser PIN
  pinMode(ButtonS, INPUT_PULLUP);
  pinMode(ButtonL, INPUT_PULLUP);
  delay(2000);

}

// Main loop
void loop() {
  if (credits == 0) {//not yet running, there is no credit yet
    lcd.clear();
    lcd.print("ONION SKIN VENDO");
    lcd.setCursor(0, 1);
    lcd.write("-[INSERT COINS]-");
    delay(3000);
    lcd.clear();
    lcd.print("-[INSERT COINS]-");
    lcd.setCursor(1, 1);
    lcd.write("P1 or P5 ONLY");
    Serial.println("No Coin Inserted Yet...Waiting");
    delay (3000);

    //---Wait for Coin/Credit-----------
    while (credits > 0 && userSelect == false) { //if coin inserted stay in servo enable loop

      lcd.clear();            //Clear command all LCD screen
      lcd.print("CREDITS:");         //Display LCD Display Message
      lcd.setCursor(9, 0);        //Set the cursor's starting position at position(8,0)
      lcd.print(credits);            //Displays the value of variable "credit" on the LCD screen.
      lcd.setCursor(12, 0);        //Set the cursor's starting position at position(8,0)
      lcd.print("PHP");          //Display screen text LCD
      lcd.setCursor(0, 1);
      lcd.print("PRESS TO PROCEED");
      Serial.println("Credits:");
      Serial.print(credits);
      if (digitalRead(ButtonS) == HIGH || digitalRead(ButtonL) == HIGH) {

        if (digitalRead(ButtonS) == LOW)  {
          //execute short size motor
          userSelect = true;
          shortSkinServe();
        }
        else if (digitalRead(ButtonL) == LOW)
        {
          userSelect = true;
          longSkinServe();
        }
      }
      delay (80); // for while loop LCD refresh speed control
    }

  }

}

```

Also here is a circuit diagram.

Some may say that the coding is not efficient as using several if else..if statements, but hey, this solves the problem. Cheers!
> 0 votes

# Answer
Make it a state machine:

Initial state is idle, nothing on the tray, no credit

If a coin is entered then it counts the credits and displays it. (Should always be true)

If a button is pushed then only if credit is sufficient and tray is empty will something be vended (and credit is subtracted), otherwise show error for a few seconds.

Showing an error can be done by setting a global and a start time and duration:

```
long credit;
enum{noError, insufficientCredit, trayError, thankyou};
int error;
unsigned long messageTimestamp;
unsigned long messageDuration;

void updateLCD(){
    if(millis() - messageTimestamp > messageDuration)
        error=noError;
    switch(error){
    case noError: break;

    case insufficientCredit:

        //show insufficient credit error
        break;
    case trayError:

        //show tray error
        break;
    case thankyou:

        //show thankyou message
        break;
    }

    if(credit == 0){
        //show attract mode
    }else{
        //show credit
    }
}

```

You can do something similar for the motor:

```
bool motorOn;
unsigned long motorTimestamp;
unsigned long motorDuration;

if(motorOn && millis() - motorTimestamp> motorDuration){
    motorOn = false;
    digitalWrite(shortSize, LOW);//Turn off the feeder motor
}

```

this way you can also prevent the vending from starting again while the motor is still running by making an extra check on `motorOn`.
> 2 votes

---
Tags: arduino-uno, programming, millis
---


# Question
Title: How I can divide information stream from bluetooth hc-06?
All good afternoon or evening. I am having a problem writing a sketch for Arduino using Arduino UNO and Bluetooth HC - 06.

My program does not divide the input stream of information into several variables. No matter how many variables I specify, they are considered as one.

Maybe I do not know all subtleties of the use of Serial.read(). Apparently from a sketch given below I get through Bluetooth two variables of color and var. A microcontroller perceives these two variables as one and as a result does not execute before him task. As a result we will be able to choose the color and change delay of blinking by this color.

If anybody knows how to correct this problem or can point me to a similar project I will be very thankful for any rendered help

```
const int rPin = 3;
const int gPin = 5;
const int bPin = 6;
int chosed_color;
int val;
int color;

void setup()
{
  Serial.begin(9600);
  pinMode( rPin, OUTPUT );
  pinMode( gPin, OUTPUT );
  pinMode( bPin, OUTPUT );

}

void loop()
{
while(Serial.available()>0)
  {
     color = Serial.read();
   if(color==1)
      {
       chosed_color = rPin;
      digitalWrite( rPin, HIGH );
      digitalWrite(rPin, LOW);
       return chosed_color;
      }
        else if(color==2)
      {
       chosed_color = bPin;
       digitalWrite( bPin, HIGH );
      digitalWrite(bPin, LOW);
       return chosed_color;
      }
         else if(color==3)
      {
        chosed_color = gPin;
       digitalWrite( gPin, HIGH );
       digitalWrite(gPin, LOW);
       return chosed_color;
      }
  }
if(Serial.available()>0)
{
  val = Serial.read();
}

      digitalWrite( rPin, HIGH );
      delay(val);
      digitalWrite(rPin, LOW);
      delay(val);
}

```

# Answer
Your code have various issues.

This:

```
   if(color==1)
      {
       chosed_color = rPin;
      digitalWrite( rPin, HIGH );
      digitalWrite(rPin, LOW);
       return chosed_color;
      }

```

means that when you find a color, you exit `loop()` instead of reading the `val` variable.

**Serial.read**

`Serial.read` read only one byte. If you need to read an arbitrary integer, need `Serial.parseInt` or some elaborate solution. As it, you are only able to read one-digit integer values.

Worse, when you type "1" in the Serial Monitor, what the program received is the value 49 (the ascii code for char 1).

Also, you have to filter non interesting chars, like LF, CR, commas or whatever char you use as delimitir.

Please, read the excelent post by Majenko about Reading Serial on the Arduino.

Here a better version of your code. It is very basic and lacks all error checking, etc.

```
const int rPin = 3;
const int gPin = 5;
const int bPin = 6;
int pins[3] = {rPin, gPin, bPin};

void setup()
{
    Serial.begin(9600);
    pinMode(rPin, OUTPUT);
    pinMode(gPin, OUTPUT);
    pinMode(bPin, OUTPUT);
}

void loop()
{
    if(Serial.available()>0) {
        int color = Serial.read();
        int chosed_color = pins[color-1];
        digitalWrite(chosed_color, HIGH);
        digitalWrite(chosed_color, LOW);

        if(Serial.available()>0) {
            int val = Serial.read();
            digitalWrite(chosed_color, HIGH); // I suppose you want this
            delay(val);
            digitalWrite(chosed_color, LOW);
            delay(val);
        }
    }
}

```
> 1 votes

# Answer
You have a misconception, how serial communication works. The data is transmitted one byte at a time and not in one bunch (even if you type it in the Serial Monitor in as one string). So, when you use distinct if- or while-statements for each variable, the data may arrive at any step in these statements, without any possibility to distinguish between the variables.

You have to ways dealing with serial messages (I prefer the latter for it is more flexible):

* **Constant message length:** You can always send messages with the same length. This is suitable for small projects with only one functionality, so that you always send the same amount of data. In this case you can wait for all bytes of a message to arrive and then treat the message as a whole:

```
if(Serial.available() >= 2){
  variable1 = Serial.read();
  variable2 = Serial.read();
}

```
* **Using a delimiter character for each message:** After each message you can send an extra byte, which value you treat as a delimiter for a message. Normally with this method you save each available byte in an extra buffer, until you receive your delimiter character (often the newline character is used `'\n'`):

```
void setup(){
  String message="";
}

void loop(){
  while(Serial.available>0){
    char c = Serial.read();
    if(c == '\n'){
      // Message is complete in buffer variable
      // Extract values from it
      if(message.length>0){
        byte variable1 = message[0];
      }
      if(message.length>2){
        int variable2 = (message[1] << 8) | message[2];
      }
      // Reset buffer variable
      message = "";
    } else {
      // Message is not complete, add byte to buffer variable
      message += c;
    }
  }
}

```

As said in the other answers you have to decide, how to send numerical data.

* You can send direct byte data as I used in the code above. When you are sending a bigger value to the Arduino than 1 byte, you can take the corresponding number of bytes from the buffer and put them into one variable (`<< 8` shifts the byte data 8 bytes to the left (in the direction of the MSB); `|` makes a bytewise or, that puts the bytes together in this code).
* If you want to type in values in the serial monitor, you have to consider, that these are simple ASCII encoded strings. In this case you can use the `String.toInt()` function and it's siblings on a substring of your message, that contains the numerical value.
> 1 votes

# Answer
Communication is done only with bytes. A byte is ALWAYS a numerical value and you cant' transmit more than one byte at a time. Saying that, you have two points to understand:

1) how do you want to "see" the result, from a human point of view?

2) how can you transmit more than one byte?

Just test this little sketch:

```
 void setup() {
Serial.begin(9600);
Serial.println(65);
Serial.println("65");
Serial.println("A");

Serial.write(65);
Serial.write('A');
}

void loop()
{
}

```

You will get on the serial monitor: 65 65 A AA

Check for ASCII table on the internet and you'll see a list of code for letters representation.

Now: Serial.println("65"); don't print the number 65. It prints the "letters" for human representation of this number. In fact, 65 is a number but here is the "human word".

*If you have 65 potatoes in a bag, a french will say "soixante cinq". An Englisman will say "sixty five" and a portuges will say "sesenta y cinquo". But they have all the same number of potatoes.*

So the computer has the **number** but the human has the **visual representation of the number**.

Serial.print convert automaticly the numerical value in a "letter value". So when you do Serial.print(65) you don't print ONE byte... but TWO! First one is the human representation of 6 (which has the ASCII value of 54) and the the human representation of 5 (which has the ASCII value of 53)

Then the next line also print 65 because I have had "quote". So Serial.print dsplay this as a text.

The third write "A" which is a "text"

Then we use Serial.write(). Serial.write **don't** try to create a "human" point of view. So it uses directly the number as an ASCII value. As 65 is the ASCII value for A, Serial.write(65) send only ONE byte and show it as the ASCII letters so A. And of course Serial.write('A') give the same result.

For transmission, this is the very first point to understand: if you transmit a byte with value of 65 you'll get this same value on the other side. But depending on the way you display, you can be fooled and believe transmission was wrong (*"I send 'A' and receive 65!"*)

For the second point ("how can I transmit more than a byte"): if you have 2 values to send and each one is on one byte, you have to send two bytes. While receiving, you put the first byte coming in, in a variable, and the second in an other.

If you have to transmit a values using an INT so two bytes, you have to "break" the INT into bytes.

Eg the INT as a value of 3154 (in décimal). Its Hexa representation is 0x0C52. You can break this in two blocks: 0x0C it the value of half of the INT and 0x52 is the other part.

So you can transmit 0x0C (higher part of the INT), then 0x52 (lower part of the INT) and while receiving you use the two bytes to "build again" the INT value.

To send 0x0C52 (INT) and 0xF345AC12 (LONG) you must send: 0x0C, 0x52, 0xF3, 0x45, 0xAC and 0x12 so a total of 6 bytes. Then while receiving you "build back" the value. Of course, if you don't remember the way you "break for sending", you can be confused. Because 0x0C, 0x52, 0xF3, 0x45, 0xAC and 0x12 can be seen as:

* six bytes
* three INT (0x0C52, 0xF345 and 0xAC12),
* one long and two bytes (0x0C52F345, 0xAC and 0x12) etc...

So you must "rebuild" according to the way you "break" the data while sending!

Hope this will help understanding.
> 0 votes

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


title: Can you use digital pins as PWM output?

text:
# Question
Title: Can you use digital pins as PWM output?
I am currently working on a robotics project that requires 16 PWM outputs to control 16 servos. Is it possible to use Arduino Uno's digital pins as PWM output pins through code?

If it is not possible, what microcontrollers do you suggest to use on such a project?

# Answer
> 2 votes
Only specific Digital Pins marked with ~PWM can generate a PWM signal. In the case of arduino Uno the pins 3,5,6,9,10,11 are all hardware PWM driven, and are marked on the Uno with a ~ or something. Others can be driven with software PWM(though I wouldn't recommend it). As the Arduino Uno uses the ATMEGA328P, the number of pins is same with other boards using same processor.

On the other hand if you want to run 16pins for PWM, its best if you use Arduino MEGA 2560 because its processor supports more than 6 Hardware pins for PWM. Also you get the advantage of a higher memory storage for your code

# Answer
> 0 votes
PWM is not used to control servos. Servos need a pulse that is 1 to 2 ms wide, with 1.5 ms wide being the center position, that occur every 20 ms (50 Hz).

A 2560 has enough timers and the library to control up to 48 servos.

---
Tags: arduino-uno, arduino-mega, programming, pwm
---


# Question
Title: Using timer2's ISR instead of timer1's in Arduino wiring.c breaks Serial object
I want to change *timer0* frequency because I need to use 4 PWM pins at a frequency lower than 500Hz and the SPI on an ATmega328. So I changed *timer2* to *Fast PWM* with 64 divisor, enabled the overflow interrupt for timer2 and disabled the overflow interrupt for timer0:

```
  TCCR2A = _BV(WGM21) | _BV(WGM20);
  TCCR2B = _BV(CS22);
  TIMSK2 |= (1 << TOIE2); // enable overflow interrupt for timer2
  TIMSK0 &= ~(1 << TOIE0); // disable overflow interrupt for timer0

```

and changed the ISR vector in *wiring.c* from `ISR(TIMER0_OVF_vect)` to `ISR(TIMER2_OVF_vect)`.

But `delay` doesn't work. What can be the problem?

# Answer
> 1 votes
> Now everything works except for delay()

`delay()` uses `micros()` and `micros()` reads the hardware registers, like this:

```
unsigned long micros() {
    unsigned long m;
    uint8_t oldSREG = SREG, t;

    cli();
    m = timer0_overflow_count;
#if defined(TCNT0)
    t = TCNT0;
#elif defined(TCNT0L)
    t = TCNT0L;
#else
    #error TIMER 0 not defined
#endif

#ifdef TIFR0
    if ((TIFR0 & _BV(TOV0)) && (t < 255))
        m++;
#else
    if ((TIFR & _BV(TOV0)) && (t < 255))
        m++;
#endif

    SREG = oldSREG;

    return ((m << 8) + t) * (64 / clockCyclesPerMicrosecond());
}

```

You would need to change all those references (TCNT0, TIFR0, TOV0 etc.) to use the Timer 2 equivalents.

---
Tags: interrupt, timers
---


title: UID value arduino uno

text:
# Question
Title: UID value arduino uno
How to read UID value in arduino uno to PHP language? before, thanks for a lot

# Answer
Use this library: https://github.com/rubberneck/php-serial

On GNU/Linux, you may need to be a member of the ‘dialout’ group. Ubuntu solves this problem by making its users members of every group, so you may not need to edit `/etc/group`

Once you have connected via a USB or USB-TTL cable (the latter will not force a reset upon connect), use a buffer to store all the reads, then parse them.
> 1 votes

---
Tags: programming
---


# Question
Title: Can not initialize ESP module in Arduino SoftwareSerial
Can not initialize ***ESP module*** in Arduino SoftwareSerial's example sketch in configuring ***WiFi module***.

In the sketch it tells:

```
#include "WiFiEsp.h"
// Emulate Serial1 on pins 6/7 if not present
#ifndef HAVE_HWSERIAL1
#include "SoftwareSerial.h"
SoftwareSerial Serial1(11,12); // RX, TX
#endif

```

I plugged jumper wires in from esp8266 RX to Digital 11 of mega which is RX and TX of esp8266 to Digital 12 of mega, and I compile the code and looked at the Serial Monitor, but it says:

```
[WiFiEsp] Initializing ESP module
[WiFiEsp] >>> TIMEOUT >>>
[WiFiEsp] >>> TIMEOUT >>>
[WiFiEsp] >>> TIMEOUT >>>
[WiFiEsp] >>> TIMEOUT >>>
[WiFiEsp] >>> TIMEOUT >>>
[WiFiEsp] Cannot initialize ESP module

```

Advise is greatly appreciated.

# Answer
> 1 votes
```
#ifndef HAVE_HWSERIAL1
#include "SoftwareSerial.h"
SoftwareSerial Serial1(11,12); // RX, TX
#endif

```

Because your Mega has a Hardware `Serial1` port, `HAVE_HWSERIAL1` is defined. Thus the lines inside that preprocessor conditional will not be compiled. This means you should connect the ESP8266 to the `Serial1` lines on your Mega:

```
Mega | ESP8266
--------------
19   | TX
18   | RX

```

---
Tags: arduino-mega, esp8266, wifi, softwareserial
---


# Question
Title: Honeywell HPMA115S0, sensor not start again after stop
I use HPMA115S0 sensor with Arduino for Nodemcu, i can read it value but face one problem. The sensor not work after send stop measure command (fan not start too).

```
const int StartPmMeasure[4] = {0x68, 0x01, 0x01, 0x96};
const int StopPmMeasure[4] =  {0x68, 0x01, 0x02, 0x95};
...
void stopSensor() {
  if (isSensorStart) {
   Serial.println("INFO: Stop sensor");
   sendCommand(AutoSendOff);
   sendCommand(StopPmMeasure);
   isSensorStart = false;
 }
}

void startSensor() {
 if (!isSensorStart) {
  Serial.println("INFO: Start sensor");
  sendCommand(StartPmMeasure);
  sendCommand(AutoSendOn);
  isSensorStart = true;
 }
}

```

# Answer
I have the same problem here. I'm using a HPMA115S0 with an ESP8266 and found out that the sensor don't respond in general if you are doing a deep sleep with the ESP. If the ESP wakes up, the sensor does not respond on commands till you remove the 5 volts of the HPMA for a short time to make an "hard reset" of the sensor.

I think there is a problem with the ttl-level on the UART-RX-line of the HPMA. Because if you're pulling the rx-line of the sensor manually to ground (maby the ESP is doing this if he goes to deep sleep or wakes up), the sensor does not respond after that.

I spend very much time in this phenomenon. I used different pins on the ESP for software UART and used the hardware UART, problem still exists. I assume that the ESP pulls all his pins on ground level for too long. That means that the stop bit (high-level), which the sensor wants after 8 bits are transmitted, is not present. This leads to strange behavior of the sensor. I don't have a digital storage scope to see the level on rx-line, so this is only a presumption. But I don't have this problem, if the ESP idles with an sleep-command. Maby you are also doing a deepsleep with your ESP which results in the same problem?

Best regards
> 1 votes

---
Tags: nodemcu
---


# Question
Title: Missing character when introducing delay in the code
I am using the following code for reading any incoming message, and doing something after decoding the incoming string. There is a delay of 10sec in the code. When this delay is not introduced in the code, it is working nice. In this case, the output is like below.

```
+CIEV: "MESSAGE",1

+CMT: "+919080404532",,"2018/02/09,19:30:51+06"
This is an incoming test message

```

When the delay is introduced, I am unable to see the message on the serial monitor, and subsequent action is not taken by the code. The output is like below.

```
+CIEV: "MESSAGE",1
+CMT: "+919080404532",,"2018/02/09,1

```

It is clear that, I am missing some character in serial monitor. If delay is reduced to 400 ms, the output is like below.

```
+CMT: "+919080404532",,"2018/02/09,19:30:51+06"
This is an incoI am working other job

```

I checked the following, but did not get any improvement.

1. `Serial.flush` and `mySerial.flush`
2. Increased both hardware, and software aerial buffer size
3. used `if (!mySerial.available()` before delay
4. Changed baud rate for both
5. Instead of of `Serial.readString()`, I used `Serial.read()` character by character inside function loop

Without use of the delay, it is working nice. I Think you guys are experienced, and can sort out the problem easily.

```
//while Introducing any delay in function loop, incoming message cant be read
//working with power failure but with serial monitor
#include <SoftwareSerial.h>
SoftwareSerial mySerial(9, 10);  // TX-Pin11, RX-Pin10
String str="";
void updateSerial()
{
  delay(2000);
  while (Serial.available()) {
    mySerial.write(Serial.read());//Forward what Serial received to Software Serial Port
  }
  while(mySerial.available()) {
    Serial.write(mySerial.read());//Forward what Software Serial received to Serial Port
  }

}

void setup()
{
  Serial.begin(9600);
  mySerial.begin(9600);
  modemsetup();
}

void loop()
{
 Serial.println("I am working other job");
 //delay(10000);            //If you give this delay, then incoming message cant be read
 smstask();
}

void smstask()
{
if(mySerial.available())
{
str=mySerial.readString();
Serial.println(str);
int bra = str.indexOf('@');
int ket = str.indexOf('#');
String str1=str.substring(bra+1,ket);

if(str1=="server")
{
Serial.println(str);
int i=random(1,500);
String str2=(String)i;
String str3="@deviceA#"+str2;
mySerial.println("AT+CMGF=1");    //Sets the GSM Module in Text Mode
updateSerial();
mySerial.println("AT+CMGS=\"+917602304567\"\r"); // Replace x with mobile number
updateSerial();
mySerial.println(str3);// The SMS text you want to send
updateSerial();
mySerial.println((char)26);// ASCII code of CTRL+Z
updateSerial();
mySerial.println("AT+CMGD=1,4"); // AT Command to receive a live SMS
updateSerial();
}
}

}

void modemsetup()
{
  for(int i=0;i<3;i++)
  {
  mySerial.println("AT");          //Once the handshake test is successful, it will back to OK
  updateSerial();

  mySerial.println("AT+CSQ");      //Signal quality test, value range is 0-31, 31 is the best
  updateSerial();

  mySerial.println("AT+CCID");    //Read SIM information to confirm whether the SIM is plugged
  updateSerial();

  mySerial.println("AT+CREG?");    //Check whether it has registered in the network
  updateSerial();

  mySerial.println("AT+SNFS=0");  //Adjust to earphone mode(AT+SNFS=1 is microphone mode)
  updateSerial();

  mySerial.println("AT+CRSL=2");  //Adjust volume, volume range is 0-15, maximum:15
  updateSerial();

  mySerial.println("AT+CMGF=1");
  updateSerial();

  mySerial.println("AT+CMGD=1,4");
  updateSerial();
  }

  mySerial.println("AT+CMGS=\"+917602304567\"\r");
  updateSerial();

  mySerial.println("I am SMS from GSM Module");
  updateSerial();

  mySerial.println((char)26);// ASCII code of CTRL+Z
  updateSerial();

}

```

# Answer
If serial data is coming in, and your code is doing a `delay`, the incoming data is stored in a buffer (of 64 bytes). But if you wait too long, the buffer will fill-up. Once it's full, any further incoming serial data isn't stored, and will be lost.

In your third output example, you get exactly 63 characters. Which is the maximum size a 64-byte cyclic buffer can store.
> 4 votes

---
Tags: arduino-uno, gsm, communication
---


# Question
Title: Ubuntu class string has no member remove
I am running some code that works fine on my windows system using the .remove method. On Ubuntu 16.04 I get the following errror:

```
error: ‘class String’ has no member named ‘remove’

```

To see if it was installation, I uninstalled arduino with

```
sudo apt-get purge arduino arduino-core

```

then

```
sudo apt-get update
sudo apt-get upgrade

sudo apt-get install arduino arduino-core

```

and the issue remains. I have seen some people say opening arduino through the terminal (from this), although that does not fix it.

Arduino version 2:1.0.5+dfsg2-4

Any help is appreciated.

# Answer
The `remove` method was added to the `String` class in 1.0.6.

Installing Arduino IDE from the Ubuntu repository gets you a really old package (1.0.5).

You should download and install the newest version from the official Arduino page.
> 5 votes

---
Tags: arduino-ide, library, string, compilation-errors
---


title: Arduino Leonardo RX TX mystery

text:
# Question
Title: Arduino Leonardo RX TX mystery
I'm at the tail end of a project using a Leonardo, a HC-06 bluetooth module and a few cell phone vibration motors. Everything is working fine except the serial communication between the Leonardo and the HC-06. I've done some tests to rule out common mistakes

1. TX is connected to RX, and vice versa.
2. Using a multimeter I checked for continuity with the RX TX, no problem there
3. I can upload the script
4. I uploaded the exact same script to an Uno, using the same HC-06. I was able to connect to the HC-06 with my phone and execute the script. So I know it's not the script and I know it's not the HC-06.
5. The Leonardo is working properly because I can upload the script and execute it using the Arduino Serial Monitor.

The only clue I have is that I can upload the script with the RX/TX connected and that's not supposed to work. However, I checked the connections and there is continuity. So I'm stumped. The only thing I can think of is that I damaged the RX/TX while I was soldering, but I'm hoping it's not that. Is there a way to test for that. Any suggestions?

```
/*
 * created by Rui Santos, http://randomnerdtutorials.com
 * Bluetooth App - Turn On and Off LED
*/

#include <SoftwareSerial.h>
SoftwareSerial mySerial(1, 0); // RX, TX

int led = 3;
int state;

void setup() {
  // initialize the digital pin as an output.
  pinMode(led, OUTPUT);
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
}

void loop() {
  if(Serial.available() > 0){
      state = Serial.read();}

  if (state == '1') {
      digitalWrite(led, HIGH);}   // turn the LED on (HIGH is the voltage level)

  else if (state == '2') {
      digitalWrite(led, LOW);}    // turn the LED off by making the voltage LOW

  delay(100);               // wait for 100ms

  //For debugging purpose
  //Serial.println(state);
}

```

# Answer
An Arduino Leonardo has native USB support. Which means that it has separate serial interfaces to the PC and to the hardware pins.

`Serial` is only used for the communication with the PC and is unrelated to the hardware serial pins 0 and 1. Those are exposed trough `Serial1`.

So, if you are using the exact same Uno sketch, that uses the hardware serial pins, it can't work on a Leonardo, because data is just sent-to/read-from the PC and not to the connected Bluetooth module connected on pins 0 an 1.
> 3 votes

---
Tags: arduino-leonardo, hc-06
---


# Question
Title: Why doesn't pin 3 blink? It blinks in another program
I used toneMelody example code (sketch sample 02.Digital-\>toneMelody) on an Arduino UNO. Then I wanted to blink an LED with the melody.

Here's the code:

```
#include "pitches.h"
#define BLUE 3 // pin 3 does not blink. but, pin 9 ok.
#define GREEN 5
#define RED 6

int melody[] = {
  NOTE_C4, NOTE_G3, NOTE_G3, NOTE_A3, NOTE_G3, 0, NOTE_B3, NOTE_C4
};
int noteDurations[] = {
  4, 8, 8, 4, 4, 4, 4, 4
};

void setup() {
  for (int thisNote = 0; thisNote < 8; thisNote++) {
    analogWrite(RED, 0);
    analogWrite(GREEN, 0);
    analogWrite(BLUE, 0);
    int noteDuration = 1000 / noteDurations[thisNote];
    tone(8, melody[thisNote], noteDuration);
    int pauseBetweenNotes = noteDuration * 1.30;
    int color = melody[thisNote] % 5;
    if(color == 0) {
      analogWrite(RED, 200);
    } else if(color == 1) {
      analogWrite(GREEN, 200);
    } else {
      analogWrite(BLUE, 200);
    }
    delay(pauseBetweenNotes);
    noTone(8);
  }
  analogWrite(RED, 0);
  analogWrite(GREEN, 0);
  analogWrite(BLUE, 0);
}

void loop() {
  // no need to repeat the melody.
}

```

Unfortunately, pin 3 did not blink. But it worked when I changed pin 3 to pin 9.

To check whether pin 3 or Blue LED is broken, I checked with the following code.

```
#define BLUE 3

void setup() {
  analogWrite(BLUE, 0);
}

void loop() {
  for(int i = 0 ; i < 255 ; i ++) {
    analogWrite(BLUE, i);
    delay(10);
  }
  analogWrite(BLUE, 0);
}

```

This code worked. Blue LED blinked. Why couldn't pin 3 blink with toneMelody?

Thanks.

# Answer
In the tone function reference you can read:

> Use of the tone() function will interfere with PWM output on pins 3 and 11 (on boards other than the Mega).

analogWrite() is PWM
> 5 votes

---
Tags: arduino-uno
---


# Question
Title: Sending Float values from Python to Arduino via serial communication
I want to Control the current flowing through a circuit using an Arduino. I have trained a PID controller for this purpose. I am using a current sensor to determine the error. It runs successful on my Arduino. In my next step I want build a system where I can send the Current setpoint (deter mined by my python code) value to the Arduino through serial communication. I am able to send integer values to Arduino. But I am unable to send and receive float values from Python to Arduino. I want to know the necessary code to be written in both sender and receiver. I tried of converting float to string and then send it to Arduino. But I failed. Please help.

Arduino Code(edit- Sorry previous code was an old file. Here is the correct one):

```
void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);
//pinMode(13,OUTPUT);
}
float f;

void loop() {
 if(Serial.available())
      {f=Serial.parseFloat();
        Serial.println(f);
      }
    delay(1000);
   }
//count=count+1;
      //delay(1);
//}

```

Python Code (edit- Sorry, the previous code was from an old file. Here is the correct one):

```
import serial
import time
import struct

ser = serial.Serial('/dev/ttyACM0', 9600, timeout = 1) # ttyACM1 for Arduino board
data=5.7

while True:
        ser.write(str(data))
        time.sleep(1)
        ser.flush()

```

When I run this code I get the following output on the Arduino Serial Monitor. As shown in the figure below.

Thank you.

# Answer
> 0 votes
It would seem you managed to solve your problem with `Serial.parseFloat()`. This is probably the easiest solution, but it has one serious drawback: it is a *blocking* function. Which means, during all the time needed by the serial port to transfer the number, your Arduino does nothing but wait for the incoming characters. This is an issue if your program has other task to do like, e.g., manage a PID regulation.

I suggest you consider reading the serial port in a *non blocking* fashion instead. This should make your PID happier, as it won't feel neglected while you read the incoming data. Look Alterno's answer is a good example of a non-blocking function that combines reading and parsing. However, I would like to point out that you do not need to implement your own number parser if you don't want to. A very common pattern is to instead store the incoming characters in a buffer and, when you see the character chosen as a terminator (e.g. ASCII LF), you parse the buffer at once using either `strtod()` or `atof()`. For example:

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

void loop() {
    static char buffer[32];
    static size_t pos;
    if (Serial.available()) {
        char c = Serial.read();
        if (c == '\n') {  // on end of line, parse the number
            buffer[pos] = '\0';
            float value = atof(buffer);
            Serial.print("received: ");
            Serial.println(value);
            pos = 0;
        } else if (pos < sizeof buffer - 1) {  // otherwise, buffer it
            buffer[pos++] = c;
        }
    }
}

```

# Answer
> 0 votes
Problem with Serial.parseFloat() is that it blocks until it read the value.

Try this code, which implement a minimal float parse routine (no error checking), and it's not blocking, so you can do other things while waiting for float to come

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

    while(!Serial);

    Serial.println("Start");
}

float result = 0;
bool dec = false;
int decDiv = 10;

void loop()
{
   // Float are positive, with format 999.99 (no sign, variable length integer/dec
   // We read only one char in each execution.

    if(Serial.available()) {
        // Read a single char from serial input.
        char c = Serial.read();

        if(isDigit(c)) {
            int val = (c - '0');  // Convert ASCII to binary.

            if(dec) {
                // We just read a decimal digit.
                result += (float) val / decDiv;
                decDiv *= 10;
            } else {
                // We just read a integer digit.
                result = result * 10 + val;
            }
        } else if(c == '.') {
            // Decimal part start now.
            dec = true;
        } else {
            // Any other thing is the end of the float value.
            Serial.println(result);
            // And reset everything for another float value.
            result = 0;
            dec = false;
            decDiv = 10;
        }
    }
}

```

---
Tags: arduino-uno, code-review, python, float
---


title: Combining Strings into a datestamp

text:
# Question
Title: Combining Strings into a datestamp
I'm creating a weather station / environmental datalogger and am saving my data to a SD card Breakout. The SD card works fine but I would like to name the files I am saving on it after the date when the readings were taken.I've tryed multiple things but I can't work out how to combine the date from my RTC and put them in a file name. I've tryed this:

```
dataFile = SD.open(String(now.day()) + "-" + String(now.month()) + "-" + String(now.year()) + ".csv",FILE_WRITE);

```

But this gives me an error -

```
char dateName[13] = {String(now.day()) + "-" + String(now.month()) + "-" + String(now.year()) + ".csv"};
dataFile = SD.open(dateName,FILE_WRITE);

```

But this gives me this error:

```
 cannot convert 'StringSumHelper' to 'char' in initialization

```

Help! How do I do this?

# Answer
> 5 votes
*EDIT: As noted by Klaus Warzecha, the SD library may only support 8.3 format filenames (i.e. 8 characters for the name, 3 characters for the extension). The solution may in fact be to ensure that the years is only 2 digits, resulting in names like: `20-12-14.csv`*

---

From what I can see in the SD library code, the `open()` method isn't designed to accept a `String` object as a parameter. It only wants a plain old C-style string (which means a `char` array). That explains why your first example doesn't work -- it's trying to pass a `String` object.

The second example unfortunately is invalid C++. You simply can't initialise an array like that. What you want to do instead is to build the `String` object, then extract the characters out using `String::toCharArray()`.

Something like this should work:

```
String filename = String(now.day()) + "-" + String(now.month()) + "-" + String(now.year()) + ".csv";
char str[16] = {0};
filename.toCharArray(str, 16);
dataFile = SD.open(str, FILE_WRITE);

```

I'm not sure what your `now.year()` returns; i.e. if that's a 2 digit or 4 digit year. I've assumed 4 digits, so I've made the `char` array big enough for 15 characters in total, plus an extra null terminator (which is essential for C-style strings).

# Answer
> 2 votes
Is this based on the SDFat library?

Then you have to live with short 8.3 filenames for the moment.

# Answer
> 1 votes
In your second case, you need to break the initialization into two lines and use toCharArray() as shown:

```
char dateName[13];
String(String(now.day()) + "-" + String(now.month()) + "-" + String(now.year()) + ".csv").toCharArray(dateName, 13);

```

Then, you can move ahead with opening the file.

The problem you are seeing is quite literally what the error message says. An initialization of a character array requires a character array. It cannot be initialised with a string object.

# Answer
> 1 votes
//////////////////////////////////////////////////////////////

```
String filename = String(now.month()) + "-" + String(now.year()) + ".csv";

char str[16] = {0};

filename.toCharArray(str, 16);

File dataFile = SD.open(str, FILE_WRITE);

```

//////////////////////////////////////////////////////////////

# Answer
> 0 votes
Well:

```
  char buffer[15];
  snprintf(buffer, sizeof(buffer), "%02d-%02d-%04d.csv", now.day(), now.month(), now.year());

```

After `snprintf` call, `buffer` contains the name of the file.

This solution use constant fixed space in RAM (just 15 bytes for buffer), while all others solutions demands tons of RAM for creating multiple String objects.

And it's faster, because it only do the format part, minus all creations, conversions, and deletion using String.

Finally, generated names are always the same length, from 1-1-2018 thru 31-12-2018.

Don't use String with Arduino.

---
Tags: sd-card
---


# Question
Title: How are Arduino's OSH if Atmel AVR is proprietary?
I keep reading how Arduinos are "open source", but my understanding of OSH is that all its components must be open source.

Arduino uses an Atmel AVR CPU - but Googling this shows the Atmel is proprietary!?

So I ask: **how can Arduino be truly OSH if it's chief component - its Atmel CPU - is proprietary?!?**

# Answer
> 5 votes
The components are necessarily going to be proprietary. There is no feasible way around this. If you wanted to design a new open source microcontroller from scratch with no proprietary components, it would set you back several billion dollars. The software used to design integrated circuits costs hundreds of thousands of dollars to license and represents billions of dollars of investment. Production of the chips themselves takes place in wafer fabs that cost billions of dollars to build, and represent billions of dollars of investment in process technology and semiconductor physics research. The equipment and process technologies are very closely held trade secrets. If you are OK with proprietary production, then you can submit GDSII design files (developed with your own open source IC design software) to fabs such as TSMC for production, but the line setup costs will run in the hundreds of thousands of dollars.

Bottom line: you have to draw the line somewhere as to what is acceptable to be 'open' and what is not. Open source hardware generally means the board-level design files and firmware sources are available, and generally nothing more.

Interestingly, there are many open source CPU designs available. Sun's OpenSPARC is an open design, you can download the RTL description of the CPU core and modify it. However, convering RTL to a chip requires IC design software or implementation on a proprietary FPGA with a proprietary development environment.

# Answer
> 3 votes
An 'Arduino' is open source in that you can see the schematics, go out and buy any required components (including the AVR), and change the design however you like.

The AVR is not part of what Arduino owns, it is a simply a component which they have built their design around. You could if you so choose replace that component with something else like a PIC for example, or any other programmable microcontroller for that matter. Granted if you made such a change you would also have to change the software, but then if you change the hardware even to another AVR you would have to change the software so in that sense it isn't really a limiting factor.

# Answer
> 1 votes
There is a good practical question and interesting issues raised here, but this part:

"my understanding of OSH is that all its components must be open source."

I would say your understanding is wrong, where did you get that from?

The design (i.e. how to arrange components) must be open source. Ideally the components would be Open Source too, but practicality dictates that components must be bought "off the shelf". IOW, overall the design should aim for "as Open Source as much as possible".

The thing about hardware is that to realize a design components must be bought, and those components often contain proprietary IP. Of course, the same problem applies to Open Source Software, to run it I need to buy a CPU from Intel, AMD, etc.

So while all open source designs must rely on some proprietary IP as a base platform, the practical question is how easily can the design be moved to another platform (portability), and how easily a component can be substituted (fungibility).

There is only one source of AVR chips and that is Atmel. Other components, like a 3.3V regulator can be easily substituted with other.

The Arduino core software does not rely solely on AVR architecture, in principle it is portable to any CPU platform, in practice any platform that is targeted by GCC. The fact that some Arduinos are not AVR e.g. Due, shows that.

# Answer
> 0 votes
Open-source hardware is fundamentally different from open-source software in that you cannot make a copy of OSH for free. If you want to build an Arduino, you will need all the components it's made of, and even the simplest components like diodes are proprietary, just like the AVR chip. Neither can be home-made and both are proprietary designs.

The important thing about OSH is not that it's made of free components, but the fact that **information about how it's made is freely available**. The abundance of Arduino shields and addons is not due to availability of free AVR cores, but to the fact that anyone has access to the information needed to make their board Arduino-compatible. BTW, that's how personal computers gained the dominant position on the market: IBM has published detailed specifications including schematics of their IBM PC (albeit not under a free license), enabling other companies to make compatible hardware, and later on, PC clones.

Last but not least, the open-source aspect of Arduino is by no means limited to the hardware. The core library was written in portable way, which made it possible to run it on a wide range of hardware cores. There are even FPGA boards featuring Arduino connectors (, , ), which can run Arduino software on soft-cores such as F32C or NIOS.

---
Tags: avr
---


title: 3.3V Conversion

text:
# Question
Title: 3.3V Conversion
I'm writing a SPI Master module for my FPGA and I would like test it with my Arduino Uno. What's the problem? My FPGA has 3.3V logic and Arduino has 5V TTL logic. So, what's the simplest solution to convert 5V TTL logic into 3.3V logic?

I know this topic has been already discussed in many sites but I can't find an unified answer.

Thanks in advance!

# Answer
> 1 votes
You can get 5, 4 channel bi-directional logic level converters for less than $1 USD Logic Level Module

Not only will they "translate" 3.3V to 5V and 5V to 3.3V, but they also work with higher voltages as well. For example, a vehicle with a 12V electrical system to 5V and vice versa works too.

---
Tags: voltage-level, convert
---


title: Burning sketch with I2C

text:
# Question
Title: Burning sketch with I2C
Not a pure Arduino question really. I'm actually using a standalone ATmega168. So far I've been using AVR-ISP programmer (working from AVR Studio) to program the chip. After everything is done, the chip will be covered and I will only have access to the I2C pins. The MISO,MOSI, etc pins will be unreachable.

I was just wondering if there was a way to use the I2C pins to update the program that is burned on the chip. I won't need to burn the bootloader again, but just to update the program if it needs to be.

# Answer
You need to write a I2C bootloader to the AVR. There seems to be a project that has already created such a bootloader.

Atmel has provided a TWI/I2C bootloader for their XMega processors (not the ATmega168).

Next problem is uploading the code via I2C. You'd need some hardware to convert USB to I2C. And some software to talk to this hardware. The last part is probably supported by AVR studio, as Atmel has provided an I2C bootloader. Though I'm not sure both of the above bootloaders are using a compatible protocol over the I2C.
> 3 votes

# Answer
Take a look at miniboot. I implemented it as a self-contained bootloader. Instructions about uploading from USB to I2C are also provided. Live long and prosper.
> 0 votes

---
Tags: arduino-uno, i2c, atmega328
---


# Question
Title: how to make this work auto on off led with fading
I'm working on a project with Arduino to make LED timer with fading feature. After doing some research finally I wrote some code but it's not working until now P.S i don't have any knowledge in coding at all T\_T

**Edit:** Adding more details about the issue; when trying to check upload this error is always shown.

```
Arduino: 1.8.5 (Windows 10), Board: "Arduino/Genuino Uno"

\SunRisetimer.ino: In function 'void loop()':

SunRisetimer:55: error: 'startOff' was not declared in this scope

     startOff();
\SunRisetimer.ino: In function 'void startOn()':

SunRisetimer:89: error: variable or field 'startOff' declared void

 void startOff

SunRisetimer:91: error: expected '}' before ';' token

analogWrite(uled, 1);

SunRisetimer:116: error: expected '}' at end of input

 }
exit status 1
'startOff' was not declared in this scope

```

**Code:**

```
#include <DS3231.h> //Include the clock library

// Changable Vars
int fadeTimeOn = 30; // How long the light will fade to max
int fadeTimeOff = 30; // How long the light will fade to min
int setHourOn = 9; // Set hours to wake (military time)
int setMinOn = 15; // Set minute to wake
int setHourOff = 9; //set off h
int setMinOff = 30; //
int uled = 9; // Set pinout with with PWM

// Set up Vars
DS3231  rtc(SDA, SCL);
Time t;
void start();

void setup()
{
  pinMode(uled, OUTPUT);
  Serial.begin(9600); // Match to serial monitor
  rtc.begin();
}

void loop()
{
  t = rtc.getTime(); // Make a time class called 't'

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

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

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

  if (t.hour == setHourOn && t.min == setMinOn) // Check if it's time to wake up!
  {
    startOn();
  }

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

 if (t.hour == setHourOff && t.min == setMinOff) // Check if it's time to off!
  {
    startOff();
  }

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

void startOn()
{
  // Fix for SB LED
  analogWrite(uled, 1);
  delay((fadeTimeOn * 60000)/50);
  analogWrite(uled, 2);
  delay((fadeTimeOn * 60000)/50);
  analogWrite(uled, 3);
  delay((fadeTimeOn * 60000)/50);
  analogWrite(uled, 4);
  delay((fadeTimeOn * 60000)/50);
  analogWrite(uled, 4);
  delay((fadeTimeOn * 60000)/50);
  analogWrite(uled, 5);
  delay((fadeTimeOn * 60000)/50);

for (int i = 6 ; i <= 255; i++)
    {
    analogWrite(uled, i);
    delay(((fadeTimeOn * 60000)/306));
    Serial.print(" mil sec ");
    Serial.print(((fadeTimeOn * 60000)/306));
    Serial.print(" PWM " );
    Serial.print(i);
    {
}

void startOff
{
  analogWrite(uled, 1);
  delay((fadeTimeOff * 60000)/50);
  analogWrite(uled, 5);
  delay((fadeTimeOff * 60000)/50);
  analogWrite(uled, 4);
  delay((fadeTimeOff * 60000)/50);
  analogWrite(uled, 3);
  delay((fadeTimeOff * 60000)/50);
  analogWrite(uled, 2);
  delay((fadeTimeOff * 60000)/50);
  analogWrite(uled, 1);
  delay((fadeTimeOff * 60000)/50);

  // Fade script
  for (int i = 6 ; i <= 255; i++)
  {
    analogWrite(uled, i);
    delay(((fadeTimeOff * 60000)/306));
    Serial.print(" mil sec ");
    Serial.print(((fadeTimeOff * 60000)/306));
    Serial.print(" PWM " );
    Serial.print(i);

  }

}

```

# Answer
> 1 votes
Look at your function definitions:

```
void startOn() // works
void startOff    // doesn't work

```

You are missing the `()` after `startOff`.

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


# Question
Title: Problem to display Ntp time on an oled using U8G2 lib
So I have this code to get ntp time and display it on serial port. But I want to display it on a 1.30 inch I2C oled with a SH1106 controller using the U8G2 library. The only problem is I don't know the correct syntax. I have tried

```
Serial.print((epoch  % 86400L) / 3600); // print the hour (86400 equals secs
per day)
int ho = ((epoch  % 86400L) / 3600+9);
itoa(ho,hours,10);
u8g2.clearBuffer();         // clear the internal memory
u8g2.setFont(u8g2_font_ncenB14_tr); // choose a suitable font
u8g2.drawStr(0,20,hours);

```

and also

```
{
u8g2.setFont(u8g2_font_ncenB14_tr);
u8g2.firstPage();
do {
u8g2.setCursor(0, 20);
u8g2.print(hours,DEC);
u8g2.setCursor(33, 20);
u8g2.print(minutes,DEC);
}
while ( u8g2.nextPage() );
}

```

This is my code

```
//This is a code to display ntp time using Nodemcu

#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <Arduino.h>
#include <U8g2lib.h>

#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif

U8G2_SH1106_128X64_NONAME_1_HW_I2C u8g2(U8G2_R0, /* reset=*/U8X8_PIN_NONE);

char ssid[] = "123456";     //  your network SSID (name)
char pass[] = "123456";     // your network password

//Your UTC Time Zone Differance  India +5:30
char HH = 5;
char MM = 30;

unsigned int localPort = 2390;      // local port to listen for UDP packets

//* Don't hardwire the IP address or we won't get the benefits of the pool.
//* Lookup the IP address for the host name instead */

//IPAddress timeServer(129, 6, 15, 28); // time.nist.gov NTP server

IPAddress timeServerIP; // time.nist.gov NTP server address

const char* ntpServerName = "time.nist.gov";

const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes
// of the message

byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing
//packets

// A UDP instance to let us send and receive packets over UDP
WiFiUDP udp;

                              //SETUP

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

// We start by connecting to a WiFi network
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, pass);

while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");

Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());

Serial.println("Starting UDP");
udp.begin(localPort);
Serial.print("Local port: ");
Serial.println(udp.localPort());
}

//  Send an NTP request to the time server at the given address

unsigned long sendNTPpacket(IPAddress& address)
{
Serial.println("sending NTP packet...");
// set all bytes in the buffer to 0
memset(packetBuffer, 0, NTP_PACKET_SIZE);

// Initialize values needed to form NTP request
// (see URL above for details on the packets)
packetBuffer[0] = 0b11100011;   // LI, Version, Mode
packetBuffer[1] = 0;     // Stratum, or type of clock
packetBuffer[2] = 6;     // Polling Interval
packetBuffer[3] = 0xEC;  // Peer Clock Precision
// 8 bytes of zero for Root Delay & Root Dispersion
packetBuffer[12]  = 49;
packetBuffer[13]  = 0x4E;
packetBuffer[14]  = 49;
packetBuffer[15]  = 52;

// all NTP fields have been given values, now
// you can send a packet requesting a timestamp:

udp.beginPacket(address, 123); //NTP requests are to port 123
udp.write(packetBuffer, NTP_PACKET_SIZE);
udp.endPacket();

u8g2.begin();
}
                              //LOOP

void loop()
{
char hours;
char minutes;
char seconds;

// get a random server from the pool
WiFi.hostByName(ntpServerName, timeServerIP);

sendNTPpacket(timeServerIP);

// send an NTP packet to a time server
// wait to see if a reply is available
delay(1000);

int cb = udp.parsePacket();
if (!cb) {
Serial.println("no packet yet");
}
else {
Serial.print("packet received, length=");
Serial.println(cb);

// We've received a packet, read the data from it
udp.read(packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer
//the timestamp starts at byte 40 of the received packet and is four bytes,
// or two words, long. First, esxtract the two words:
unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);

// combine the four bytes (two words) into a long integer
// this is NTP time (seconds since Jan 1 1900):
unsigned long secsSince1900 = highWord << 16 | lowWord;
Serial.print("Seconds since Jan 1 1900 = " );
Serial.println(secsSince1900);

// now convert NTP time into everyday time:
Serial.print("Unix time = ");
// Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
const unsigned long seventyYears = 2208988800UL;
// subtract seventy years:
unsigned long epoch = secsSince1900 - seventyYears;
// print Unix time:
Serial.println(epoch);

// print the hour, minute and second:
minutes = ((epoch % 3600) / 60);
minutes = minutes + MM; //Add UTC Time Zone

hours = (epoch  % 86400L) / 3600;
if(minutes > 59)
{
hours = hours + HH + 1; //Add UTC Time Zone
minutes = minutes - 60;
}
else
{
hours = hours + HH;
}

Serial.print("The UTC time is ");       // UTC is the time at Greenwich //Meridian (GMT)

Serial.print(hours,DEC); // print the hour (86400 equals secs per day)
Serial.print(':');

if ( minutes < 10 ) {
// In the first 10 minutes of each hour, we'll want a leading '0'
Serial.print('0');
}
Serial.print(minutes,DEC); // print the minute (3600 equals secs per minute)
Serial.print(':');

seconds = (epoch % 60);
if ( seconds < 10 ) {
// In the first 10 seconds of each minute, we'll want a leading '0'
Serial.print('0');
}
Serial.println(seconds,DEC); // print the second
}
// wait ten seconds before asking for the time again
delay(10000);
}

```

Adding the second block of code (print one) to the main code gives me correct time on the oled screen but only when the ntp receives a packet. Otherwise its some 10 digit number. How do I get rid of the number and keep displaying the time till it is update with a valid newer value. I have attached images of display.

# Answer
> 1 votes
EDIT: I checkout Internet access is working OK. Problem is the server.

Your sketch works well (after some refactoring) against my local LAN NTP server and ntp.shoa.cl, but not against time.nist.gov, the one in your sketch.

It looks like the NTP server time.nist.gov itself is having problems. `ntpdate` reports:

```
> look@gear ~/Downloads/mover $ ntpdate -q time.nist.gov server
> 129.6.15.28, stratum 0, offset 0.000000, delay 0.00000 11 Feb 13:11:05 ntpdate[5855]: no server suitable for synchronization found

```

so that may explain that your code fails.

Anyway, I refactored your code before testing before `delays` are source of all kind of problems. I run OK at the first test.

I only modify `loop`; everything else is the same. I made it a state machine with three states: `idle`, your are reading to send an UDP packet; `reading`, you are trying to read the answer; and `waiting`, where you spend 10 seconds doing nothing.

I also move all printing to a new `processPacket` function, to keep `loop` short and easy to read.

Never use delay(). Use the scheme provide here to wait using millis().

```
void loop() {
    enum st {idle, reading, waiting};
    static st status;
    static unsigned long prev = 0;
    unsigned long now = millis();

    switch(status) {
    case idle:
        // get a random server from the pool
        WiFi.hostByName(ntpServerName, timeServerIP);

        sendNTPpacket(timeServerIP);
        status = reading;
        prev = now;
        break;

    case reading:
        if(now - prev > 1000L) {
            int cb = udp.parsePacket();

            if(cb) {
                status = idle;
                Serial.print("packet received, length=");
                Serial.println(cb);
                processPacket();
            } else {
                Serial.println("no packet yet");
            }

            prev = now;
        }

        break;

    case waiting:
        if(now - prev > 10000L) {
            status = idle;
            prev = now;
        }
    }
}

void processPacket()
{
    char hours;
    char minutes;
    char seconds;

    // We've received a packet, read the data from it
    udp.read(packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer
    //the timestamp starts at byte 40 of the received packet and is four bytes,
    // or two words, long. First, esxtract the two words:
    unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
    unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);

    // combine the four bytes (two words) into a long integer
    // this is NTP time (seconds since Jan 1 1900):
    unsigned long secsSince1900 = highWord << 16 | lowWord;
    Serial.print("Seconds since Jan 1 1900 = ");
    Serial.println(secsSince1900);

    // now convert NTP time into everyday time:
    Serial.print("Unix time = ");
    // Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
    const unsigned long seventyYears = 2208988800UL;
    // subtract seventy years:
    unsigned long epoch = secsSince1900 - seventyYears;
    // print Unix time:
    Serial.println(epoch);
    // print the hour, minute and second:
    minutes = ((epoch % 3600) / 60);
    minutes = minutes + MM; //Add UTC Time Zone
    hours = (epoch  % 86400L) / 3600;
    if(minutes > 59) {
        hours = hours + HH + 1; //Add UTC Time Zone
        minutes = minutes - 60;
    } else {
        hours = hours + HH;
    }
    Serial.print("The UTC time is ");       // UTC is the time at Greenwich //Meridian (GMT)
    Serial.print(hours,DEC); // print the hour (86400 equals secs per day)
    Serial.print(':');
    if(minutes < 10) {
    // In the first 10 minutes of each hour, we'll want a leading '0'
        Serial.print('0');
    }
    Serial.print(minutes,DEC); // print the minute (3600 equals secs per minute)
    Serial.print(':');
    seconds = (epoch % 60);
    if(seconds < 10) {
        // In the first 10 seconds of each minute, we'll want a leading '0'
        Serial.print('0');
    }
    Serial.println(seconds,DEC); // print the second
    u8g2.setFont(u8g2_font_ncenB14_tr);
    u8g2.firstPage();
    do {
       u8g2.setCursor(0, 20);
       u8g2.print(hours,DEC);
       u8g2.drawStr(25, 17,":");
       u8g2.setCursor(33, 20);
       u8g2.print(minutes,DEC);
       }
    while(u8g2.nextPage());
  }

```

And this is the output:

---
Tags: i2c, nodemcu, code-review, display, u8glib
---


# Question
Title: How do I get multiple readings(binary) based on my arduino output?
I am new to arduino and therefore not much experience in handling codes, please be forgiving and help me!

For my school project, make use of arduino to make 4 capacitive sensors (which has already been successful). Now I am trying to make use of the 4 sensors to be shown in a table format(one for each output) so that I can use that data to be plotted into either Excel or Matlab. Hence I would like to ask how do I group up my data into different columns? Also is it possible to get convert my results into binary format so that it would be easier when trying to plot the data?

My arduino code is here:

```
#include <CapacitiveSensor.h>

CapacitiveSensor   cs_2_4 = CapacitiveSensor(2,4); // 1M resistor between pins 4 & 8, pin 8 is sensor pin, add a wire and or foil
CapacitiveSensor   cs_5_7 = CapacitiveSensor(5,7);
CapacitiveSensor   cs_8_10 = CapacitiveSensor(8,10);
CapacitiveSensor   cs_11_13 = CapacitiveSensor(11,13);
void setup()
{
   cs_2_4.set_CS_AutocaL_Millis(0xFFFFFFFF);// turn off autocalibrate on channel 1 - just as an example
   cs_5_7.set_CS_AutocaL_Millis(0xFFFFFFFF);
   cs_8_10.set_CS_AutocaL_Millis(0xFFFFFFFF);
   cs_11_13.set_CS_AutocaL_Millis(0xFFFFFFFF);
 Serial.begin(9600);
   pinMode(3,OUTPUT);
   pinMode(6,OUTPUT);
   pinMode(9,OUTPUT);
   pinMode(12,OUTPUT);
}

void loop()
{
 long sensor1 =  cs_2_4.capacitiveSensor(50);
 long sensor2 =  cs_5_7.capacitiveSensor(50);
 long sensor3 =  cs_8_10.capacitiveSensor(50);
 long sensor4 =  cs_11_13.capacitiveSensor(50);

Serial.println(sensor1);  // print sensor output
    Serial.print("\t");
    Serial.println(sensor2);
    Serial.print("\t");
    Serial.println(sensor3);
    Serial.print("\t");
    Serial.println(sensor4);
 if(sensor1 >= 1000)
   {
    digitalWrite(3,HIGH);
   }
  else{
    digitalWrite(3,LOW);
   }
     if(sensor2 >= 1000)
   {
    digitalWrite(6,HIGH);
   }
   else{
    digitalWrite(6,LOW);
   }
    if(sensor3 >= 1000)
   {
    digitalWrite(9,HIGH);
   }
   else{
    digitalWrite(9,LOW);
   }
    if(sensor4 >= 1000)
   {
    digitalWrite(12,HIGH);
   }
   else{
    digitalWrite(12,LOW);
   }

   }

```

And with that code above the output I receive when I use the serial monitor is:

# Answer
> 0 votes
> ```
> Serial.println(sensor1);  // print sensor output
> Serial.print("\t");
> Serial.println(sensor2);
> Serial.print("\t");
> Serial.println(sensor3);
> Serial.print("\t");
> Serial.println(sensor4);
>
> ```

If you want 4 columns don't use `println` for each number, as that starts a new line.

---

> Also is it possible to get convert my results into binary format so that it would be easier when trying to plot the data?

Yes it's possible however I don't see how that makes anything easier.

---
Tags: arduino-mega, serial-data
---


# Question
Title: High pass filtering accelerometer data on Arduino
I'm trying to use an accelerometer for user input to a device. The idea is that the user input will be tied to "taps" on the accelerometer, one tap means something, two taps something else, etc.

I'm using an Adafruit Feather M0 as my microcontroller, controlling an accelerometer that feeds me x,y,z-data at a sampling rate of 100 Hz. I now then want to high pass filter the data with a cutoff frequency of 10 Hz, since taps on the accelerometer give rise to much higher frequencies than other "noise", such as movement.

The accelerometer uses a FIFO buffer to output the data, so I collect 20 samples at a time, and I want to filter those 20 samples with a high pass filter to see if there is a tap within that sampling window. I am currently using the filter function on Arduino playground, https://playground.arduino.cc/Code/Filters.

However, and here is my problem; When I implement this in my code, the filtering "restarts" each window, so that my filtered data looks like this:

```
[X], [Y], [Z]
0.00,0.00,0.00
-39.67,94.13,-85.18
-29.89,71.66,-64.18
-24.02,53.99,-49.08
-17.39,40.78,-37.09
-13.00,30.51,-27.74
-9.80,22.99,-20.91
-7.58,17.00,-16.17
-7.01,13.88,-14.01
-4.86,12.04,-10.53
-4.02,9.96,-8.71
-2.44,8.05,-7.04
-1.99,6.57,-5.74
-1.60,5.26,-3.80
-2.76,3.27,-4.45
-1.43,2.67,-3.63
-1.16,2.16,-2.13
-0.94,2.55,-1.72
-0.76,1.26,-0.58
-0.62,0.21,-1.29

0.00,0.00,0.00
-40.26,94.51,-84.88
-30.38,70.55,-64.78
-22.13,53.89,-48.04
-17.42,40.60,-37.69
-13.91,29.87,-27.68
-10.99,23.61,-22.67
-10.05,19.04,-16.00
-5.78,14.79,-13.94
-4.69,12.82,-11.31
-3.84,9.69,-9.27
-3.14,7.91,-7.56
-2.52,6.35,-6.08
-2.07,5.22,-4.18
-0.88,4.29,-3.43
-2.35,4.32,-3.62
-0.29,3.54,-2.97
-1.07,2.94,-3.29
-1.63,0.74,-1.02
-0.50,1.38,-1.60

0.00,0.00,0.00
-40.51,95.10,-85.37
-30.32,70.41,-65.39
-22.86,53.10,-49.31
-17.26,40.83,-35.71
-13.45,31.81,-27.81
-9.37,22.43,-20.92
-7.80,17.62,-15.74
-6.50,13.01,-13.10
-4.04,9.56,-8.16
-3.02,7.15,-6.85
-2.29,5.42,-4.43
-2.70,3.63,-4.46
-1.38,4.56,-3.61
-1.14,2.95,-2.16
-1.73,2.38,-1.75
-1.32,2.59,-2.10
-1.05,0.47,-1.67
-0.04,1.12,-1.28
-0.03,0.90,-1.03

```

I don't understand why this happens, and why the data in the subsequent windows aren't suppressed from the start. I have implemented a very similar solution in Python which works very well with the filtering. Have I misunderstood how Arduinos filtering functions work?

Here is my code:

```
// Include SPI library
#include <SPI.h>
#include <Filters.h>

// List of addresses: 7-bit adresses, 8th bit is R/W bit, and is set in the functions readRegister and writeRegister.
char X_data_low = 0x28;
char X_data_high = 0x29;
char Y_data_low = 0x2A;
char Y_data_high = 0x2B;
char Z_data_low = 0x2C;
char Z_data_high = 0x2D;

char CTRL_REG1 = 0x20; // Controls data rate selection, low power mode, and X-, Y- and Z-axis enable
char CTRL_REG1_value = 0b00101111; // 0001 1111 = 1 Hz, LP mode, XYZ enable.

char CTRL_REG5 = 0x24; // Enables FIFO mode, among others.
char CTRL_REG5_value = 0b01000000; // 0100 0000, FIFO enabled, all else is zero.

char STATUS_REG = 0x27; // Flags for new XYZ values.

char FIFO_CTRL_REG = 0x2E; // Controls FIFO mode (Bypass, FIFO, Stream, Stream-To-FIFO)
char FIFO_CTRL_REG_value = 0b01000000; // Selects FIFO mode

char FIFO_SRC_REG = 0x2F; // Watermark level, FIFO Overrun, FIFO empty, FSS. Can read FSS to know how many unread samples FIFO buffer contains currently.

//int smpls = 20; // Number of samples

char values[240]; // buffer for storing read values.

int x_val[40]; // Arrays for storing values before filtering
int y_val[40];
int z_val[40];

float filtered_x_val[40]; // Arrays for storing values after filtering
float filtered_y_val[40];
float filtered_z_val[40];

int CS = 5; // Chip select pin

int concat_val = 0b00011111; // For concatenation with values[0] to find number of samples in FIFO buffer
int number_of_FIFO_values; // Number of FIFO samples

// Testing Arduinos own filtering

// filters out changes slower that 10 Hz.
float filterFrequency = 10.0;

// create a one pole (RC) lowpass filter
FilterOnePole highpassFilter_x( HIGHPASS, filterFrequency );
FilterOnePole highpassFilter_y( HIGHPASS, filterFrequency );
FilterOnePole highpassFilter_z( HIGHPASS, filterFrequency );

void setup() {
  // put your setup code here, to run once:
  // Opening pins
  pinMode(22, INPUT_PULLUP); // MISO
  pinMode(24, OUTPUT); // SCK
  pinMode(23, OUTPUT); // MOSI
  pinMode(CS, OUTPUT);  // CS
  pinMode(14, OUTPUT);  // VDD_IO, for use when no breadboard is available to connect both VDD and VDD_IO to 3.3V output
  digitalWrite(CS, HIGH);
  digitalWrite(14, HIGH);
  delay(50);

  // Communication with computer
  Serial.begin(9600);

  // SPI
  SPI.begin();
  SPI.beginTransaction(SPISettings(10000000, MSBFIRST, SPI_MODE0));
  // Loading settings
  delay(10);
  writeRegister(CTRL_REG1,CTRL_REG1_value);
  delay(10);
  writeRegister(CTRL_REG5,CTRL_REG5_value);
  delay(10);
  writeRegister(FIFO_CTRL_REG,FIFO_CTRL_REG_value);
  delay(10);

}

void loop() {
  readRegister(0x2F,1,values);
  number_of_FIFO_values = values[0] & concat_val;

  if (number_of_FIFO_values >= 20){ // It is enough to read high values since LP mode is only 8 bits
    readRegister(0x28,120,values);
    int x_count = 0; // Counters to keep track of which value in x_val, y_val, z_val to be assigned
    int y_count = 0;
    int z_count = 0;
    for(int i=0; i<120; i++){
      if (i % 6 == 1) {
        x_val[x_count] = int(values[i]);
        if(x_val[x_count] > 127)
          x_val[x_count] -= 256;
        x_count += 1;
        }
      if (i % 6 == 3) {
        y_val[y_count] = int(values[i]);
        if(y_val[y_count] > 127)
          y_val[y_count] -= 256;
        y_count += 1;
        }
      if (i % 6 == 5) {
        z_val[z_count] = int(values[i]);
        if(z_val[z_count] > 127)
          z_val[z_count] -= 256;
        z_count += 1;
        }
      }
    Serial.print('\n');
    filtering(x_val,y_val,z_val);
    writeRegister(FIFO_CTRL_REG,0b00000000);
    delay(10);
    writeRegister(FIFO_CTRL_REG,FIFO_CTRL_REG_value);
    delay(10);
  }
}

void filtering(int x_arr[], int y_arr[], int z_arr[]){
    for(int i=0; i<20; i++) {
      highpassFilter_x.input(x_arr[i]);
      highpassFilter_y.input(y_arr[i]);
      highpassFilter_z.input(z_arr[i]);
      filtered_x_val[i] = highpassFilter_x.output();
      filtered_y_val[i] = highpassFilter_y.output();
      filtered_z_val[i] = highpassFilter_z.output();
      Serial.print(filtered_x_val[i]);
      Serial.print(",");
      Serial.print(filtered_y_val[i]);
      Serial.print(",");
      Serial.print(filtered_z_val[i]);
      Serial.print('\n');
    }
  }

//This function will write a value to a register on the sensor.
// Parameters:
//  char registerAddress - The register to write a value to
//  char value - The value to be written to the specified register.
// The bits to specify write or read operation on slave device, and single
// or multiple register reading in reading operation, are included in the
// registeraddress.
// As defined by protocol, the MSB of the address indicates write/read, and the following bit indicate single/multiple reading. Cause ADXL345 support Byte operation,
// The MSB is the 8th bit, the following bit is the 7th bit. (note: if indicating multiple bits reading, ADXL345 will increasing the register address automatically to the
// next successive register like a pointer.
void writeRegister(char registerAddress, char value){
  //Set Chip Select pin low to signal the beginning of an SPI packet.
  digitalWrite(CS, LOW);
  //Transfer the register address over SPI.
  // All ADXL345 register address are smaller than 0100 0000, all are like 00** ****, so that any register address of ADXL345 can be used directly for register write operation
  // without any change on the MSB and its following bit, but the case for reading operation is the opposite.
  // Might need a delay here between CS going low and data transfer.
  SPI.transfer(registerAddress);
  //Transfer the desired register value over SPI.
  // ignored the reture of SPI.transfer in writer operation
  SPI.transfer(value);
  //Set the Chip Select pin high to signal the end of an SPI packet.
  digitalWrite(CS, HIGH);
}

//This function will read a certain number of registers starting from a specified address and store their values in a buffer.
//Parameters:
//  char registerAddress - The register addresse to start the read sequence from.
//  int numBytes - The number of registers that should be read.
//  char * values - A pointer to a buffer where the results of the operation should be stored.
void readRegister(char registerAddress, int numBytes, char * values){
  //Since we're performing a read operation, the most significant bit (bit 7(counting starts from bit 0)) of the register address should be set high.
  char address = 0x80 | registerAddress;
  //If we're doing a multi-byte read, bit 6 (counting starts from bit 0)needs to be set high as well.
  if(numBytes > 1)address = address | 0x40;

  //Set the Chip select pin low to start an SPI packet.
  digitalWrite(CS, LOW);
  //Transfer the starting register address that needs to be read.
  SPI.transfer(address);
  //Continue to read registers until we've read the number specified, storing the results to the input buffer.
  //SPI is full duplex transsmission. Every signle time SPI.transfer can and can only transmit 8 bits. the input parameter will be delived to slave, and it's return will be
  // the data that master device and get from the slave device. The data returned during master device's write operation makes no sense, hence always been ignored by not
  // doing any assignment operation.
  for(int i=0; i<numBytes; i++){
    values[i] = SPI.transfer(0x00);
  }
  //Set the Chips Select pin high to end the SPI packet.
  digitalWrite(CS, HIGH);
}

```

# Answer
This filter library is sensitive to the timing of you calling `FilterOnePole::input()`. It assumes that the delays between consecutive calls are the same as the delays between the samples being measured. C.f. the first statement in the method, which is a call to `micros()`. The pauses between your 20-sample buffers are then interpreted like long times during which the input only changed very little.

If you are sampling at a constant data rate, I recommend you reimplement the filter yourself: it is simple enough and it will be way more efficient than the one you found on Playground.

---

**Edit**: Here is a simple implementation of a first-order high-pass filter like the one in the library, but using a constant sampling rate:

```
class HigPassFilter
{
public:
    HigPassFilter(float reduced_frequency)
    : alpha(1-exp(-2*M_PI*reduced_frequency)), y(0) {}
    float operator()(float x) {
        y += alpha*(x-y);
        return x-y;
    }
private:
    float alpha, y;
};

```

You would use it like this:

```
// Create the filters.
HigPassFilter highpassFilter_x(cutoffFrequency/samplingFerquency);
HigPassFilter highpassFilter_y(cutoffFrequency/samplingFerquency);
HigPassFilter highpassFilter_z(cutoffFrequency/samplingFerquency);

// Apply them.
filtered_x_val[i] = highpassFilter_x(x_arr[i]);
filtered_y_val[i] = highpassFilter_y(y_arr[i]);
filtered_z_val[i] = highpassFilter_z(z_arr[i]);

```
> 3 votes

---
Tags: c++, accelerometer, signal-processing
---