# Question
Title: Transfer a struct's data to an external struct via serial?
Using two boards of similar architecture I would like to send the contents of a struct from the sending board to the receiving board. I am using UART to transfer.

My plan was to populate an array with the starting structs data. Transfer that, than un-package the array onto the receiving boards struct.

I'm not sure this is a possible option. Unpacking the array seems sort of rigid, as I would be assigning each struct variable to the array index. It might work but I'm not really convinced I should do it this way.

Here's what my sending sketch looks like.

Send:

```
typedef struct NWK_DataReq_t
{
 uint8_t      state;
 uint8_t      options;
} NWK_DataReq_t;

//Instance struct
NWK_DataReq_t dataRequest;

void setup()
{
  //Give it some values
  dataRequest.state = 2;
  dataRequest.options = 4;

  Serial.begin(9600);
}

void loop()
{
  //set variable array to struct length
  uint8_t payload[sizeof(dataRequest)];

  //copy struct to variable array
  memcpy(payload,&dataRequest,sizeof(dataRequest));

  //send each item of struct, now contained in payload array
  for(int i=0;i < sizeof(payload);i++)
  {
    //Serial.print(i);
    //Serial.print(":");
    Serial.println(payload[i]);
  }

  Serial.println("");
  delay(1000);
}

```

Receive:

```
typedef struct NWK_DataReq_t
{
 uint8_t      state;
 uint8_t      options;
} NWK_DataReq_t;

//Instance struct
NWK_DataReq_t dataRequest;
uint8_t incomingPayload[sizeof(dataRequest)];

void setup()
{
  Serial.begin(9600);
  Serial.print("Recieve started");
}

void loop()
{

  if (Serial.available())
  {
    //add incoming data to array
    for(int i=0;i<sizeof(dataRequest);i++)
    {
      uint8_t incomingByte = Serial.read();
      incomingPayload[i] = incomingByte;
    }
  }

  //set array values to structs
  for (int i= 0;i < sizeof(dataRequest);i++)
  {
    structIndexPosition = incomingPayload[i];
  }
}

```

structIndexPosition is not attached as I wasn't sure how I might index the struct, or if this is an okay approach.

# Answer
I think you are over-complicating it to send two bytes. Just send them as straight ASCII with a newline after, and decode it on the receiving end.

eg.

```
42,87

```

However if the question was just an example of something much more complex, then you may need to do more work. You need to have the receiving end know when a packet of data starts, and ends, and preferably have some validation that it wasn't corrupted. If you want to pursue that idea, see my thread about sending data via RS485 which has a library that does that sort of thing.
> 1 votes

# Answer
The simplest possible way of sending the struct's data is:

```
Serial.write((const uint8_t *)&myData, sizeof(myData));

```

Get the address of myData, cast it to an unsigned int pointer, and starting at that address write the number of bytes specified by `sizeof(myData)`. That will transfer the raw data of the struct through the serial with no messing with copying of data into other arrays, assigning pointers, etc.

However: it won't work.

Sending raw binary data over serial like that, where serial has no concept of anything other than bytes, it is just not possible to know where in the stream of data you are. Which of the myriad of bytes coming in is which within a struct? Who can tell?

So you need to write a protocol. A method whereby one end tells the other end "This is the start of the data. This is the data. This is the end of the data." But also you need to be able to say "This bit, that looks the same as the 'start of the data' message is actually a bit of the data, not the start of the data". You see, it's quite an involved task really.
> 1 votes

# Answer
If you couldn't run this code like me then all you have to do is cut the:" struct package { }; typedef struct package Package; Package data; " And paste it into the "void loop" and it should work fine. P/s: Thank you very much for this helpful video, but hope you will update this in the future ( i guess the update had changed something in the Arduino codes)
> 1 votes

# Answer
*Why go over the bridge for water?*

It is possible to access the data in the struct as a character pointer. No need to transfer to a buffer etc.

```
void loop()
{
  ...
  ...
  const char* dp = (const char*) &dataRequest;
  for (int i = 0; i < sizeof(dataRequest); i++) Serial.print(*dp++);
  Serial.println();
  delay(1000);
  ...
  ...
 }

```

It might be hard to extrapolate how to receive this?

```
void loop()
{
  if (Serial.available() > sizeof(dataRequest)) {
     char* dp = (char*) &dataRequest;
     for (int i = 0; i < sizeof(dataRequest); i++) *dp++ = Serial.read();
     Serial.read();
     ...
     ...
  }
}

```

The Serial.println() and extra Serial.read() could be replaced by a "frame marker" and/or a check-sum.

Cheers!
> 0 votes

---
Tags: c++, uart, struct
---


title: File created, but not logging data

text:
# Question
Title: File created, but not logging data
I am starting using Arduino and have very little to none experience coding. However, I have managed to code and understand how it works.

The problem that I have is that I am unable to log (record) data from the three sensors attached (Adafruit Anemometers). All of them work properly; the data file is created. However, there is no data (or time reference) being written on the file. When I verify the code, it's approved...Therefore, it should work, right?.=/ Then, I uploaded code.

I am using an Arduino uno with an SD Logger shield (Data Logging Shield v1.0, from Deek-Robot(TM)), which uses a DS1307 RTC.

All comments are more than welcome!

Thanks in Advance

```
#include "SD.h"
#include <Wire.h>
#include "RTClib.h"

// A simple data logger for the Arduino analog pins
#define LOG_INTERVAL  60000 // mills between entries
#define ECHO_TO_SERIAL   0 // echo data to serial port
#define WAIT_TO_START    0 // Wait for serial input in setup()

// the digital pins that connect to the LEDs
#define redLEDpin 3
#define greenLEDpin 4

// The analog pins that connect to the sensors
#define Anemometer0           // analog 0
#define Anemometer1           // analog 1
#define Anemometer2           // analog 2

RTC_DS1307 RTC; // define the Real Time Clock object

//Setup Variables of Anemometers

//Anemometer0
const int sensorPin0 = A0; //Defines the pin that the anemometer output is connected to
int sensorValue0 = 0; //Variable stores the value direct from the analog pin
float sensorVoltage0 = 0; //Variable that stores the voltage (in Volts) from the anemometer being sent to the analog pin
float windSpeed0 = 0; // Wind speed in meters per second (m/s)

//Anemometer1
const int sensorPin1 = A1; //Defines the pin that the anemometer output is connected to
int sensorValue1 = 0; //Variable stores the value direct from the analog pin
float sensorVoltage1 = 0; //Variable that stores the voltage (in Volts) from the anemometer being sent to the analog pin
float windSpeed1 = 0; // Wind speed in meters per second (m/s)

//Anemometer2
const int sensorPin2 = A2; //Defines the pin that the anemometer output is connected to
int sensorValue2 = 0; //Variable stores the value direct from the analog pin
float sensorVoltage2 = 0; //Variable that stores the voltage (in Volts) from the anemometer being sent to the analog pin
float windSpeed2 = 0; // Wind speed in meters per second (m/s)

float voltageConversionConstant = .004882814; //This constant maps the value provided from the analog read function,
//which ranges from 0 to 1023, to actual voltage, which ranges from 0V to 5V
int sensorDelay = 1000; //Delay between sensor readings, measured in milliseconds (ms)

//Anemometer Technical Variables
//The following variables correspond to the anemometer sold by Adafruit but could be modified to fit other anemometers.

float voltageMin = .4; // Mininum output voltage from anemometer in mV.
float windSpeedMin = 0; // Wind speed in meters/sec corresponding to minimum voltage

float voltageMax = 2.0; // Maximum output voltage from anemometer in mV.
float windSpeedMax = 32; // Wind speed in meters/sec corresponding to maximum voltage

// for the data logging shield, we use digital pin 10 for the SD cs line
const int chipSelect = 10;

// the logging file
File logfile;

void error(char *str)
{
  Serial.print("error: ");
  Serial.println(str);

  // red LED indicates error
  digitalWrite(redLEDpin, HIGH);

  while(1);
}

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

  Serial.begin(9600);
  Serial.println();

#if WAIT_TO_START
  Serial.println("Type any character to start");
  while (!Serial.available());
#endif //WAIT_TO_START

  // initialize the SD card
  Serial.print("Initializing SD card...");
  // make sure that the default chip select pin is set to
  // output, even if you don't use it:
  pinMode(10, OUTPUT);

  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    return;
  }
  Serial.println("card initialized.");

  // create a new file
  char filename[] = "LOGGER00.CSV";
  for (uint8_t i = 0; i < 100; i++) {
    filename[6] = i/10 + '0';
    filename[7] = i%10 + '0';
    if (! SD.exists(filename)) {
      // only open a new file if it doesn't exist
      logfile = SD.open(filename, FILE_WRITE);
      break;  // leave the loop!
    }
  }

  if (! logfile) {
    error("couldnt create file");
  }

  Serial.print("Logging to: ");
  Serial.println(filename);

  Wire.begin();
  if (!RTC.begin()) {
    logfile.println("RTC failed");
#if ECHO_TO_SERIAL
    Serial.println("RTC failed");
#endif  //ECHO_TO_SERIAL
  }

  pinMode(redLEDpin, OUTPUT);
  pinMode(greenLEDpin, OUTPUT);

   // If you want to set the aref to something other than 5v
  //analogReference(EXTERNAL);
}

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

  DateTime now;

  // delay for the amount of time we want between readings
  delay((LOG_INTERVAL -1) - (millis() % LOG_INTERVAL));

  digitalWrite(greenLEDpin, HIGH);

  // log milliseconds since starting
  uint32_t m = millis();
  logfile.print(m);           // milliseconds since start
  logfile.print(", ");
#if ECHO_TO_SERIAL
  Serial.print(m);         // milliseconds since start
  Serial.print(", ");
#endif

  // fetch the time
  now = RTC.now();
  // log time
//logfile.print(); // seconds since 2000
  logfile.print(", ");
  logfile.print(now.year(), DEC);
  logfile.print("/");
  logfile.print(now.month(), DEC);
  logfile.print("/");
  logfile.print(now.day(), DEC);
  logfile.print(" ");
  logfile.print(now.hour(), DEC);
  logfile.print(":");
  logfile.print(now.minute(), DEC);
  logfile.print(":");
  logfile.print(now.second(), DEC);

#if ECHO_TO_SERIAL
  Serial.print(now.get()); // seconds since 2000
  Serial.print(", ");
  Serial.print(now.year(), DEC);
  Serial.print("/");
  Serial.print(now.month(), DEC);
  Serial.print("/");
  Serial.print(now.day(), DEC);
  Serial.print(" ");
  Serial.print(now.hour(), DEC);
  Serial.print(":");
  Serial.print(now.minute(), DEC);
  Serial.print(":");
  Serial.print(now.second(), DEC);
#endif //ECHO_TO_SERIAL

//Anemometer0
const int sensorPin0 = A0; //Defines the pin that the anemometer output is connected to
int sensorValue0 = 0; //Variable stores the value direct from the analog pin
float sensorVoltage0 = 0; //Variable that stores the voltage (in Volts) from the anemometer being sent to the analog pin
float windSpeed0 = 0; // Wind speed in meters per second (m/s)

//Anemometer1
const int sensorPin1 = A1; //Defines the pin that the anemometer output is connected to
int sensorValue1 = 0; //Variable stores the value direct from the analog pin
float sensorVoltage1 = 0; //Variable that stores the voltage (in Volts) from the anemometer being sent to the analog pin
float windSpeed1 = 0; // Wind speed in meters per second (m/s)

//Anemometer2
const int sensorPin2 = A2; //Defines the pin that the anemometer output is connected to
int sensorValue2 = 0; //Variable stores the value direct from the analog pin
float sensorVoltage2 = 0; //Variable that stores the voltage (in Volts) from the anemometer being sent to the analog pin
float windSpeed2 = 0; // Wind speed in meters per second (m/s)

float voltageConversionConstant = .004882814; //This constant maps the value provided from the analog read function,
//which ranges from 0 to 1023, to actual voltage, which ranges from 0V to 5V
int sensorDelay = 1000; //Delay between sensor readings, measured in milliseconds (ms)

//Anemometer Technical Variables
//The following variables correspond to the anemometer sold by Adafruit but could be modified to fit other anemometers.

float voltageMin = .4; // Mininum output voltage from anemometer in mV.
float windSpeedMin = 0; // Wind speed in meters/sec corresponding to minimum voltage

float voltageMax = 2.0; // Maximum output voltage from anemometer in mV.
float windSpeedMax = 32; // Wind speed in meters/sec corresponding to maximum voltage

  logfile.print(", ");
  logfile.print(A0);
  logfile.print(", ");
  logfile.print(A1);
  logfile.print(",");
  logfile.println(A2);

#if ECHO_TO_SERIAL
  Serial.print(", ");
  Serial.print(Anemometer0);
  Serial.print(", ");
  Serial.print(Anemometer1);
  Serial.print(",");
  Serial.println(Anemometer2);
#endif //ECHO_TO_SERIAL

  digitalWrite(greenLEDpin, LOW);
}
´´´

```

# Answer
Thanks for all your help. I managed to log data in the SD card including date and time. The new code is the following:

```
#include <SPI.h>
#include <SD.h>
#include "RTClib.h"

RTC_DS1307 rtc; // create local instances of library class objects

DateTime time;

File dataFile;

const int chipSelect = 10;

// Anemometer at 0.15 magl

const int sensorPinA0 = A0; //Defines the pin that the anemometer output is connected to
int sensorValue0 = 0; //Variable stores the value direct from the analog pin
float sensorVoltage0 = 0; //Variable that stores the voltage (in Volts) from the anemometer being sent to the analog pin
float WindSpeed0 = 0; // Wind speed in meters per second (m/s)

float voltageConversionConstant0 = .0048828125; //This constant maps the value provided from the analog read function, which ranges from 0 to 1024, to actual voltage, which ranges from 0V to 5V
// hence, this value corresponds to 5.00V/1024. Check https://forum.allaboutcircuits.com/threads/why-adc-1024-is-correct-and-adc-1023-is-just-plain-wrong.80018/
int sensorDelay0 = 60000; //Delay between sensor readings, measured in milliseconds (ms)

//Anemometer Technical Variables
//The following variables correspond to the anemometer sold by Adafruit but could be modified to fit other anemometers.

float voltageMin0 = .4; // Mininum output voltage from anemometer in mV.
float windSpeedMin0 = 0; // Wind speed in meters/sec corresponding to minimum voltage

float voltageMax0 = 2.0; // Maximum output voltage from anemometer in mV.
float windSpeedMax0 = 32; // Wind speed in meters/sec corresponding to maximum voltage

// Anemometer at 0.5 magl

const int sensorPinA1 = A1; //Defines the pin that the anemometer output is connected to
int sensorValue1 = 0; //Variable stores the value direct from the analog pin
float sensorVoltage1 = 0; //Variable that stores the voltage (in Volts) from the anemometer being sent to the analog pin
float WindSpeed1 = 0; // Wind speed in meters per second (m/s)

float voltageConversionConstant1 = .0048828125; //This constant maps the value provided from the analog read function, which ranges from 0 to 1024, to actual voltage, which ranges from 0V to 5V
// hence, this value corresponds to 5.00V/1024. Check https://forum.allaboutcircuits.com/threads/why-adc-1024-is-correct-and-adc-1023-is-just-plain-wrong.80018/
int sensorDelay1 = 1000; //Delay between sensor readings, measured in milliseconds (ms)

//Anemometer Technical Variables
//The following variables correspond to the anemometer sold by Adafruit but could be modified to fit other anemometers.

float voltageMin1 = .4; // Mininum output voltage from anemometer in mV.
float windSpeedMin1 = 0; // Wind speed in meters/sec corresponding to minimum voltage

float voltageMax1 = 2.0; // Maximum output voltage from anemometer in mV.
float windSpeedMax1 = 32; // Wind speed in meters/sec corresponding to maximum voltage

// Anemometer at 1.2 magl

const int sensorPinA2 = A2; //Defines the pin that the anemometer output is connected to
int sensorValue2 = 0; //Variable stores the value direct from the analog pin
float sensorVoltage2 = 0; //Variable that stores the voltage (in Volts) from the anemometer being sent to the analog pin
float WindSpeed2 = 0; // Wind speed in meters per second (m/s)

float voltageConversionConstant2 = .0048828125; //This constant maps the value provided from the analog read function, which ranges from 0 to 1024, to actual voltage, which ranges from 0V to 5V
// hence, this value corresponds to 5.00V/1024. Check https://forum.allaboutcircuits.com/threads/why-adc-1024-is-correct-and-adc-1023-is-just-plain-wrong.80018/
int sensorDelay2 = 60000; //Delay between sensor readings, measured in milliseconds (ms)

//Anemometer Technical Variables
//The following variables correspond to the anemometer sold by Adafruit but could be modified to fit other anemometers.

float voltageMin2 = .4; // Mininum output voltage from anemometer in mV.
float windSpeedMin2 = 0; // Wind speed in meters/sec corresponding to minimum voltage

float voltageMax2 = 2.0; // Maximum output voltage from anemometer in mV.
float windSpeedMax2 = 32; // Wind speed in meters/sec corresponding to maximum voltage

void setup() {
 Serial.begin(9600);
 while (!Serial) {;} // wait for serial port to connect.
 Serial.print("Initializing SD card...");
 if (!SD.begin(chipSelect)) {
 Serial.println("Card failed, or not present");
 while (1); // loop forever
 }
 Serial.println("Have SD card");
 rtc.begin();
}

void loop() {

sensorValue0 = analogRead(A0); //Get a value between 0 and 1023 from the analog pin connected to the anemometer
sensorValue1 = analogRead(A1); //Get a value between 0 and 1023 from the analog pin connected to the anemometer
sensorValue2 = analogRead(A2); //Get a value between 0 and 1023 from the analog pin connected to the anemometer

sensorVoltage0 = sensorValue0 * voltageConversionConstant0; //Convert sensor value to actual voltage
sensorVoltage1 = sensorValue1 * voltageConversionConstant1; //Convert sensor value to actual voltage
sensorVoltage2 = sensorValue2 * voltageConversionConstant2; //Convert sensor value to actual voltage

//Convert voltage value to wind speed using range of max and min voltages and wind speed for the anemometer
if (sensorVoltage0 <= voltageMin0){
WindSpeed0 = 0; //Check if voltage is below minimum value. If so, set wind speed to zero.
}

else {
  WindSpeed0 = (sensorVoltage0 - voltageMin0)*windSpeedMax0/(voltageMax0 - voltageMin0); //For voltages above minimum value, use the linear relationship to calculate wind speed on A0.
    }

if (sensorVoltage1 <= voltageMin1){
WindSpeed1 = 0; //Check if voltage is below minimum value. If so, set wind speed to zero.
}

else {
  WindSpeed1 = (sensorVoltage1 - voltageMin1)*windSpeedMax1/(voltageMax1 - voltageMin1); //For voltages above minimum value, use the linear relationship to calculate wind speed on A1.
    }

if (sensorVoltage2 <= voltageMin2){
WindSpeed2 = 0; //Check if voltage is below minimum value. If so, set wind speed to zero.
}

else {
  WindSpeed2 = (sensorVoltage2 - voltageMin2)*windSpeedMax2/(voltageMax2 - voltageMin2); //For voltages above minimum value, use the linear relationship to calculate wind speed on A2.
    }

 time = rtc.now(); // Read RTC
 String dataString = ""; // Assemble data

log:
 dataString = time.timestamp(DateTime::TIMESTAMP_DATE);
 dataString += ", ";
 dataString += time.timestamp(DateTime::TIMESTAMP_TIME);
 dataString += ", ";
 dataString += String(sensorVoltage0);
 dataString += ", ";
 dataString += String(WindSpeed0);
 dataString += ", ";
 dataString += String(sensorVoltage1);
 dataString += ", ";
 dataString += String(WindSpeed1);
 dataString += ", ";
 dataString += String(sensorVoltage2);
 dataString += ", ";
 dataString  += String(WindSpeed2);
 dataFile = SD.open("Speedlog.txt", FILE_WRITE);
 if (dataFile) { // Write to logfile

 dataFile.println(dataString);
 dataFile.close();
 Serial.println(dataString);
 delay(1000); // pause for one second between sensor logs
 }
 else {
 Serial.println("error opening datalog.txt");
 }
}

```
> 2 votes

---
Tags: arduino-uno, code-review, datalogging
---


# Question
Title: Reading Multiple MPU 9250 Sensors using TCA9548A Multiplexer
I am trying to read multiple MPU 9250 sensors using TCA9548A multiplexer in ESP 32 and Arduino IDE. Has anyone done that successfully?

I am new to the area of Arduino coding. I am trying to edit the code in this tutorial for MPU 9250 (https://www.bluedot.space/tutorials/connect-multiple-sensors-using-i2c-multiplexer/). I am facing issues with libraries and commands while shifting from BME 280 to MPU 9250. Once I am changing to MPU 9250 and trying to call instance MPU9250 IMU\_0, I am getting error "no matching function for call to 'MPU9250", which I understand is because the library I've used doesn't support the call. I am unable to find alternate library or command. How can this be sorted out?

```
#include <Wire.h>
#include <MPU9250.h>
MPU9250 mpu_0;
MPU9250 mpu_1;
MPU9250 mpu_2;
MPU9250 mpu_3;

#define TCAADDR 0x70
void tcaselect(uint8_t i) {
  if (i > 7) return;

  Wire.beginTransmission(TCAADDR);
  Wire.write(1 << i);
  Wire.endTransmission();
}
void setup() {
  Serial.begin(9600);
  Wire.begin();
  Serial.println(F("##############################"));
  Serial.println(F("Starting Initialization"));
  Serial.println(F("##############################"));

  //*************INITIALIZING FIRST SENSOR*******************************
  tcaselect(0);

  if (mpu_0.begin() != 0x68)
  { Serial.print(F("MPU.1 detected?\t")); Serial.println(F("No"));}
  else
  { Serial.print(F("MPU.1 detected?\t")); Serial.println(F("Yes"));}
  //**********************************************************************
  //*************INITIALIZING SECOND SENSOR*******************************
  tcaselect(1);

  if (mpu_1.begin() != 0x68)
  { Serial.print(F("MPU Nr.2 detected?\t")); Serial.println(F("No"));}
  else
  { Serial.print(F("MPU Nr.2 detected?\t")); Serial.println(F("Yes"));}
  //*********************************************************************
  //**********************************************************************
  Serial.println();
  Serial.println(F("##############################"));
  Serial.println(F("Initialization Finished"));
  Serial.println(F("##############################"));
  Serial.println();
  Serial.println();
}

```

# Answer
You need to adapt the example you're following to follow how the MPU library does its construction and setup.

Looking at the documentation for the MPU library you are using, you should change the definitions to:

```
MPU9250 mpu_0(Wire, 0x68);  // 0x69 if you pulled AD0 high

```

Then if you read further to the "Common Setup Functions" section, you'll see that this library's `setup` function has this behavior:

> This function returns a positive value on a successful initialization and returns a negative value on an unsuccesful initialization

So you need to adapt that too:

```
Serial.print(F("MPU.1 detected?\t"));
if (mpu_0.begin() < 0) { // the examples assume zero is ok too
  Serial.println(F("No"));
} else {
  Serial.println(F("Yes"));
}

```

You'll save yourself some trouble if you use an array for your sensors too.

```
MPU9250 mpus[] = { MPU9250(Wire, 0x68), MPU9250(Wire, 0x68) };
const int num_mpus = sizeof(mpus)/sizeof(mpus[0]);

```

Then your initialization can be done with a loop:

```
for (int i = 0; i < num_mpus; ++i) {
   tcaselect(i);
   if (mpus[i].begin() < 0) {
     // ...
   }
 }

```

And you can do similar things for interacting with the sensor. e.g.:

```
for (int i = 0; i < num_mpus; ++i) {
   tcaselect(i);
   mpus[i].readSensor();
   Serial.println(mpus[i].getAccelX_mss());
   // ...
 }

```
> 1 votes

---
Tags: esp32, mpu6050, multiplexer
---


# Question
Title: How to count number of bytes appearing in the Arduino serial?
I need to count the number of bytes appearing in the serial (UART bus) bus, how to count bytes in Arduino with Arduino Serial functions? is this possible?

Application - RS485 communication with multiple boards **without slave ID**

slave boards will send data to the master board when,

1st 10 bytes = masters send a 10byte message to all slaves

slaves listening to the bus always until it is the turn to send the data

when byte count is 10, slave 1 sends data 5 bytes to master

when byte count is 15 (10+5), slave 2 sends data 5 bytes to master

when byte count is 20 (15+5), slave 3 sends data 5 bytes to master

max count is 25 known value

# Answer
> 1 votes
`Serial.available()` returns the number of bytes available for reading in the buffer.

```
int nBytes=Serial.available();
if (nBytes > x) {
............
............
............
}

```

---
Tags: serial, rs485
---


title: File.read() always returns -1

text:
# Question
Title: File.read() always returns -1
I'm trying to print a txt file from an SD card to a SSD1306 using the u8x8 library. Here's the current code:

```
#include <SD.h>

#include <Arduino.h>
#include <U8x8lib.h>

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

  U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8(/* reset=*/ U8X8_PIN_NONE);

/*
  This example will probably not work with the SSD1606, because of the
  internal buffer swapping
*/
#define maxChar  128
#define rows 8
#define cols 16

File myFile;
int x = 0;
int y = 0;
char c;

void setup()
{
  /*Serial.begin(9600);
  Serial.print("Initializing SD... ");
  if (!SD.begin(10)) {
    Serial.println("initialization failed!");
    while (1);
  }
  Serial.println("initialization done.");*/

  u8x8.begin();
  delay(500);
  u8x8.setFont(u8x8_font_amstrad_cpc_extended_f);

  myFile = SD.open("target.txt", FILE_READ);
  u8x8.clear();
  u8x8.print("ciao");
  u8x8.print(myFile.read());
  delay(2000);
  printNewSet();
}
void loop()
{

}

void printNewSet()
{
  u8x8.clear();
  x = 0;
  y = 0;
  while (myFile.available() && y<rows)
  {
    c = (char) myFile.read();
    if (c == '\n') c = 'a';
    u8x8.print(c);
    stepCoords();
  }
}

void stepCoords()
{
  x++;
  if (x >= cols) newLine();
}
void newLine()
{
  u8x8.print('\n');
  x = 0;
  y++;
}

```

The function `printNewSet()` is supposed to print a batch of characters until either the file ends or the display limit is reached.

The file displayed correctly until i switched from `while(myFile.available()) u8x8.print( (char) myFile.read());` to `printNewSet()`, at which point `myFile.read()` only returns -1 and `myFile.available()` is always false.

What is going wrong?

EDIT: While debugging i discovered that myFile fails to be initialized. Am I running out of memory?

# Answer
> 1 votes
I had accidentally commented out the SD initialization along with the serial initialization. After uncommenting it it works correctly

---
Tags: sd-card, oled, ssd1306
---


# Question
Title: Splitting DOUBLE in byte for save on EEPROM
I'm trying to save in memory (FRAM in this case) DOUBLE value, i try the same method with use of UNION for save FLOAT value, but don't go over the 2nd number after dot, why? Where I'm wrong? thank's for help .

```
 //---------------------------------------------------------

  union Scomp_double  // si utilizza union x double
  {
    double temp;
    char byte_s[8];
  } S_double;

  //---------------------------------------------------------

double mioDouble = 1234567.12345678;

//-------------------------DOUBLE--------------------------------

  Serial.println("DOUBLE");
  byte d0 = 0;  // contengono i byte del float
  byte d1 = 0;
  byte d2 = 0;
  byte d3 = 0;
  byte d4 = 0;
  byte d5 = 0;
  byte d6 = 0;
  byte d7 = 0;

  S_double.temp = mioDouble;
  d0 = S_double.byte_s[0];
  d1 = S_double.byte_s[1];
  d2 = S_double.byte_s[2];
  d3 = S_double.byte_s[3];
  d4 = S_double.byte_s[4];
  d5 = S_double.byte_s[5];
  d6 = S_double.byte_s[6];
  d7 = S_double.byte_s[7];

  Serial.println(d0);
  Serial.println(d1);
  Serial.println(d2);
  Serial.println(d3);
  Serial.println(d4);
  Serial.println(d5);
  Serial.println(d6);
  Serial.println(d7);

  fram.writeEnable(true);
  fram.write8(11, d0);
  fram.writeEnable(false);
  fram.writeEnable(true);
  fram.write8(12, d1);
  fram.writeEnable(false);
  fram.writeEnable(true);
  fram.write8(13, d2);
  fram.writeEnable(false);
  fram.writeEnable(true);
  fram.write8(14, d3);
  fram.writeEnable(false);
  fram.writeEnable(true);
  fram.write8(15, d4);
  fram.writeEnable(false);
  fram.writeEnable(true);
  fram.write8(16, d5);
  fram.writeEnable(false);
  fram.writeEnable(true);
  fram.write8(17, d6);
  fram.writeEnable(false);
  fram.writeEnable(true);
  fram.write8(18, d7);
  fram.writeEnable(false);

  S_double.byte_s[0] = fram.read8(11); // si ricompone il double
  S_double.byte_s[1] = fram.read8(12);
  S_double.byte_s[2] = fram.read8(13);
  S_double.byte_s[3] = fram.read8(14);
  S_double.byte_s[4] = fram.read8(15);
  S_double.byte_s[5] = fram.read8(16);
  S_double.byte_s[6] = fram.read8(17);
  S_double.byte_s[7] = fram.read8(18);

  double masterDouble = S_double.temp;
  Serial.println(masterDouble);
  //-------------------------DOUBLE-------------------------------

```

expected result 1234567.12345678 , result taken 1234567,12

# Answer
> 1 votes
how suggest in the comments, and on Arduino reference DOUBLE website

only on arduino 2 float it's 8 byte.

# Answer
> 1 votes
The problem here is the serial output, which by default only outputs 2 decimal places. Solution: Serial.println(masterDouble,8);

---
Tags: eeprom
---


# Question
Title: Different Output Voltages from Same Source?
I'm wondering whether it is possible to wire multiple buck converters with different voltage requirements and amperage draws to the same power source (this idea is for controlling a radio-controlled boat). Going off other related questions this seems to be possible (, ).

My background is in programming, not electronics, so the terminology is difficult for me to understand. I'm getting a grasp on voltage and amperage. My problem is always understanding how electricity can be "split" into different modules. In my understanding, this below would be a parallel circuit and that should be fine.

1. Are there any gotchas to consider with this type of circuit, or is this the totally normal way of doing things (eg. like wiring a house out of a breaker box)?
2. Is there a better way to do this?
3. This won't cause a short circuit, right?

# Answer
> Are there any gotchas to consider with this type of circuit, or is this the totally normal way of doing things (eg. like wiring a house out of a breaker box)?

That's a perfectly normal way of wiring it.

> Is there a better way to do this?

No, it's how I'd do it.

> This won't cause a short circuit, right?

Not intentionally, no. However it's always good to add a fuse or two to protect everything just in case anything untoward should happen. Especially where water is concerned.
> 1 votes

---
Tags: electronics, voltage
---


title: Connect RGB LED board to Arduino?

text:
# Question
Title: Connect RGB LED board to Arduino?
I'm trying to repurpose an RGB LED (pictured) and use an Arduino board I've just gotten to reprogram the lights. I'm very new to electronics engineering and I don't really know how to get started. How would I connect it to the Arduino? What kind of wire(s) would be best for soldering this to as well as connecting to the Arduino? Can this be programmed like any other LED?

Images: https://i.stack.imgur.com/u14Bd.jpg https://i.stack.imgur.com/2inQB.jpg

# Answer
> 2 votes
Connect each of the 3 "L" wires to 3 separate digital IO pins of an arduino e.g. D8, D9, D10 via a resistor say 470 ohms but the value is not too critical. Connect VDD to the arduino +5v.

Use the arduino IDE write a sketch that configures pins 8 9 and 10 as outputs and then see what happens when you send these pins HIGH or LOW. Theres lots more you can do. Good luck.

# Answer
> 1 votes
Given that the pin is labeled VDD, it's likely that the LEDs are common anode. (You'd hook the VDD pin to a positive voltage, and then connect the other pins to ground in order to light them.)

You really need to know the specs of the LEDs in order to calculate the size of the current limiting resistors.

Say your LEDs have a 1.2v forward voltage and can take 20 mA of current (.02 amps)

You'd use the formula R = (supply\_voltage - LED\_voltage)/current

so R = (5-1.2)/.020 = 190 Ω. Use the next higher value. (220 Ω for 20% resistors, the cheapest/most common kind you're likely to have access to.)

Try hooking each of the LEDs through a 220 Ω resistor to ground and seeing what you get. (Note that different colors of LEDs can have different forward voltages, so the forward voltage you use in the above calculation might be different for each LED.) If it barely lights, move down to the next-lower resistor value and try again. (150 Ω for 20% resistors.) If it's crazy-bright, or gets warm to the touch, use the next higher resistor value.

You'd then control the LEDs using PWM pins on your Arduino, and vary the duty cycle on 3 different output pins to vary the apparent brightness of the different colored LEDs. Note that since these LEDS appear to be common **anode** (Common power connection, and you switch the grounds to turn them on and off) the PWM values will be reversed. Setting a PWM pin to 0 will make that LED burn the brightest, and setting it to 255 will turn it off. That's because at 0, the pin is at 5V 0% of the time and connected to ground (which lights it) 100% of the time.

---
Tags: arduino-nano, led, rgb-led
---


# Question
Title: I am looking into putting sound files onto an Arduino Nano without a microSD card
I figured out how to install the sound onto the card from this site

https://github.com/charliegerard/dev-notes/blob/master/arduino/wavFilesWithoutSdCard.md

It says I need to use pin 11 on the Uno but would pin 11 on the nano work or not? I am getting these boards.

https://www.amazon.com/gp/product/B0713XK923/ref=ox\_sc\_act\_title\_3?smid=A2WWHQ25ENKVJ1&psc=1

Also, does anyone have good speaker suggestions, I'm going with these right now(https://www.amazon.com/CQRobot-JST-PH2-0-Interface-Electronic-Projects/dp/B0738NLFTG/ref=sr\_1\_6?dchild=1&keywords=speakers+arduino%5D%5C&qid=1607285501&sr=8-6)

I'm not sure if I'm giving enough information so just tell me if I need to provide you with more information.

# Answer
Uno and Nano uses the same Atmel MCU, so pin 11 is the same on both.

And a for the speakers, Arduino CAN'T driver 8ohms load! You need a amplifier.
> 2 votes

---
Tags: arduino-nano, speaker
---


# Question
Title: Storing and sequencing output value (Arduino)
I am new to Arduino programming, after days and nights trying to use array and for loop, and googling a lot of articles, I am still unable to find how to store each weighing output value from `int Sampling()` to be executed by the respective servo in sequence order.

If you have any clue to share and help me, I'll be very happy.

Below is my base code:

```
#include <HX711.h>
///////////////////////////////////////////////////////////////////////
#define calibration_factor -251
#define LOADCELL_DOUT_PIN 7   // data
#define LOADCELL_SCK_PIN 8    // sck
////////////////////////////////////////////////////////////////////////
HX711 scale;
////////////////////////////////////////////////////////////////////////
int servo1 = 12;
int servo2 = 13;
int proxiPin1 = 2;
int proxiPin2 = 3;
////////////////////////////////////////////////////////////////////////
int toggleState = 0;
int proxiState1 = 1;
int proxiState2 = 1;
////////////////////////////////////////////////////////////////////////
int weight;
int weightFinal;
////////////////////////////////////////////////////////////////////////
void setup()
{
  Serial.begin(9600);
  scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN);
  scale.set_scale(calibration_factor);
  scale.tare();

  pinMode(servo1, OUTPUT); // simulating servo1
  pinMode(servo2, OUTPUT); // simulating servo2
  pinMode(proxiPin1, INPUT_PULLUP); // proximity
  pinMode(proxiPin2, INPUT_PULLUP); // proximity

}
/////////////////////////////////////////////////////////////////////////
void loop()
{
  Serial.print(Sampling());
  Serial.print(" gram");
  Serial.println();
  ///////////////////////////////////////////////////////////////////////
  if ( weightFinal == 10 )
  {
    toggleState = true;
    servo10gr();
  }

  if ( weightFinal == 20 )
  {
    toggleState = true;
    servo20gr();
  }
}
////////////////////////////////////////////////////////////////////////
int Sampling()
{
  int weight = scale.get_units();

  if (weight >= 10  && weight< 20)
  {
    weightFinal = 10;
  }

  else if (weight >= 20  && weight < 30)
  {
    weightFinal = 20;
  }

  return weight;
}
/////////////////////////////////////////////////////////////////////////
int servo10gr()
{
  proxiState1 = digitalRead(proxiPin1);
  if ( proxiState1 == 0 && toggleState == true )
  {
    digitalWrite(servo1, HIGH);  //Simulating servo signal Pin//
    delay(500);
    digitalWrite(servo1, LOW);

    toggleState = false;
    weightFinal=0;
  }
}
/////////////////////////////////////////////////////////////////////////
int servo20gr()
{
  proxiState2 = digitalRead(proxiPin2);
  if ( proxiState2 == 0 && toggleState == true )
  {
    digitalWrite(servo2, HIGH);    //Simulating servo signal Pin//
    delay(500);
    digitalWrite(servo2, LOW);

    toggleState = false;
    weightFinal=0;
  }
}

```

# Answer
I'm still not entirely sure what you want to achieve, but maybe this will help:

You have a global variable `int weight`, and in `int Sampling()` you create another `int weight = scale.get_units()` which you give a value.

That second variable is only accessible inside of `Sampling()`. If you want to use it elsewhere for storing or in other functions, change:

`int weight = scale.get_units();`

to

`weight = scale.get_units();`

and you can then use `weight` wherever you like in your code, also in `servo10gr()` and `servo20gr()`.

You don't need to store a sequence of `weight`s to drive the servos; you can just use the current weight immediately to drive a servo and then get a new `weight`.

If, however, you want or need to keep a list of `weights` for some reason, there's a bit more work to be done.

There are better ways of going about this, but let's see first if this solves your problem.
> 1 votes

---
Tags: c++, array, loop
---


# Question
Title: Interfacing unusual 4 digits 7 segments display
There is a common anode and common cathode of 7 segments display. But I got an unusual one.

There are 7 pins controlling 4 digits 7 segments.

I find the pinout by a multimeter. Basically, each pin can be anode or cathode.

My questions:

1. What is the exact name of this 7 segments display?
2. How to drive this display by Arduino, any website/sample code?
3. If I am using the 5V tolerant board, which resistor I need to use? And how is the schematic?

# Answer
This display seems to have 32 addressable LEDs controlled by only 7 pins. Judging from this fact, and from the provided pinout table, it looks like a Charlieplexed matrix.

A typical way to drive this kind of matrix is by looping over the cathodes. You pull one cathode pin `LOW`, and then pull `HIGH` all the anodes of the LEDs you want to shine which are connected to this particular cathode. Wait a few milliseconds, then move to the next cathode. It is important that all pins that are not involved in lighting an LED remain in `INPUT` mode.

For example, let's say you want to light all the segments of the first digit (display an “8”) while keeping everything else off. You first pull pin 1 `LOW` (first cathode) and pull `HIGH` pins 2–5 (segments F, G, C and D). Let that shine for a few milliseconds, then put everything to high impedance (pins to `INPUT`) and move to the next cathode: pin 2 goes `LOW` and pin 1 (segment A) goes `HIGH`. And so on until you have done all the cathodes.

For the coding part, I would suggest using a 7×7 matrix of booleans telling whether a particular segment is meant to be lit. The indices of the array would be row = cathode number and column = anode number. The array would have the same structure as the pinout table you posted, except for the fact that the lines and columns would have indices ranging 0–6 instead of 1–7. This should make it easy to handle refreshing the display.

Drawing the digits is a bit trickier than with traditional 7-segment displays, as for each segment you will have to find its coordinates in the matrix (cathode number and anode number). For this, I would use a “mapping matrix” that stores the mapping (digit number, segment number) → (cathode number, anode number).

Below is a tentative, and untested, implementation of these strategies. Note that I did not write a function to output a digit, but that should be easy to implement on top of the `set_segment()` function defined here. Besides, the question of how to draw a digit once you know how to control individual segments is the standard 7-segment problem, for which you should be able to find many tutorials.

Note that this code assumes you drive the display directly, using no iterface other than current-limiting resistors. This carries the risk of either overloading the cathode outputs or having the display be too dim, depending on the current-limiting resistors. You may want to use transistors for the cathodes, in which case you would have a set of cathode pins different from the set of anode pins.

```
// Arduino pins connected to the display.
const uint8_t display_pins[7] = {2, 3, 4, 5, 6, 7, 8};

// Which segments are lit. Each segment is located in this matrix at
// the coordinates [cathode][anode].
bool segment_lit[7][7];

// Coordinates in the matrix above where a segment can be found.
struct SegmentCoordinates {
    uint8_t cathode;
    uint8_t anode;
};

// segments[digit][segment] gives the coordinates of
// any segment (0 = A) of any digit (0 = 1st digit).
const SegmentCoordinates segments[4][7] = {
// seg: A      B        C       D      E        F       G
    {{1, 0}, {2, 0}, {0, 3}, {0, 4}, {3, 0}, {0, 1}, {0, 2}},
    {{2, 1}, {3, 1}, {1, 4}, {5, 1}, {4, 1}, {1, 2}, {1, 3}},
    {{3, 4}, {4, 2}, {4, 3}, {0, 5}, {2, 5}, {2, 3}, {2, 4}},
    {{5, 6}, {6, 5}, {5, 4}, {3, 5}, {5, 3}, {4, 5}, {6, 4}}
};

// Turn a segment OFF (lit = false) or ON (lit = true).
void set_segment(uint8_t digit, uint8_t segment, bool lit) {
    SegmentCoordinates coordinates = segments[digit][segment];
    segment_lit[coordinates.cathode][coordinates.anode] = lit;
}

void setup(){}

void loop() {
    static uint8_t cathode;  // currently used cathode

    // Set the current cathode to OUTPUT LOW.
    digitalWrite(display_pins[cathode], LOW);
    pinMode(display_pins[cathode], OUTPUT);

    // Set the relevant anodes to OUTPUT HIGH.
    for (int anode = 0; anode < 7; anode++) {
        if (segment_lit[cathode][anode]) {
            digitalWrite(display_pins[anode], HIGH);
            pinMode(display_pins[anode], OUTPUT);
        }
    }

    // Let that shine for a while.
    delay(10);

    // Turn off everything.
    for (int pin = 0; pin < 7; pin++) {
        pinMode(display_pins[pin], INPUT);
    }

    // Move to the next cathode.
    if (++cathode >= 7) cathode = 0;
}

```

I used `delay()` here for simplicity. In production code you would handdle the timings with `millis()` in a non-blocking fashion, in the spirit of the “Blink without delay” tutorial.
> 4 votes

# Answer
1. I don't know. If I had to talk about it, I would say a LED segment display with a matrix layout with a complementary drive.
2. If a pin is used as a cathode, a LOW signal must be applied. If it is used as an anode, a HIGH signal must be applied.

You could define constants for each segments anode and cathode that define a pin number. e.g :

```
#define CAT_1A = 2
#define AN_1A  = 1

```

and so on. Then if you whant to show segment 1A set CAT\_1A to LOW and AN\_1A to HIGH.

Of course the whole process is more complicated. You have to define which segments must be light up to show a specific digit. You must show all four digits one by one in a fast loop and so on. But that's the same as you would do for an ordinary LED segment bar. The difference is that you have to configure pin pairs and not single pins.

3. Use your Multimeter to measure the Forward voltage of the segments. If they are red, it should be around 1.8 to 2.4 Volts. Substract this Voltage from 5 Volts. Then devide by 0.02 (20 mA) and you get the Resistor in Ohms. A standard LED is bright enough with about 20 mA.

Example:

```
(5V - 1.8V) / 0.02A) = 160 Ohm

```

Use a resistor of say 100 Ohms at each pin. It is common available and as the current flows always through 2 pins, you have 200 Ohms together.

It is also possible that the LED bar has internal resistors. Try to meassure the resistance beetween to pins.

**Edit** When I said, "each digit must be shown in a fast loop", I forgot to clearify that, for each digit, the segments must be switched sequentially.

You can do it even more complicated and show all Segments with a common cathode or a common annode at once. Then you need fewer cycles, but as you use resistors for all pins (see point 3.) this could dim the LEDs remarkably. Also, becaus technically, the forward voltage of different LED may differ, so the some could be brighter the others.

There is also another thing, I did not think of, when I wrote the answer. If you power a segment, say from pin A (+5V) to pin B (GND), you have a resistor (100 Ohms), an LED (minus 1.8 Volts) and a second resitor (100 Ohms) in series. So in an ideal situation the voltage on pin B (also on the second resitor) would by around 1.6 Volts. Pin B is the cathode of the LED segment, but can also be the anode of another segment (S2). If the cathode of S2 is connected to GND there is a very small chance, that the segment lights up. If you don't see (ghost) lights, all is fine. But if some segments light up (but much darker than the right ones) you have to find a better solution.
> 2 votes

---
Tags: 7-segment
---


# Question
Title: Unable to control fan with IR circuit despite capturing and reproducing the IR transmissions
I'm trying to use an Arduino to control my Bionaire window fan. I followed several guides to build an IR receiver circuit to record the patterns sent by the remote for its five buttons . From there, I've tried both an IR transmitter circuit with IRSendRaw and a separate Raspberry Pi circuit using an IR transceiver hat and LIRC , but the fan does not seem to pick up either. I've verified that the Pi receiver recognizes the commands from the Arduino transmitter circuit just as it does from the fan's actual remote and vice-versa, but even if I put the fan directly against the IR LED, it does not respond to any of the commands from the circuit.

What else might I need to do to make this work properly? As an alternative, what would be the best way to go about directly activating the 'buttons' on the remote circuit board pictured above?

Thanks in advance for your help

For future refernece, these are the signals I recorded for the remote, which match up with this post on electronics stackexchange.

```
power: 4E87E0AB
1300 -400 1300 -350 450 -1200 1300 -400 1300 -350 1300 -400 450 -1200 500 -1200 450 -1200 1300 -400 1300 -350 450
temp_up: 4EA240AE
1300 -400 1300 -350 450 -1200 1300 -400 1300 -350 1300 -400 450 -1200 450 -1250 450 -1200 450 -1250 1300 -350 1300
temp_down: 1D2FEFF6
1300 -400 1300 -350 450 -1250 1300 -350 1300 -350 500 -1200 1300 -350 500 -1200 450 -1200 500 -1200 450 -1200 450
mode: 39D41DC6
1300 -350 1300 -400 450 -1200 1300 -350 1300 -400 450 -1200 500 -1200 1300 -350 500 -1200 450 -1200 450 -1250 450
air_flow: E0984BB6
1300 -400 1300 -350 500 -1200 1300 -350 1300 -400 450 -1200 450 -1250 450 -1200 1300 -350 500 -1200 450 -1200 500

```

This is the sketch I'm trying to use to transmit data (just a modified version of the send raw demo from the library). Note that I also tried with only 23 items in the array (as originally recorded), but that made no difference:

```
#include <IRremote.h>

IRsend irsend;

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

}

void loop() {
  int khz = 38; // 38kHz carrier frequency for the NEC protocol
  Serial.println("Sending power");
  unsigned int irSignal[] = {1300,350, 1300,350, 500,1200, 1300,350, 1300,400, 1300,350, 450,1250, 450,1200, 450,1200, 1300,400, 1300,350, 500, 1200};
  irsend.sendRaw(irSignal, 24, khz); //Note the approach used to automatically calculate the size of the array.

  delay(1000); //In this example, the signal will be repeated every 5 seconds, approximately.
}

```

**EDIT** to show that I seem to be able to replicate the real signal.

In the following output from the IRecvDump2 example, the top two signal dumps are from the real remote and the bottom two are from my RPi sending the recorded signal. They're very slightly different, but seem (to me) to be within the variation of the recording of the true signal anyway.

What else could I be missing? Could there be some brightness threshold such that even holding the Pi directly up to (i.e. touching) the fan receiver wouldn't work? Some other sort of wake-up signal that for whatever reason the Arduino isn't recording/receiving?

```
Encoding  : UNKNOWN
Code      : 4E87E0AB (32 bits)
Timing[23]:
     +1300, - 400     +1300, - 350     + 450, -1200     +1350, - 350
     +1300, - 350     +1300, - 400     + 450, -1200     + 500, -1200
     + 450, -1200     +1300, - 400     +1250, - 400     + 450
unsigned int  rawData[23] = {1300,400, 1300,350, 450,1200, 1350,350, 1300,350, 1300,400, 450,1200, 500,1200, 450,1200, 1300,400, 1250,400, 450};  // UNKNOWN 4E87E0AB

Encoding  : UNKNOWN
Code      : 4E87E0AB (32 bits)
Timing[23]:
     +1300, - 400     +1300, - 350     + 450, -1250     +1300, - 350
     +1300, - 400     +1300, - 350     + 450, -1200     + 500, -1200
     + 450, -1200     +1300, - 400     +1300, - 350     + 450
unsigned int  rawData[23] = {1300,400, 1300,350, 450,1250, 1300,350, 1300,400, 1300,350, 450,1200, 500,1200, 450,1200, 1300,400, 1300,350, 450};  // UNKNOWN 4E87E0AB

Encoding  : UNKNOWN
Code      : 4E87E0AB (32 bits)
Timing[23]:
     +1350, - 350     +1300, - 350     + 450, -1200     +1300, - 350
     +1300, - 350     +1300, - 400     + 450, -1200     + 450, -1200
     + 450, -1200     +1350, - 350     +1300, - 350     + 450
unsigned int  rawData[23] = {1350,350, 1300,350, 450,1200, 1300,350, 1300,350, 1300,400, 450,1200, 450,1200, 450,1200, 1350,350, 1300,350, 450};  // UNKNOWN 4E87E0AB

Encoding  : UNKNOWN
Code      : 4E87E0AB (32 bits)
Timing[23]:
     +1350, - 300     +1350, - 350     + 450, -1200     +1300, - 350
     +1300, - 350     +1350, - 350     + 450, -1200     + 450, -1200
     + 450, -1200     +1300, - 350     +1350, - 350     + 450
unsigned int  rawData[23] = {1350,300, 1350,350, 450,1200, 1300,350, 1300,350, 1350,350, 450,1200, 450,1200, 450,1200, 1300,350, 1350,350, 450};  // UNKNOWN 4E87E0AB

```

# Answer
> -1 votes
Interesting question with a lot of paths. I know nothing about your controller but in working with IR remotes in the past I found almost all IR remotes use the infrared frequency range (300 GHz - 400 GHz). This range should not be confused with the modulation rate (carrier frequency) of the remote control. The remote control codes are sent to the receiver using the modulation rate. The modulation rate for the remotes and set top boxes is between 36 kHz and 60 kHz, typically 36 kHz to 39kHz. Try this link it may be a bit redundant but it may help. http://www.pehratek.com/documents/FAQ-Infrared-Light-Control.pdf

---
Tags: arduino-uno, infrared
---


# Question
Title: Can I connect an SD card shield to Digispark ATtiny85 board?
I have a Digispark ATtiny85 Arduino board (as shown in the picture). Can I connect a SD card shield to this board as a normal Arduino? How can I do that I'm new to this field?

# Answer
In short I am going to say NO.

The flash is too small to adequately run the SD library as well as the rest of your Arduino code.

The RAM is also underpowered for what is needed to properly access files on an SD card.

Having said this, I am sure there are some clever software engineers that could write a cut down SD card library to do limited commands. Overall this is too hard for the beginner - Just buy an Arduino Uno/Mega/Due and avoid the unnecessary hassle.
> 2 votes

# Answer
Yes you can connect it: http://elm-chan.org/fsw/ff/00index\_p.html Your happiness depends on what you want to accomplish. Simple streaming, like feeding an FPGA with a bitstream is achievable. Logging an incoming data stream to the SD card filesystem is probably not.
> 4 votes

# Answer
```
#include <SPI.h>
#include <SD.h>

File file;
int const pinCS = 2;

void setup()

{
SD.begin(pinCS);
file = SD.open("Test.txt", FILE_WRITE);
file.println("anything");
file.close();}

void loop()
{}

```

This Arduino(ATmega) code creates to SD card a file "Test.txt" and records there a text "anything".

Dear Arduino experts, pls kindly, let me ask you, rewrite this code to ATtiny85. It can helps to many Arduino hobby men. Josef
> 2 votes

---
Tags: attiny, sd-card, digispark
---


# Question
Title: Arduino boards are not working with powerbanks!
I have used many Arduino boards with adapters and other power supplies. While connecting with a powerbank for portable projects I have noticed that the power goes off after a couple of seconds and then turn on again after sometimes. Why this is happening with power bank?
I have used following powerbanks:

1. Basus
2. Xiaomi

# Answer
Most USB powerbanks will automatically turn off if there is not a minimum current draw to keep them turned on. The Arduino is obviously drawing current below the limit for the devices you have.

A couple of options:

1. Add some additional load to keep the powerbank on indefinitely. Of course this may waste power but that's part of the price to pay.
2. Find a power bank that is less sophisticated. I have one with a manual on/off switch. It powers the Arduino just fine until it runs out of power.
3. Find a different powerbank that has a lower threshold for staying on. Some vendors give you this spec and others don't.
4. Modify the powerbank to stay on. I'm not sure there is a general way to do this but you might experiment with it and see.
> 2 votes

---
Tags: arduino-uno, arduino-nano, power, oled
---


title: Record data to SD card with ATtiny85

text:
# Question
Title: Record data to SD card with ATtiny85
An application of ATtiny with SD card is complicated due to missing of hardware SPI in attiny. The "ATmega" code for creating of a "SD file" is:

```
#include <SPI.h>
#include <SD.h>

File file;
int const pinCS = 2;

void setup()

{
SD.begin(pinCS);
file = SD.open("Test.txt", FILE_WRITE);
file.println("anything");
file.close();}

void loop()
{}

```

This code creates on SD card a file "Test.txt" and to this file records text "anathing". Is it possible to rewrite this code for "ATtiny85"?

# Answer
> 2 votes
The ATtiny85 has no dedicated SPI port. It has, however, an “USI” port (Universal Serial Interface) that should be able to do the job. The lack of SPI should not be a problem, but the lack of memory *will* be a problem.

Files on an SD card are written one sector (512 bytes) at a time. For this reason, the SD library uses a 512 bytes buffer in RAM. That cannot work on an ATtiny85, as the buffer would consume the whole RAM.

You may be able to do something using the Petit FAT library, provided you can work around the severe limitations of its write interface:

> The write function has some restrictions listed below:
>
> * Cannot create file. Only existing file can be written.
> * Cannot expand file size.
> * Cannot update time stamp of the file.
> * Write operation can start/stop on the sector boundary only.
> * Read-only attribute of the file cannot block write operation.

The first two points imply that you would have to create the file and allocate the sectors for it in your computer.

This blog post mentions a port of the library to the Arduino environment, and its use on an ATtiny84, which has similar capabilities to the ATtiny85 (only with more pins).

---
Tags: sd-card, attiny
---


title: System crash after using sprintf

text:
# Question
Title: System crash after using sprintf
My Arduino crashes after using sprintf, To reduce system ram am trying to move away from strings to char and now this happened. Loop not working properly and it's not going to webrequest, spent 2 days to find a solution nothing worked yet. My project is to send temp and humidly to my server i was using strings and after one day of use system very slow to send data to server then i realized stings are the culprit then i changed to char

```
char ventionoroff[6];

char Foggeronoroff[6] ;

char Exhuastonoroff[6] = "OFF";

char current[4];

char today[10];

bool running = false;
bool isFoggerRunning = false;
bool isExhaustFanRunning = false;

Time t;

void loop() {

 t = rtc.getTime();

  hum = dht.readHumidity();
  temp = dht.readTemperature();
  delay(1000);

  if (isnan(hum) || isnan(temp)) {
    Serial.println(F("Failed to read from DHT sensor!"));
    return;
  }
  val = digitalRead(powerStatus);

      byte MIN = t.hour;
      byte SEC = t.min;

  char timeStamp[20];
 snprintf(today, "%02d:%02d",  MIN, SEC);

   Serial.println(today);

if (millis() - lastConnectionTime > postingInterval) {
   Serial.println("reaching here2");
    httpRequest();
  }

  if (val)
  snprintf( current , "YES");

  else
 snprintf( current , "NO");

  if (running == false) {
    snprintf( Foggeronoroff , "WAIT");

  } else {
   snprintf( Foggeronoroff , "READY");

  }

    ventilationfan();

void httpRequest() {
Serial.println("shit reached here");
  client.stop();
  char data[10];
  const char phpScript[21]  = "";
  const char server[20]  =  ""; // also change the Host line in httpRequest()

   char strt[6];
   char str[6];
  sprintf(strt, "te=%d", temp);
  strcpy(data, strt);
  strcat (data,"&ti=");
  strcat (data,today);
   strcat (data,"&mot=");
   strcat (data,ventionoroff);
   strcat (data,",");
   strcat (data,Foggeronoroff);
    strcat (data,",");
    strcat (data,current);
     strcat (data,"&mo=");
     strcat (data,Exhuastonoroff);
      sprintf(str, "&hum=%d",hum);
      strcat (data,str);

 Serial.println(data);
   int len = strlen(data);
  if (client.connect(server, 80)) {
    client.print("POST ");
    client.print(phpScript);
    client.println(" HTTP/1.1");
    client.println("Host:");
    client.println("User-Agent: Arduino/1.0");
    client.println("Connection: close");
    client.println("Content-Type: application/x-www-form-urlencoded; charset=UTF-8");
    client.print("Content-Length: ");
    client.println(len);
    client.println();
    client.print(data);
    restartnet = 0;
     data[0] = 0;
     Serial.print("data after sucessfull connection");
     Serial.println(data);
     Serial.print("freeMemory after connection");
     Serial.println(freeMemory());
    lastConnectionTime = millis();

  } else {

     Serial.println(F("Failed"));
     data[0] = 0;

  }
}

```

# Answer
There are quite a few points that could be improved in this code. The main ones have already been shown in the comments:

1. the `data` buffer was not large enough to hold the whole string, which leads to a buffer overflow, memory corruption and, ultimately, the crash you are experiencing.
2. The second parameter to `snprintf()` should be the size of the provided buffer.

Here I will add a few points that, although not really defects of this program, could help improved it and save memory.

Here:

```
char current[4];
// ...
if (val)
    snprintf(current, "YES");
else
    snprintf(current, "NO");

```

you are not using the `current` buffer to build a string, but only to store one of two pre-existing strings (the literals `"YES"` and `"NO"`) that are already stored in memory. Rather than making a copy, you could instead reuse those pre-existing strings, and have `current` be a pointer to the relevant one:

```
const char *current;
// ...
if (val)
    current = "YES";
else
    current = "NO";

```

This only saves two bytes (size of the buffer minus size of the pointer), but this pattern happens multiple times in the program, and the savings add up.

Now, another small optimization. Here:

```
char strt[6];
sprintf(strt, "te=%d", temp);
strcpy(data, strt);

```

you do not need the extra `strt` buffer, as you can write directly into the `data` buffer. Better yet, you can write *everything* into the buffer in a single call to `snprintf()`:

```
snprintf(data, sizeof data,
        "te=%d&ti=%02d:%02d&mot=%s,%s,%s&mo=%s&hum=%d",
        temp, t.hour, t.min, ventionoroff, Foggeronoroff, current,
        Exhuastonoroff, hum);

```

If you don't like this approach, and would prefer writing the data in separate calls to `snprintf()`, you can do so without using auxiliary buffers. You have to remember (with a pointer) where within the buffer you finished your previous write, and pass this address to the next `snprintf()` call. Note that you also have to keep track of the room that is still available, which is easy to do with a second pointer that points to the end of the buffer:

```
char *p = data;                  // current writing position
char *end = data + sizeof data;  // end of the buffer
p += snprintf(p, end - p, "te=%d", temp);
p += snprintf(p, end - p, "&ti=%s", today);
// ...

```
> 4 votes

---
Tags: arduino-uno
---


# Question
Title: Alternative IDE for compiling and running arduino code?
I am not super experienced with c++ and I know that the syntax for C++ and the code written/compiled by the arduino IDE are slightly different.

---

I would like to be able to write code, compile it the same way the arduino IDE does, and run it, without uploading it to a board.

---

I dont need to test any code that interacts with any hardware. I simply want to be able to test basic syntax to make sure my concepts work before integrating with the full program.

I have written a few Arduino programs and I think the most complicated thing I've used were pointer functions, but I'd like to be able to test out code without needing to upload to a board for every change, while relying on Serial.print.

I have found alternatives that help with debugging and although that is helpful, I'd like to avoid the need to upload to a board every time I want to test changes for basic concepts

# Answer
> 2 votes
You can use any C++ IDE you like, best when bundled with a compiler, for example Code::Blocks. Assuming you're using Windows: A combination of a decent editor like Notepad++ and some good compiler chain like MinGW will do, too. If you absolutely have to you could also use MS Visual Studio, I don't bother.

Then create standard console programs with this `main()`:

```
void setup();
void loop();

int main()
{
    setup();
    for (;;)
    {
        loop();
    }
}

```

And append your hardware-less Arduino code.

# Answer
> 2 votes
PlatformIO is a plugin for Visual Studio Code that has support for many embedded device, including most Arduinos

---
Tags: c++, ide
---


title: Trouble with ESP8266 on Eero network

text:
# Question
Title: Trouble with ESP8266 on Eero network
I have an ESP8266 Node MCU and am learning to use its wifi capabilities. In my home I have a router provided by my ISP that runs a network we'll call 'network1'. I also have an Eero mesh network that runs in the house, called 'network2'.

When I upload the following minimal example and use network1,

1. my 8266 device connects to network1 (the messages in the serial monitor confirm this) and
2. I can use my phone and laptop to connect to the 8266 - i.e., I can put the IP into my browser and see a webpage telling me 'Hello World'.

However, I have trouble with network2, the Eero network.

1. I *can* connect my 8266 device to network2 (the messages in the serial monitor confirm this) but
2. I can't connect to the 8266 device with my phone/laptop. (Yes, I switch these over to network2 first.) I put the new IP into my browser and I am told the page is taking too long to respond.

I haven't done anything special with my network1 router; things just worked. With network2, I've tried various settings with my Eero - given the 8266 a static IP address, enabled port forwarding (on port 80) and established a firewall rule for it, but nothing works.

I can run many different programs through network1, and nothing works on the Eero network. Any suggestions on getting things to work?

My minimal working example:

```
#include <ESP8266WiFi.h>

const char* ssid = "network1"; // or 'network2'
const char* password = "thepassword"; // real password used in code

WiFiServer server(80); //just pick any port number you like

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

  // Connect to WiFi network
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

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

  Serial.println("");
  Serial.println("WiFi connected");

  // Start the server
  server.begin();
  Serial.println("Server started");

  // Print the IP address
  Serial.println(WiFi.localIP());
  //gateway = WiFi.gatewayIP();
  Serial.print("GATEWAY: ");
  Serial.println(WiFi.gatewayIP());

  // print your subnet mask:
  //subnet = WiFi.subnetMask();
  Serial.print("NETMASK: ");
  Serial.println(WiFi.subnetMask());
}

void loop() {
  // Check if a client has connected
  WiFiClient client = server.available();
  if (!client) {
    return;
  }

  // Prepare the response
  String s = "HTTP/1.1 200 OK\r\n";
  s += "Content-Type: text/html\r\n\r\n";
  s += "<!DOCTYPE HTML>\r\n<html>\r\n";
  s += "<head>\r\n";
  s+= "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\r\n";
  s+= "<title>ESP Web Server</title>\r\n";
  s+= "</head>\r\n";
  s += "Hello World";
  s += "</html>\n";

  client.flush();

  // Send the response to the client
  client.print(s);
  delay(1);
}

```

# Answer
I was able to find an answer though I'm not sure *why* it works. It comes down to adding `WiFi.mode(WIFI_STA);` in the setup, as in

```
void setup() {

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  ...
  }

```

I was able to replicate success with another file on my ESP8266 device and Eero network as well.
> 1 votes

---
Tags: esp8266, network
---


title: Multitasking with Arduino?

text:
# Question
Title: Multitasking with Arduino?
I am making a Christmas Tree with Arduino. I found a 12 led chaser code on internet so I made 12 rows of leds and hook them up to my Arduino pro mini. They are working just fine.

However, I also want to add music with piezo buzzer while running the LEDs. Is that possible somehow or should I use another microcontroller for piezo? I also used pin 10 for piezo buzzer and used pin 14(a0) for led assigned for pin 10 previously..

Here are the codes: 12 led chaser

```
#define t   30
#define t1  20
#define t2  100
#define t3  50

void setup() {
  // set up pins 2 to 13 as outputs
  for (int i = 2; i <= 13; i++) {
    pinMode(i, OUTPUT);
  }
}
/////////////////////////////////////////////////////////////////////////////////Effect 1
void loop(){

effect_1();
effect_1();

 effect_2();
 effect_2();

 effect_3();
 effect_3();

 effect_4();
 effect_4();

 effect_5();
 effect_5();

 effect_6();
 effect_6();

 effect_7();
 effect_7();
  }
//left to right and right to left
void effect_1()
{
for(int i=2; i<14; i++){
digitalWrite(i, HIGH);
delay(t1);
digitalWrite(i+1, HIGH);
delay(t1);
digitalWrite(i+2, HIGH);
delay(t1);
digitalWrite(i, LOW);
delay(t1);
digitalWrite(i+1, LOW);
delay(t1);
}
for(int i=13; i>1; i--){
digitalWrite(i, HIGH);
delay(t1);
digitalWrite(i-1, HIGH);
delay(t1);
digitalWrite(i-2, HIGH);
delay(t1);
digitalWrite(i, LOW);
delay(t1);
digitalWrite(i-1, LOW);
delay(t1);
}
}
/////////////////////////////////////////////////////////////////////////////////Effect 2
void effect_2()
{
int count = 13; // keeps track of second LED movement

  // move first LED from left to right and second from right to left
  for (int i = 2; i < 13; i++) {
    clear();
    digitalWrite(i, HIGH);      // chaser 1
    digitalWrite(count, HIGH); // chaser 2
    count--;
    // stop LEDs from appearing to stand still in the middle
    if (count != 7) {
      delay(t2);
    }
  }

  // move first LED from right to left and second LED from left to right
  for (int i = 13; i > 2; i--) {
    clear();
    digitalWrite(i, HIGH);      // chaser 1
    digitalWrite(count, HIGH); // chaser 2
    count++;
    // stop LEDs from appearing to stand still in the middle
    if (count != 8) {
      delay(t2);
    }
  }
}

////////////////////////////////////////////////////////////////////////////////Effect 3

void effect_3()
{
for(int i=2; i<14; i++){
  digitalWrite(i, HIGH);
  delay(t3);
}
for(int i=2; i<14; i++){
  digitalWrite(i, LOW);
  delay(t3);
}

for(int i = 14; i>=2; i--){
  digitalWrite(i, HIGH);
  delay(t3);
}
for(int i = 14; i>=2; i--){
  digitalWrite(i, LOW);
  delay(t3);
}
}
  ///////////////////////////////////////////////////////////////////////////Effect 4
void effect_4()
{
for(int j = 2; j <= 13; j++){
  digitalWrite(j, HIGH);
  delay(t2);
  j=j+1;
  }
for(int j = 2; j <= 13; j++){
  digitalWrite(j, LOW);
  delay(t2);
  }

  for(int k = 15; k > 2; k--){
  digitalWrite(k, HIGH);
  delay(t2);
  k=k-1;
  }
for(int k = 15; k > 2; k--){
  digitalWrite(k, LOW);
  delay(t2);
  }
}
//////////////////////////////////////////////////////////////////////////////Effect 5
  void effect_5()
{
 for(int pin = 13; pin >= 2; pin--)
  {
  digitalWrite(pin, HIGH);
  delay(t1);
  digitalWrite(pin+1, LOW);
  delay(t1);
  }
  for(int pin = 13; pin >= 2; pin--)
  {
  digitalWrite(pin+1, HIGH);
  delay(t1);
  digitalWrite(pin+2, LOW);
  delay(t1);
  }
  for(int pin = 13; pin >= 2; pin--)
  {
  digitalWrite(pin+2, HIGH);
  delay(t1);
  digitalWrite(pin+3, LOW);
  delay(t1);
  }
  for(int pin = 13; pin >= 2; pin--)
  {
  digitalWrite(pin+3, HIGH);
  delay(t1);
  digitalWrite(pin+4, LOW);
  delay(t1);
  }
    for(int pin = 13; pin >= 2; pin--)
  {
  digitalWrite(pin+4, HIGH);
  delay(t1);
  digitalWrite(pin+5, LOW);
  delay(t1);
  }
  for(int pin = 13; pin >= 2; pin--)
  {
  digitalWrite(pin+5, HIGH);
  delay(t1);
  digitalWrite(pin+6, LOW);
  delay(t1);
  }
  for(int pin = 13; pin >= 2; pin--)
  {
  digitalWrite(pin+6, HIGH);
  delay(t1);
  digitalWrite(pin+7, LOW);
  delay(t1);
  }
   for(int pin = 13; pin >= 2; pin--)
  {
  digitalWrite(pin+7, HIGH);
  delay(t1);
  digitalWrite(pin+8, LOW);
  delay(t1);
  }
  for(int pin = 9; pin >= 2; pin--)
  {
  digitalWrite(pin+8, HIGH);
  delay(t1);
  digitalWrite(pin+9, LOW);
  delay(t1);
  }
    for(int pin = 9; pin >= 2; pin--)
  {
  digitalWrite(pin+9, HIGH);
  delay(t1);
  digitalWrite(pin+10, LOW);
  delay(t1);
  }
  for(int pin = 9; pin >= 2; pin--)
  {
  digitalWrite(pin+10, HIGH);
  delay(t1);
  digitalWrite(pin+11, LOW);
  delay(t1);
  }
  for(int pin = 14; pin >= 2; pin--)
  {
  digitalWrite(pin+11, HIGH);
  delay(t1);
  }
  for(int pin = 13; pin >= 2; pin--)
  {
    digitalWrite(pin, LOW);
  delay(t1);
    }
  }
  /////////////////////////////////////////////////////////////////////////////Effect 6
void effect_6()
{
for(int j=2; j<14; j++){
  digitalWrite(j, LOW);
  delay(t);
  digitalWrite(j, HIGH);
  delay(t);
  digitalWrite(j-2, LOW);
  delay(t);
  digitalWrite(j, HIGH);
}
for(int k = 15; k>2; k--){
  digitalWrite(k, LOW);
  delay(t);
  digitalWrite(k, HIGH);
  delay(t);
  digitalWrite(k+2, LOW);
  delay(t);
  digitalWrite(k, HIGH);
}
for(int k = 2; k<14; k++){
  digitalWrite(k, LOW);
  delay(t);
  digitalWrite(k, HIGH);
  delay(t);
  digitalWrite(k-2, LOW);
  delay(t);
  digitalWrite(k, HIGH);
}
for(int k = 15; k>2; k--){
  digitalWrite(k, LOW);
  delay(t);
  digitalWrite(k, HIGH);
  delay(t);
  digitalWrite(k+4, LOW);
  delay(t);
  digitalWrite(k, HIGH);
}
for(int k = 2; k<14; k++){
  digitalWrite(k, LOW);
  delay(t);
  digitalWrite(k, HIGH);
  delay(t);
  digitalWrite(k-4, LOW);
  delay(t);
  digitalWrite(k, HIGH);
}
}
///////////////////////////////////////////////////////////////////////////////////Effect 7
void effect_7()
{
for(int j=2; j<14; j++){
  digitalWrite(j, HIGH);
  delay(t);
  digitalWrite(j+2, LOW);
  delay(t);
}
for(int k = 15; k>2; k--){
  digitalWrite(k, HIGH);
  delay(t);
  digitalWrite(k+2, LOW);
  delay(t);
}
}

// function to switch all LEDs off
void clear(void)
{
  for (int i = 2; i <= 13; i++) {
    digitalWrite(i, LOW);
  }
}

```

Melody tone for buzzer:

```
/*
  We Wish You a Merry Christmas - Traditional Christmas song
  Connect a piezo buzzer or speaker to pin 11 or select a new pin.
  More songs available at https://github.com/robsoncouto/arduino-songs

                                              Robson Couto, 2019
*/
#define NOTE_B0  31
#define NOTE_C1  33
#define NOTE_CS1 35
#define NOTE_D1  37
#define NOTE_DS1 39
#define NOTE_E1  41
#define NOTE_F1  44
#define NOTE_FS1 46
#define NOTE_G1  49
#define NOTE_GS1 52
#define NOTE_A1  55
#define NOTE_AS1 58
#define NOTE_B1  62
#define NOTE_C2  65
#define NOTE_CS2 69
#define NOTE_D2  73
#define NOTE_DS2 78
#define NOTE_E2  82
#define NOTE_F2  87
#define NOTE_FS2 93
#define NOTE_G2  98
#define NOTE_GS2 104
#define NOTE_A2  110
#define NOTE_AS2 117
#define NOTE_B2  123
#define NOTE_C3  131
#define NOTE_CS3 139
#define NOTE_D3  147
#define NOTE_DS3 156
#define NOTE_E3  165
#define NOTE_F3  175
#define NOTE_FS3 185
#define NOTE_G3  196
#define NOTE_GS3 208
#define NOTE_A3  220
#define NOTE_AS3 233
#define NOTE_B3  247
#define NOTE_C4  262
#define NOTE_CS4 277
#define NOTE_D4  294
#define NOTE_DS4 311
#define NOTE_E4  330
#define NOTE_F4  349
#define NOTE_FS4 370
#define NOTE_G4  392
#define NOTE_GS4 415
#define NOTE_A4  440
#define NOTE_AS4 466
#define NOTE_B4  494
#define NOTE_C5  523
#define NOTE_CS5 554
#define NOTE_D5  587
#define NOTE_DS5 622
#define NOTE_E5  659
#define NOTE_F5  698
#define NOTE_FS5 740
#define NOTE_G5  784
#define NOTE_GS5 831
#define NOTE_A5  880
#define NOTE_AS5 932
#define NOTE_B5  988
#define NOTE_C6  1047
#define NOTE_CS6 1109
#define NOTE_D6  1175
#define NOTE_DS6 1245
#define NOTE_E6  1319
#define NOTE_F6  1397
#define NOTE_FS6 1480
#define NOTE_G6  1568
#define NOTE_GS6 1661
#define NOTE_A6  1760
#define NOTE_AS6 1865
#define NOTE_B6  1976
#define NOTE_C7  2093
#define NOTE_CS7 2217
#define NOTE_D7  2349
#define NOTE_DS7 2489
#define NOTE_E7  2637
#define NOTE_F7  2794
#define NOTE_FS7 2960
#define NOTE_G7  3136
#define NOTE_GS7 3322
#define NOTE_A7  3520
#define NOTE_AS7 3729
#define NOTE_B7  3951
#define NOTE_C8  4186
#define NOTE_CS8 4435
#define NOTE_D8  4699
#define NOTE_DS8 4978
#define REST      0

// change this to make the song slower or faster
int tempo = 140;

// change this to whichever pin you want to use
int buzzer = 11;

// notes of the moledy followed by the duration.
// a 4 means a quarter note, 8 an eighteenth , 16 sixteenth, so on
// !!negative numbers are used to represent dotted notes,
// so -4 means a dotted quarter note, that is, a quarter plus an eighteenth!!
int melody[] = {

  // We Wish You a Merry Christmas
  // Score available at https://musescore.com/user/6208766/scores/1497501

  NOTE_C5,4, //1
  NOTE_F5,4, NOTE_F5,8, NOTE_G5,8, NOTE_F5,8, NOTE_E5,8,
  NOTE_D5,4, NOTE_D5,4, NOTE_D5,4,
  NOTE_G5,4, NOTE_G5,8, NOTE_A5,8, NOTE_G5,8, NOTE_F5,8,
  NOTE_E5,4, NOTE_C5,4, NOTE_C5,4,
  NOTE_A5,4, NOTE_A5,8, NOTE_AS5,8, NOTE_A5,8, NOTE_G5,8,
  NOTE_F5,4, NOTE_D5,4, NOTE_C5,8, NOTE_C5,8,
  NOTE_D5,4, NOTE_G5,4, NOTE_E5,4,

  NOTE_F5,2, NOTE_C5,4, //8
  NOTE_F5,4, NOTE_F5,8, NOTE_G5,8, NOTE_F5,8, NOTE_E5,8,
  NOTE_D5,4, NOTE_D5,4, NOTE_D5,4,
  NOTE_G5,4, NOTE_G5,8, NOTE_A5,8, NOTE_G5,8, NOTE_F5,8,
  NOTE_E5,4, NOTE_C5,4, NOTE_C5,4,
  NOTE_A5,4, NOTE_A5,8, NOTE_AS5,8, NOTE_A5,8, NOTE_G5,8,
  NOTE_F5,4, NOTE_D5,4, NOTE_C5,8, NOTE_C5,8,
  NOTE_D5,4, NOTE_G5,4, NOTE_E5,4,
  NOTE_F5,2, NOTE_C5,4,

  NOTE_F5,4, NOTE_F5,4, NOTE_F5,4,//17
  NOTE_E5,2, NOTE_E5,4,
  NOTE_F5,4, NOTE_E5,4, NOTE_D5,4,
  NOTE_C5,2, NOTE_A5,4,
  NOTE_AS5,4, NOTE_A5,4, NOTE_G5,4,
  NOTE_C6,4, NOTE_C5,4, NOTE_C5,8, NOTE_C5,8,
  NOTE_D5,4, NOTE_G5,4, NOTE_E5,4,
  NOTE_F5,2, NOTE_C5,4,
  NOTE_F5,4, NOTE_F5,8, NOTE_G5,8, NOTE_F5,8, NOTE_E5,8,
  NOTE_D5,4, NOTE_D5,4, NOTE_D5,4,

  NOTE_G5,4, NOTE_G5,8, NOTE_A5,8, NOTE_G5,8, NOTE_F5,8, //27
  NOTE_E5,4, NOTE_C5,4, NOTE_C5,4,
  NOTE_A5,4, NOTE_A5,8, NOTE_AS5,8, NOTE_A5,8, NOTE_G5,8,
  NOTE_F5,4, NOTE_D5,4, NOTE_C5,8, NOTE_C5,8,
  NOTE_D5,4, NOTE_G5,4, NOTE_E5,4,
  NOTE_F5,2, NOTE_C5,4,
  NOTE_F5,4, NOTE_F5,4, NOTE_F5,4,
  NOTE_E5,2, NOTE_E5,4,
  NOTE_F5,4, NOTE_E5,4, NOTE_D5,4,

  NOTE_C5,2, NOTE_A5,4,//36
  NOTE_AS5,4, NOTE_A5,4, NOTE_G5,4,
  NOTE_C6,4, NOTE_C5,4, NOTE_C5,8, NOTE_C5,8,
  NOTE_D5,4, NOTE_G5,4, NOTE_E5,4,
  NOTE_F5,2, NOTE_C5,4,
  NOTE_F5,4, NOTE_F5,8, NOTE_G5,8, NOTE_F5,8, NOTE_E5,8,
  NOTE_D5,4, NOTE_D5,4, NOTE_D5,4,
  NOTE_G5,4, NOTE_G5,8, NOTE_A5,8, NOTE_G5,8, NOTE_F5,8,
  NOTE_E5,4, NOTE_C5,4, NOTE_C5,4,

  NOTE_A5,4, NOTE_A5,8, NOTE_AS5,8, NOTE_A5,8, NOTE_G5,8,//45
  NOTE_F5,4, NOTE_D5,4, NOTE_C5,8, NOTE_C5,8,
  NOTE_D5,4, NOTE_G5,4, NOTE_E5,4,
  NOTE_F5,2, NOTE_C5,4,
  NOTE_F5,4, NOTE_F5,8, NOTE_G5,8, NOTE_F5,8, NOTE_E5,8,
  NOTE_D5,4, NOTE_D5,4, NOTE_D5,4,
  NOTE_G5,4, NOTE_G5,8, NOTE_A5,8, NOTE_G5,8, NOTE_F5,8,
  NOTE_E5,4, NOTE_C5,4, NOTE_C5,4,

  NOTE_A5,4, NOTE_A5,8, NOTE_AS5,8, NOTE_A5,8, NOTE_G5,8, //53
  NOTE_F5,4, NOTE_D5,4, NOTE_C5,8, NOTE_C5,8,
  NOTE_D5,4, NOTE_G5,4, NOTE_E5,4,
  NOTE_F5,2, REST,4
};

// sizeof gives the number of bytes, each int value is composed of two bytes (16 bits)
// there are two values per note (pitch and duration), so for each note there are four bytes
int notes = sizeof(melody) / sizeof(melody[0]) / 2;

// this calculates the duration of a whole note in ms
int wholenote = (60000 * 4) / tempo;

int divider = 0, noteDuration = 0;

void setup() {
  // iterate over the notes of the melody.
  // Remember, the array is twice the number of notes (notes + durations)
  for (int thisNote = 0; thisNote < notes * 2; thisNote = thisNote + 2) {

    // calculates the duration of each note
    divider = melody[thisNote + 1];
    if (divider > 0) {
      // regular note, just proceed
      noteDuration = (wholenote) / divider;
    } else if (divider < 0) {
      // dotted notes are represented with negative durations!!
      noteDuration = (wholenote) / abs(divider);
      noteDuration *= 1.5; // increases the duration in half for dotted notes
    }

    // we only play the note for 90% of the duration, leaving 10% as a pause
    tone(buzzer, melody[thisNote], noteDuration * 0.9);

    // Wait for the specief duration before playing the next note.
    delay(noteDuration);

    // stop the waveform generation before the next note.
    noTone(buzzer);
  }
}

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

```

# Answer
> 0 votes
I think the method suggested by chrisl is probably the best for you to use here. If you want to make a more-conventional multitasking system, you would set a timer such as TIMER2 to the minimum time slice, then at the start of your code (after setup) you'd have something like this:

ISR(TIMER2\_COMPA\_vect) { myIntHandler(); }

Here myIntHandler() does whatever needs to get done on each tick of TIMER2. I use this general approach in my open-source DaqPort code to do simultaneous oscilloscope data acquisition and signal generation, while still handling serial commands in the background. But that's probably overkill for your project. You can find out more about DaqPort at https://www.daqarta.com/dw\_rraa.htm

---
Tags: led, arduino-pro-mini, piezo
---


# Question
Title: controlling 2 sensor and 3 pump using millis
i make a 3 pump for output and im using millis for it, i want to stop if rach the intervalm now in my code its still looping not realy stop for it thx

```
int pump1 = 5;//pin D5
int pump2 = 6;//pin D6
int pump3 = 7;//pin D7
float pompa1;
float pompa2;
float pompa3;
unsigned long prev_pump1    = 0;
unsigned long prev_pump2    = 0;
unsigned long prev_pump3    = 0;
unsigned long initiate_start = 0;
int pump_state1 = false;
int pump_state2 = false;
int pump_state3 = false;

```

and after this this is my loop program

```
  //-----------PUMP ALGORITHM--------------------
  long int pompa01 = pompa1*1000;//interval pump1
  long int pompa02 = pompa2*1000;//interval pump2
  long int pompa03 = pompa3*1000;//interval pump2

  unsigned long initiate_start = millis();

  //pompa1
  if(intiate_start-prev_pump1 > pompa01)
  {
    pump_state1 = !pump_state1;

    if(pump_state1)
    {
      digitalWrite(pump1, HIGH);
    }
    else
    {
      digitalWrite(pump1, LOW);
    }
    prev_pump1 = initiate_start;
  }

    //pompa2
  if(intiate_start-prev_pump2 > pompa02)
  {
    pump_state2 = !pump_state2;

    if(pump_state2)
    {
      digitalWrite(pump2, HIGH);
    }
    else
    {
      digitalWrite(pump2, LOW);
    }
    prev_pump2 = initiate_start;
  }

    //pompa3
  if(intiate_start-prev_pump3 > pompa03)
  {
    pump_state3 = !pump_state3;

    if(pump_state3)
    {
      digitalWrite(pump3, HIGH);
    }
    else
    {
      digitalWrite(pump3, LOW);
    }
    prev_pump3 = initiate_start;
  }

```

# Answer
> 1 votes
This is meant as a complement to Michel Keijzers' answer. I fully agree with his assessment: code duplication is something to be avoided, as it greatly hurts maintainability. And I sympathise with him feeling the urge to implement this as a proper class. ;-)

I would argue, however, that between the simplistic version of the OP's code, and the fully object-oriented one of that answer, there is an intermediate step that is worth targeting as the next thing to learn. I mean: arrays and loops.

Many cases of code duplication follow a pattern roughly like this:

```
// At the top of the sketch:
some_type data0 = some_value;
some_type data1 = some_other_value;
// etc.

// Within a function:
do_lots_of_stuff(data0);
do_lots_of_stuff(data1);
// etc.

```

where `do_lots_of_stuff()` may be a lot of code, rather than a single function call (and it would indeed not be that bad if it was just a function call).

The simple solution to this kind of code duplication is to put the variables in an array, and process them by looping through the array:

```
// At the top of the sketch:
const int data_count = ...;
some_type[data_count] = {some_value, some_other_value, ...};

// Within a function:
for (int i = 0; i < data_count; i++)
    do_lots_of_stuff(data[i]);

```

Here is my attempt at applying this technique to the OP's code. Note that, since there are multiple variables for each pump, we need multiple arrays:

```
const int pump_count = 3;
const uint8_t pump_pins[pump_count] = {5, 6, 7};
const uint32_t pump_half_periods[pump_count] = {1000, 2500, 3200};

uint8_t pump_states[pump_count];  // LOW or HIGH
uint32_t pump_last_actuations[pump_count];  // time in ms

void setup() {
    for (int i = 0; i < pump_count; i++) {
        pinMode(pump_pins[i], OUTPUT);
    }
}

void loop() {
    unsigned long now = millis();
    for (int i = 0; i < pump_count; i++) {
        if (now - pump_last_actuations[i] >= pump_half_periods[i]) {
            pump_states[i] = (pump_states[i] == HIGH) ? LOW : HIGH;
            digitalWrite(pump_pins[i], pump_states[i]);
            pump_last_actuations[i] = now;
        }
    }
}

```

This removes all the duplication, and should be easier to maintain and debug.

Once one is comfortable with this concept, I would argue the next step in terms of building abstractions would be to bundle together all the data relative to one pump into a `struct`. Then we would have a single array (the elements of which are structs) instead of a collection of arrays:

```
// Data structure describing a pump.
struct Pump {
    const uint8_t pin;
    const uint32_t half_period;  // half period in ms
    uint8_t state;               // LOW or HIGH
    uint32_t last_actuation;     // time in ms
};

const int pump_count = 3;

Pump pumps[pump_count] = {
// pin, half-T, state, last_actuation
    {5, 1000, LOW, 0},
    {6, 2500, LOW, 0},
    {7, 3200, LOW, 0}
};

```

The body of `setup()` and `loop()` would be very similar to the previous version, but with `pump_pins[i]` replaced by `pumps[i].pin` and so on.

The third step in the abstraction ladder would be to embed the code that handles the data structure with the data itself in a `class`, as shown in Michel Keijzers' answer. With the proper methods defined, the main sketch could be reduced to something like this:

```
#include "Pump.h"

Pump pumps[] = {
    Pump(5, 1000),
    Pump(6, 2500),
    Pump(7, 3200)
};

void setup() {
    for (Pump &pump : pumps)
        pump.begin();
}

void loop() {
    for (Pump &pump : pumps)
        pump.process();
}

```

I tried all these methods, and it turns out the first one (with a collection of arrays) is the one that uses the least lines of code, and the last one (with a class) uses the most. One could wonder then why use more advanced abstractions, if they increase the amount of code one has to type. The reason is, these abstractions become useful when the program grows in complexity. On can put together all the code that deals with the pumps in one place (maybe in a separate file), all the code that deals with sensors in another place... and the main sketch that puts all the pieces together remains simple.

# Answer
> 0 votes
Note: this is not an answer (my previous version of the answer contained a problem, thanks Edgar Bonet for notifying and a fix for the remainder of the answer). However, I don't want to remove this answer as it may help in removing a lot of duplication. I took the liberty to convert it into a class.

It compiles, but I can't check the functionality but hopefully it helps you to continue. If there are problems, use write commands to send text to the serial to check the times and state.

Sketch:

```
#include  "Pump.h"

const int NR_OF_PUMPS = 3;

Pump pumps[NR_OF_PUMPS] =
{
  Pump(5, 1.0),
  Pump(6, 2.5),
  Pump(7, 3.2)
};

void setup()
{
}

void loop()
{
  process();
}

void process()
{
  for (int pumpIndex = 0; pumpIndex < NR_OF_PUMPS; pumpIndex++)
  {
    pumps[pumpIndex].Process(millis());
  }
}

```

Pump.h:

```
class Pump
{
public:
  Pump::Pump(int pin, float interval);
  void Process(uint32_t currentTime);

private:
  int _pin;
  float _interval;
  uint32_t _prevTime;
  bool _state;
};

```

Pump.cpp:

```
#include "Arduino.h"
#include "Pump.h"

Pump::Pump(int pin, float interval)
:
  _pin(pin),
  _interval(interval * 1000.0),
  _prevTime(0),
  _state(false)
{
}

void Pump::Process(uint32_t currentTime)
{
  if (currentTime - _prevTime > _interval)
  {
    _state = !_state;
    digitalWrite(_pin, _state ? HIGH : LOW);
    _prevTime = currentTime;
  }
}

```

---
Tags: arduino-mega, relay, millis
---


# Question
Title: Send commands from cPanel website to client ESP8266
I have a project where I want to remotely turn on and off a relay using an Arduino,(ESP8266) over the internet.

1. I have a remote web server that hosts my existing hobby website, cPanel hosted by GoDaddy Sites.
2. An Arduino (ESP8266) connects to this website listening for relay on/off commands.
3. Open a browser and load the webpage dashboard to sent commands to Arduino.

Yes I could have the Arduino poll the website ever so often to check for a value changed in a database, but I don't want to do that, Just seems unethical to me.

I was looking at WebSockets and thought that might be what I'm looking for but I know too little about it or there's not enough relevant documentation online about it to use it in this type of project.

I am looking forward to your comments and answers, but please do not tell me to host the site on the Arduino, and also using an app or other service is not going to work either, We are working with my own webpage and thats it no thirdparty apps, Thanks.

# Answer
I don't believe you will have the capability to implement a Websocket interface on the GoDaddy cPanel web site. I think you are limited to just serving up HTML content and associated files. Websocket requires a server-side resource to talk to which you cannot implement.

I see nothing wrong with having a simple HTML page, that doesn't even need to really contain HTML that your ESP8266 can "GET" and examine and determine to turn your relay on or off.
> 0 votes

---
Tags: wifi, iot, web
---


# Question
Title: Why does Arduino round off some integers but not others when my desktop PC does not do this?
I am writing (in C) some low level digit manipulation routines that convert int to float and vice versa for Arduino. I came across some puzzling behaviour with Arduino rounding some numbers but not others. So I located and extracted the offending code into a simple program which I compiled on desktop Linux PC with GCC and on Arduino - they give different results. Why? Here are the programs. The goal is to take the float number 1.3140 and the float number 2.3140 and split them into two integers. In the first case I expect '1' and '3140' and in the second case I expect '2' and '3140' (the terminal '0' is important for my application). The Arduino code:

```
void setup() {
double dnum,x,y;
uint16_t intpart,fracpart;

Serial.begin(9600);

dnum = 1.3140;

 x=modf(dnum,&y);
 intpart = (uint16_t)y;
 fracpart = (uint16_t)(10000.0*x);

Serial.println(dnum,4);
Serial.println(intpart);
Serial.println(fracpart);

}

```

and the output I get is:

```
1.3140
1
3140

```

Fantastic! Success. But hold on. If I change the hard-coded number to `dnum = 2.3140` I get this:

```
2.3140
2
3139

```

What? Why did it round the second part down? Am I doing something fundamentally wrong? So I wrote a little C program for my PC (compiled with gcc). Here is the code:

```
#include<stdint.h>
#include<stdio.h>
#include<math.h>

int main (int argc, char *argv[])
{
 double dnum,x,y;
 uint16_t intpart,fracpart;

 dnum = 2.3140;

  x=modf(dnum,&y);
  intpart = (uint16_t)y;
  fracpart = (uint16_t)(10000.0*x);

 printf("Int_part = %u\nFrac_Part = %u\n",intpart,fracpart);

 return 0;
}

```

When run I get this result:

```
Int_part = 2
Frac_Part = 3140

```

Now that's what I expect - and to be thorough I also did the above C program with `dnum = 1.3140;` and I again got the 'correct' expected result:

```
Int_part = 1
Frac_Part = 3140

```

So why does the Arduino round the fractional part down when I convert it to an integer sometimes and not others? I tried this on a genuine Arduino Uno, a clone Arduino uno and a clone Arduino nano and all give the same results. In 'theory' it could be some difference in the compiler tolerance to some coding impropriety I have done (gcc is more tolerant) but can anyone tell me what I did wrong and how to get the Arduino to behave (the way I want it to)? Thanks.

# Answer
> 5 votes
When you cast a floating point number to an integer, it always gets rounded towards zero. If you want round-to-nearest behavior, you should use the Arduino `round()` function.

As to the origin of the discrepancy you see, it comes from two facts:

1. The numbers you use are not exactly representable as floating point numbers.
2. The `double` on an Arduino Uno is actually equivalent to a `float` (32 bits only).

When you write a statement such as `dnum = 1.3140;`, the compiler stores in `dnum` the floating point number that is closest to the decimal number `1.3140`.

Compare:

```
float32(1.3140) = 1.31400001049041748046875
float64(1.3140) = 1.31400000000000005684341886080801486968994140625
float32(2.3140) = 2.3139998912811279296875
float64(2.3140) = 2.31400000000000005684341886080801486968994140625

```

Out of these 4 examples, only `float32(2.3140)` is rounded down.

---
Tags: programming, c
---