body:
I want to send HTTP post requests to a server in JSON Format using a SIM900 module. But the code is not posting the data and have an error.Can someone help me to solved the error 1,603,0 since I cannot solve , I already try to use http instead of https cause I read from other QnA channel that AT+HTTPPARA=\"URL can only be read in http .. But nothing happen the error still there. I know the error is about the DNS but I do not know how to solve it.. Sorry it was my first time to use the sim900a

Here is my code:

```cpp
#include <SoftwareSerial.h>
#include <ArduinoJson.h>

SoftwareSerial SIM900(10, 11);
StaticJsonBuffer<200> jsonBuffer;

char t[32];
char deviceID[12] = "TESTING";
char Name[12] = "Irsyad";
char Place[12] = "JB";

void setup()
{
  SIM900.begin(9600);       // the GPRS baud rate
  Serial.begin(9600);
  Serial.println("Initializing..");

  DynamicJsonBuffer jsonBuffer;

}

void loop()
{
  Serial.println("");
  Serial.println("START");

  Serial.print("Device ID: ");
  Serial.println(deviceID);

  delay(1000);

  if (SIM900.available())
  Serial.write(SIM900.read());

  SIM900.println("AT");
  delay(3000);

  SIM900.println("AT+SAPBR=3,1,\"Contype\",\"GPRS\""); // untuk cek  GPRS
  delay(6000);
  ShowSerialData();

  SIM900.println("AT+SAPBR=3,1,\"APN\",\"\"");//APN mobile phone (cek dekat phone)
  delay(6000);
  ShowSerialData();

  SIM900.println("AT+SAPBR=1,1");
  delay(6000);
  ShowSerialData();

  SIM900.println("AT+SAPBR=2,1");
  delay(6000);
  ShowSerialData();

  SIM900.println("AT+HTTPINIT"); // jika keluar error means gagal
  delay(6000);
  ShowSerialData();

  SIM900.println("AT+HTTPPARA=\"CID\",1"); //parameters untuk HTTP session
  delay(6000);
  ShowSerialData();

  StaticJsonBuffer<200> jsonBuffer;
  JsonObject& object = jsonBuffer.createObject();

  object.set("deviceID",deviceID);
  object.set("Name",Name);
  object.set("Place",Place);

  object.printTo(Serial);
  Serial.println(" ");
  String sendtoserver;
  object.prettyPrintTo(sendtoserver);
  delay(4000);

  SIM900.println("AT+HTTPPARA=\"URL\",\"http://gas-api.smartcp.app/api/ttn/uplink\""); //Server address // tukar pakai lain https://
  delay(4000);
  ShowSerialData();

  SIM900.println("AT+HTTPPARA=\"CONTENT\",\"application/json\""); //json format
  delay(4000);
  ShowSerialData();

  SIM900.println("AT+HTTPDATA=" + String(sendtoserver.length()) + ",100000"); // size bytes untuk hantar data dalam masa 10 seconds
  Serial.println(sendtoserver);
  delay(6000);
  ShowSerialData();

  SIM900.println(sendtoserver);
  delay(6000);
  ShowSerialData;

  SIM900.println("AT+HTTPACTION=1"); // Post the data (1 means post)
  delay(6000);
  ShowSerialData();

  SIM900.println("AT+HTTPREAD");
  delay(6000);
  ShowSerialData();

  SIM900.println("AT+HTTPTERM");
  delay(10000);
  ShowSerialData;
}

void ShowSerialData()
{
  while (SIM900.available() != 0)
    Serial.write(SIM900.read());
  delay(1000);

}
```

[![enter image description here][1]][1]

  [1]: https://i.stack.imgur.com/lCuSa.jpg

title: Error 1,603,0 when http post request using arduino and sim900a by Json format

Answers: 0


body:
I have an array of hexadecimal values as given below.

    byte Hexa_Val[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

I want to increase this array from the end. As in, go from {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} all the way to {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF}, and then increase the value next to it to {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00}, and continue. The increment should go as shown below.

    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}
    .
    .
    .
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF}
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00}
    .
    .
    .
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF}
    {0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00}
    .
    .
    .
    {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}

The code I am came up with is

    byte Hexa_Val[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

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

    void loop() {

      Hexa_Val[7] = Hexa_Val[7] + 1;

      if(Hexa_Val[7] = 0xFF){
        Hexa_Val[6] = Hexa_Val[6] + 1;
        Hexa_Val[7] = 0x00;
      }

      if((Hexa_Val[7] = 0xFF) && (Hexa_Val[6] = 0xFF)){
        Hexa_Val[5] = Hexa_Val[5] + 1;
        Hexa_Val[7] = 0x00;
        Hexa_Val[6] = 0x00;
      }

      if((Hexa_Val[7] = 0xFF) && (Hexa_Val[6] = 0xFF) && (Hexa_Val[5] = 0xFF)){
        Hexa_Val[4] = Hexa_Val[4] + 1;
        Hexa_Val[7] = 0x00;
        Hexa_Val[6] = 0x00;
        Hexa_Val[5] = 0x00;
      }

      if((Hexa_Val[7] = 0xFF) && (Hexa_Val[6] = 0xFF) && (Hexa_Val[5] = 0xFF) && (Hexa_Val[4] = 0xFF)){
        Hexa_Val[3] = Hexa_Val[3] + 1;
        Hexa_Val[7] = 0x00;
        Hexa_Val[6] = 0x00;
        Hexa_Val[5] = 0x00;
        Hexa_Val[4] = 0x00;
      }

      if((Hexa_Val[7] = 0xFF) && (Hexa_Val[6] = 0xFF) && (Hexa_Val[5] = 0xFF) && (Hexa_Val[4] = 0xFF) && (Hexa_Val[3] = 0xFF)){
        Hexa_Val[2] = Hexa_Val[2] + 1;
        Hexa_Val[7] = 0x00;
        Hexa_Val[6] = 0x00;
        Hexa_Val[5] = 0x00;
        Hexa_Val[4] = 0x00;
        Hexa_Val[3] = 0x00;
      }

      if((Hexa_Val[7] = 0xFF) && (Hexa_Val[6] = 0xFF) && (Hexa_Val[5] = 0xFF) && (Hexa_Val[4] = 0xFF) && (Hexa_Val[3] = 0xFF) && (Hexa_Val[2] = 0xFF)){
        Hexa_Val[1] = Hexa_Val[1] + 1;
        Hexa_Val[7] = 0x00;
        Hexa_Val[6] = 0x00;
        Hexa_Val[5] = 0x00;
        Hexa_Val[4] = 0x00;
        Hexa_Val[3] = 0x00;
        Hexa_Val[2] = 0x00;
      }

      if((Hexa_Val[7] = 0xFF) && (Hexa_Val[6] = 0xFF) && (Hexa_Val[5] = 0xFF) && (Hexa_Val[4] = 0xFF) && (Hexa_Val[3] = 0xFF) && (Hexa_Val[2] = 0xFF)  && (Hexa_Val[1] = 0xFF)){
        Hexa_Val[0] = Hexa_Val[0] + 1;
        Hexa_Val[7] = 0x00;
        Hexa_Val[6] = 0x00;
        Hexa_Val[5] = 0x00;
        Hexa_Val[4] = 0x00;
        Hexa_Val[3] = 0x00;
        Hexa_Val[2] = 0x00;
        Hexa_Val[1] = 0x00;
      }

      if((Hexa_Val[7] = 0xFF) && (Hexa_Val[6] = 0xFF) && (Hexa_Val[5] = 0xFF) && (Hexa_Val[4] = 0xFF) && (Hexa_Val[3] = 0xFF) && (Hexa_Val[2] = 0xFF) && (Hexa_Val[1] = 0xFF)  && (Hexa_Val[0] = 0xFF)){
        Hexa_Val[7] = 0x00;
        Hexa_Val[6] = 0x00;
        Hexa_Val[5] = 0x00;
        Hexa_Val[4] = 0x00;
        Hexa_Val[3] = 0x00;
        Hexa_Val[2] = 0x00;
        Hexa_Val[1] = 0x00;
        Hexa_Val[0] = 0x00;
      }

      //to find out what I am sending
      for( byte a=0; a<8; a++ ) {
        Serial.print(Hexa_Val[a], HEX);
      }
      Serial.println();

      delay(500);

    }

But it just gives me zeros in the serial monitor. If I just leave the first two IF statements

    byte Hexa_Val[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

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

    void loop() {

      Hexa_Val[7] = Hexa_Val[7] + 1;

      if(Hexa_Val[7] = 0xFF){
        Hexa_Val[6] = Hexa_Val[6] + 1;
        Hexa_Val[7] = 0x00;
      }

      if((Hexa_Val[7] = 0xFF) && (Hexa_Val[6] = 0xFF)){
        Hexa_Val[5] = Hexa_Val[5] + 1;
        Hexa_Val[7] = 0x00;
        Hexa_Val[6] = 0x00;
      }

      //to find out what I am sending
      for( byte a=0; a<8; a++ ) {
        Serial.print(Hexa_Val[a], HEX);
      }
      Serial.println();

      delay(500);

    }

The increment will start from the third value on the right. Something like

    00000200
    00000300
    00000400
    00000500
    00000600
    00000700

How do I get it to increase as I mentioned at the beginning? Why does the code recognize `0xFF` as a zero?

title: Hexadecimal array does not add up as expected

Answers: 1

body:
There are multiple problems here:

> `if(Hexa_Val[7] = 0xFF)`

First of all, `=` is the assignment operator. You are setting
`Hexa_Val[7]` to `0xFF`. If you want to compare for equality, you should
use `==`.

Second problem, The value `0xff` will never be displayed, because you
are replacing it by zero. This byte will then count 0xfd, 0xfe, 0x00,
skipping 0xff. If you want to count 0xff, the condition should be
`Hexa_Val[7] == 0`, i.e. increment `Hexa_Val[6]` only after
`Hexa_Val[7]` has overflowed.

Third problem, your second `if` test comes too late. At this point
`Hexa_Val[7]` has already been reset. You should test for `Hexa_Val[6]`
overflowing only _within_ the previous test.

With all that fixed:

```c++
Hexa_Val[7] = Hexa_Val[7] + 1;
if (Hexa_Val[7] == 0) {
  Hexa_Val[6] = Hexa_Val[6] + 1;
  if (Hexa_Val[6] == 0) {
    Hexa_Val[5] = Hexa_Val[5] + 1;
  }
}
```

If you don't want to write 8 nested conditions (which is kind of
cumbersome), you can instead loop over the array backwards, incrementing
each element in turn, and break out of the loop as soon as an increment
does _not_ overflow:

```c++
for (int i = 7; i >= 0; i--) {
    if (++Hexa_Val[i] != 0) break;
}
```

If you don't mind the array being backwards, you can also handle the
whole array as a single 64-bit number, and just increment it like you
would increment any integer. But then you have to print the array
backwards, starting from the mast element:

```c++
union {
    uint64_t number;
    byte bytes[8];
} Hexa_Val = { .number = 0 };

void loop() {
    // Increment the array.
    Hexa_Val.number++;

    // Print out.
    for (int i = 7; i >= 0; i--) {
        if (Hexa_Val.bytes[i] < 0x10) Serial.write('0');
        Serial.print(Hexa_Val.bytes[i], HEX);
        Serial.write(' ');
    }
    Serial.println();

    delay(500);
}
```


body:
While working on my project I supplied 12v to my pro mini through raw input and then a s4 named component smoked and my pro mini  stopped working . It didn't turn on either through vcc or raw. The voltage regulator seems completely fine. Can I repair my pro mini. Please help. [![enter image description here][1]][1]

  [1]: https://i.stack.imgur.com/fd3Kn.jpg

title: Blew my arduino pro mini s4 named component

Answers: 2

body:
Many Arduinos have a Schottky diode between the power connector and the voltage regulator as a protection against accidental reverse polarity connection. The [official Pro Mini](https://www.arduino.cc/en/uploads/Main/Arduino-Pro-Mini-schematic.pdf), or the [Sparkfun variant](https://www.sparkfun.com/datasheets/DevTools/Arduino/Arduino-Pro-Mini.pdf), does not.

So you can either de-solder the diode or break it off the board using diagonal cutters and then replace it with either a similar diode -- or with a solder-bridge if you are confident about never connecting power the wrong way around.

It's possible (likely even) that other components that look OK visually are actually damaged. Especially if you can't power the board by connecting a regulated 5V supply to the VCC pin.

body:
Once you have removed the diode as described in @RedGrittyBrick's answer, you will need to replace it with another. Note you don't have to replace it with a SMD version if you can't get your hands on one. Most electronics shops sell a 1N4004 or 1N4007 diode which would be a suitable replacement.

If worst comes to worst, you could solder a blob of solder across the diode's pads - which would mean you lose the reverse polarit protection - but it would provide a path for your voltage input to go into the regulator.


body:
Got a Duratech motor shield today, and I'm wondering why my motors do not run. Appreciate any help. The code I am using is the Adafruit sample code, Motorparty. The servos work however the motors do not.

Here is a photo of my setup, code is below:

![Setup](https://cdn.discordapp.com/attachments/693791493131075624/833969894059278377/20210420_173639.jpg)

```
/*
This is a test sketch for the Adafruit assembled Motor Shield for Arduino v2
It won't work with v1.x motor shields! Only for the v2's with built in PWM
control

For use with the Adafruit Motor Shield v2
----> http://www.adafruit.com/products/1438

This sketch creates a fun motor party on your desk *whiirrr*
Connect a unipolar/bipolar stepper to M3/M4
Connect a DC motor to M1
Connect a hobby servo to SERVO1
*/

#include <Wire.h>
#include <Servo.h>
#include <Adafruit_MotorShield.h>

// Create the motor shield object with the default I2C address
Adafruit_MotorShield AFMS = Adafruit_MotorShield();
// Or, create it with a different I2C address (say for stacking)
// Adafruit_MotorShield AFMS = Adafruit_MotorShield(0x61);

// Connect a stepper motor with 200 steps per revolution (1.8 degree)
// to motor port #2 (M3 and M4)
Adafruit_StepperMotor *myStepper = AFMS.getStepper(200, 2);
// And connect a DC motor to port M1
Adafruit_DCMotor *myMotor = AFMS.getMotor(3);

// We'll also test out the built in Arduino Servo library
Servo servo1;

void setup() {
  Serial.begin(9600);           // set up Serial library at 9600 bps
  Serial.println("MMMMotor party!");

  AFMS.begin();  // create with the default frequency 1.6KHz
  //AFMS.begin(1000);  // OR with a different frequency, say 1KHz

  // Attach a servo to pin #10
  servo1.attach(10);

  // turn on motor M1
  myMotor->setSpeed(200);
  myMotor->run(RELEASE);

  // setup the stepper
  myStepper->setSpeed(10);  // 10 rpm
}

int i;
void loop() {
  myMotor->run(FORWARD);
  for (i=0; i<255; i++) {
    servo1.write(map(i, 0, 255, 0, 180));
    myMotor->setSpeed(i);
    myStepper->step(1, FORWARD, INTERLEAVE);
    delay(3);
 }

 for (i=255; i!=0; i--) {
    servo1.write(map(i, 0, 255, 0, 180));
    myMotor->setSpeed(i);
    myStepper->step(1, BACKWARD, INTERLEAVE);
    delay(3);
 }

  myMotor->run(BACKWARD);
  for (i=0; i<255; i++) {
    servo1.write(map(i, 0, 255, 0, 180));
    myMotor->setSpeed(i);
    myStepper->step(1, FORWARD, DOUBLE);
    delay(3);
 }

  for (i=255; i!=0; i--) {
    servo1.write(map(i, 0, 255, 0, 180));
    myMotor->setSpeed(i);
    myStepper->step(1, BACKWARD, DOUBLE);
    delay(3);
 }
}
```

title: Motors not working with a motor Shield

Answers: 0


body:
I am going to use MCP23017 chips, and some of them will be cabled with a 1 meter max unshielded cable. I am expecting that certain transmissions may toss errors. So I want to tackle this problems by using the built in error detection of I2C, polling the inputs frequently (every 20ms or so) and by debouncing the received data in code by comparing the previous state to the current state of every input pin.

If you write bytes to an I2C slave with the Wire library. You can use the return value of ```Wire.endTransmission();``` to test if the slave has acknowledged the message.

How does this work when you are requesting bytes using ```Wire.requestFrom( address, 3 );``` for example. This function does return the amount of received bytes. Can we check this value with the value of the amount of bytes we requested?

I have read the TI document over how I2C works

> The master will continue sending out the clockpulses, but will release the SDA line, so that the slave can transmit data. At the end of every byte of data, the master will send an ACK to the slave, letting the slave know that it is ready for more data. Once the master has received the number of bytes it is expecting, it will send a NACK, signaling to the slave to halt communications and release the bus. The master will follow this up with a STOP condition

So the master either ACKs or NACKs a read-in byte. Does the Wire library automatically make several attempts with reading? Oris there something in the Wire library which we can use to detect a failed read operation?

Is it perhaps so that the ```requestFrom()``` function may return a different amount of bytes than you requested with which would indicate that atleast 1 read operation failed?

So could I attempt something like
```
doItAllAgain:

for(int i = 0 ; i < 5 ; i ++ )
{
    Wire.beginTransmission( address ) ;
    Wire.write( register ) ;
    if( !Wire.endTransmission() ) break ; // if no error, break out of for loop
    Serial.println(F("write operation failed");
}

Serial.println(F("write operation succes");

byte requestedBytes = 3 ;
byte returnedBytes = Wire.requestFrom( address, requestedBytes ) ;

if( requestedBytes != returnedBytes )
{
    Serial.println(F("read operation failed");
    goto doItAllAgain ;
}
else
{
    Serial.println(F("read operation also succes");
    byte byte1 = Wire.read() ;
    byte byte2 = Wire.read() ;
    byte byte3 = Wire.read() ;
}
```

title: How detect I2C errors with requestFrom()

Answers: 1

body:
The `Wire` library does not give you any possibility to get error states, when requesting bytes from a slave. Basically you are stuck with the number of bytes being read.

Though you can read some information from that. If the number of bytes is zero, the slave didn't answer (either because its not there, or because it cannot send any byte currently). This equals a NACK by the slave after the address byte.

Other than that the I2C protocol doesn't give any more information. On requesting the slave is sending data and the master is acknowledging it. That means, that the slave cannot generate a NACK in this process. In fact that also means, that the returned number of bytes can only be zero (on NACK on address) or equal to the number of requested bytes, since after the address ACK from the slave the master will continue to generate clock pulses, until it has read all bytes, that it wanted. If the slave doesn't have any more data to send before that, it cannot stop the transmission. It would just stop driving the data line, resulting in all high data bytes (`0xFF`).

Also I doubt, that it would be really useful in your case. I2C is made for small distances, mostly on the same PCB. It can be used for longer distances, but your mileage may vary. If your setup really can corrupt the communication on the I2C lines, your biggest problem will be a stuck bus. The I2C protocol is generally not prepared for noisy environments and it incorporates states, where the devices on the bus can wait infinitely. This is also reflected in the `Wire` library. That means, that big noise on the lines will often lead to the bus being stuck in the middle of a transaction, needing you to reset the devices (not only the slaves, but also the master) to get the bus free again. I would go so far to say, that is it more likely to get the bus stuck, than to get corrupted data. So any information about errors is not really helping you here, since you won't get out of `requestFrom()` in the first place. Your code can very well get stuck there.

I suggest, that you test your setup thoroughly with the wanted run times. If the bus gets stuck too often for you, then you should make your setup more robust (shielded cables, or using an extra MCU with the I2C slave and using a more robust communication interface between main MCU and extra MCU).


body:
I have been using a BNO055 sensor (9° dof IMU) for a project which will use angular velocity to the mouse cursor on screen.

So far, I have gotten quaternion output from the sensor and been able to convert it to angular velocity in a couple of ways. The first, multiplying 1 quaternion sample by its conjugate in the next sample, and then converting the quaternion Delta in Euler angles. The second, converting from quaternions to Euler angles and then finding the change in those between samples.

Both methods result in angular velocity measurement, but each with their advantages and disadvantages. E.g. Quaternion Delta between samples does not suffer from gimbal lock, but it's difficult to isolate y-axis from z-axis movement.

I know that you can ask the sensor for angular velocity data directly, but apparently that's less precise due to the Gyro drift and it's relative orientation only, which is why I opted to work with quaternions.

Is there a better way to go about this?

My code included below for reference with the 2 approaches in case it's helpful/interesting. It uses the Adafruit repository, doing the standard stuff in setup function and then calling the function below in loop.

    void quaternion_Delta () {
      // Quaternion data 1
      imu::Quaternion quat = bno.getQuat();
      // Euler 1
      imu::Vector<3> euler_one = quat.toEuler();
      //delay between samples
      delay(BNO055_SAMPLERATE_DELAY_MS);
      // Quaternion data 2
      imu::Quaternion quat_two = bno.getQuat();
      // Euler 2
      imu::Vector<3> euler_two = quat_two.toEuler();
      // quaternion comparison
      imu::Quaternion quatDelta = quat_two * quat.conjugate ();
      imu::Vector<3> euler = quatDelta.toEuler();
      Serial.print(" X: ");
      Serial.print(euler.x()*radius_to_degrees, 2);
      Serial.print(" Y: ");
      Serial.print(euler.y()*radius_to_degrees, 2);
      Serial.print(" Z: ");
      Serial.print(euler.z()*radius_to_degrees, 2);
      Serial.print("\t\t");
      // Euler comparison
      imu::Vector<3> euler_comparison = euler_two - euler_one;
      Serial.print(" x: ");
      Serial.print(euler_comparison.x()*radius_to_degrees, 2);
      Serial.print(" y: ");
      Serial.print(euler_comparison.y()*radius_to_degrees, 2);
      Serial.print(" z: ");
      Serial.print(euler_comparison.z()*radius_to_degrees, 2);
      Serial.print("\n");
      }

title: Best way to obtain angular velocity from a 9 DoF sensor

Answers: 1

body:
Consider building on [Sebastian Madgwick's PhD IMU research][1].  A GitHub Arduino project based on Madgwick's work can be found [here][2].

  [1]: https://x-io.co.uk/open-source-imu-and-ahrs-algorithms/
  [2]: https://github.com/arduino-libraries/MadgwickAHRS


body:
The ultimate goal is to track points, which in the case ping pong, is how many times the ball has touched the table.

My concerns are with how light the ball and therefore the impact on the table will be. Is this too light for something like a vibration sensor to register?
Would you imagine the sensor working better on the paddles or the table?

I'm open to other suggestions on more reliable ways to track other than vibration. Definitely new to arduino.

title: What is the best way I can detect if a ping pong ball has hit the ping pong table?

Answers: 1

body: Having played ping-pong (badly) I think a microphone would be able to count ball/table impacts quite well. The 'click' sound is much higher than that of hitting the paddle, so you might be able to differentiate on that basis. You might consider a two microphone/transducer arrangement- one coupled to the table and one not touching the table. If you get a simultaneous signal on both, the ball has hit the table. If you get only one signal (from the not-touching microphone) then the ball has hit a paddle. This also gives you the option of getting some timing information.


body:
The following code operates in a way that LED starts to flash only if the pushbutton is pushed for one second. I want to change this and make the LED flash for 5 times, immediately on push, regardless if the button is held "long" or released immediately. Can anyone help me out with this? I'm using the LC_baseTools library btw. I managed to do this with another library with `doFlash(5)` but I have to work with LC basetools in this scenario and I can't figure out how to do it.
```cpp
#include <mechButton.h>
#include <blinker.h>

#define BUTTON_PIN   11
#define LED_PIN      13
#define BLINK_MS     500.0
#define HOLD_MS      1000

mechButton  theButton(BUTTON_PIN);                    // A debounced button object. (Hook button between pin & ground)
blinker     theBlinker(LED_PIN,BLINK_MS/2,BLINK_MS);  // A fire and forget blinker object.
timeObj     pushTimer(HOLD_MS);                       // A timer object

void setup(void) {
   theBlinker.setOnOff(false);            // Make sure the blinker is acutally off.
   theButton.setCallback(btnClicked);     // Set the callback for the button.
}

// This gets called when the button is clicked.
void btnClicked(void) {
   if (!theButton.trueFalse()) {    // If it has been grounded..
      pushTimer.start();            // Start the timer.
      theBlinker.setPercent(100);   // Set the blinker to full on.
      theBlinker.setOnOff(true);    // Fire it up.
   } else {                         // Else, button released..
      theBlinker.setOnOff(false);   // SHut off the blinker.
   }
}

void loop(void) {
   idle();                             // idle runs the stuff in the background (button & binker)
   if (!theButton.trueFalse()) {       // If the button is currently pressed..
      if (pushTimer.ding()) {          // If the timer has expired..
         theBlinker.setPercent(50);    // Start blinking!
      }
   }
}

title: Pushbutton to initiate a 5 time flash

Answers: 2

body:
First of all, considering your comment: "*I don't have time [...] to tackle arduino programming*" - If you don't learn how to code, then you can't work with code (and that includes putting together libraries you find on the internet). And learning takes time, it's that simple.

I recommend you forget about those libraries and implement that easy task from scratch, so you actually learn something. The below code has the logic you ask for, try to understand what it does.

    #define BUTTON_PIN   11
    #define LED_PIN      13

    bool button_was_pressed=false;

    void setup(){
      pinMode(LED_PIN,OUTPUT);
    }

    void loop() {
      if (digitalRead(BUTTON_PIN)) {
        if(!button_was_pressed) {
          for (int i=0;i<5;i++) {
            digitalWrite(LED_PIN,HIGH);
            delay(50);
            digitalWrite(LED_PIN,LOW);
            delay(50);
          }
        }
        button_was_pressed=true;
      }
      else {
        button_was_pressed=false;
      }
    }

...pretty simple and it's only a few lines. You may want to debounce the button and use a non-blocking coding style, but that's a different chapter.

My advice is that you learn programming in a structured manner, e.g. by watching tutorials. A Q&A site is not the right place to do so, as we only answer questions.

body:
>I managed to do this with another library with "doFlash(5)" but I have to work with LC basetools in this scenario and I can't figure out how to do it.

It looks like you are still allowed to write Arduino code in your sketch, so why not use the `BlinkWithoutDelay` "concept" and just write your own code.

I would favour an OOP solution for the LED flashing part of your requirement.
<!-- language-all: c++ -->
```
// Arduino IDE 1.8.9.
// Sketch uses 1126 bytes (3%) of program storage space.
// Global variables use 25 bytes (1%) of dynamic memory.
class Flasher{

  private:

    byte ledPin;
    byte ledState;
    unsigned int flashCounter;
    unsigned long highTime;
    unsigned long lowTime;
    unsigned long previousMillis;

  public:

    Flasher(byte ledPinNumber, unsigned long ledOnTime, unsigned long ledOffTime){
      ledPin = ledPinNumber;
      ledState = LOW;
      highTime = ledOnTime;
      lowTime = ledOffTime;
      previousMillis = 0;
      pinMode(ledPinNumber, OUTPUT);
      digitalWrite(ledPinNumber, LOW);
    }

    void Update(){

      // Check to see if it's time to change the state of the LED.
      unsigned long currentMillis = millis();

      if((ledState == HIGH) && (currentMillis - previousMillis >= highTime) && ((flashCounter > 0))){
        ledState = LOW;
        previousMillis += highTime;
        digitalWrite(ledPin, ledState);
        if(flashCounter > 0){flashCounter--;}
      }
      else if((ledState == LOW) && (currentMillis - previousMillis >= lowTime) && ((flashCounter > 0))){
        ledState = HIGH;
        previousMillis += lowTime;
        digitalWrite(ledPin, ledState);
        if(flashCounter > 0){flashCounter--;}
      }
    }

    void Start(unsigned int flashNumberOfTimes){
      flashCounter = flashNumberOfTimes * 2;
      ledState = LOW;
      digitalWrite(ledPin, ledState);
    }

    void Stop(){
      Start(0);
    }

    void SetPinHighTime(unsigned long pinHighTime){
      highTime = pinHighTime;
    }

    void SetPinLowTime(unsigned long pinLowTime){
      lowTime = pinLowTime;
    }

};

// Flasher object_name(Pin Number, ON Time MS, OFF Time MS);
Flasher led1(LED_BUILTIN, 500, 500);

void setup(){

  // Flash the LED 5 times.
  led1.Start(5);

}

void loop(){

  // Call the Update function as fast as possible.
  led1.Update();

}

```


body:
I have very peculier problem. When I run this code SSD1306 fails to initialize. Output at serial console is:
20:26:33.194 -> MPU6050 OLED demo

20:26:33.532 -> SSD1306 allocation failed

    #include <Wire.h>
    #include <Adafruit_GFX.h>
    #include <Adafruit_MPU6050.h>
    #include <Adafruit_SSD1306.h>
    #include <Adafruit_Sensor.h>

    #define SCREEN_WIDTH 128 // OLED display width, in pixels
    #define SCREEN_HEIGHT 64 // OLED display height, in pixels
    #define OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)
    #define SCREEN_ADDRESS 0x3D ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32

    Adafruit_MPU6050 mpu;
    Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

    int count =0;

    void setup() {

      Serial.begin(9600);
      while (!Serial);
      Serial.println("MPU6050 OLED demo");

      if (!mpu.begin()) {
        Serial.println("Sensor init failed");
        while (1)
          yield();
      }
      Serial.println("Found a MPU-6050 sensor");

      // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
      if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) { // Address 0x3C for 128x32
        Serial.println(F("SSD1306 allocation failed"));
        for (;;)
          ; // Don't proceed, loop forever
      }

      display.display();
      delay(500); // Pause for 2 seconds
      display.setTextSize(1);
      display.setTextColor(WHITE);
      display.setRotation(0);
    }

    void loop() {
      sensors_event_t a, g, temp;
      mpu.getEvent(&a, &g, &temp);

      display.clearDisplay();
      display.setCursor(0, 0);

      display.println("Accelerometer - m/s^2");
      display.print(a.acceleration.x, 1);
      display.print(", ");
      display.print(a.acceleration.y, 1);
      display.print(", ");
      display.print(a.acceleration.z, 1);
      display.println("");

      display.println("Gyroscope - rps");
      display.print(g.gyro.x, 1);
      display.print(", ");
      display.print(g.gyro.y, 1);
      display.print(", ");
      display.print(g.gyro.z, 1);
      display.println("");
      display.display();
      delay(100);
    }

But when I run this code, without displaying gyro everything runs fine. Adafruit logo is displayed and then followed by regular accelerometer data.

    #include <Wire.h>
    #include <Adafruit_GFX.h>
    #include <Adafruit_MPU6050.h>
    #include <Adafruit_SSD1306.h>
    #include <Adafruit_Sensor.h>

    #define SCREEN_WIDTH 128 // OLED display width, in pixels
    #define SCREEN_HEIGHT 64 // OLED display height, in pixels
    #define OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)
    #define SCREEN_ADDRESS 0x3D ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32

    Adafruit_MPU6050 mpu;
    Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

    int count =0;

    void setup() {

      //Serial.begin(9600);
      //while (!Serial);
      //Serial.println("MPU6050 OLED demo");

      if (!mpu.begin()) {
        //Serial.println("Sensor init failed");
        while (1)
          yield();
      }
      //Serial.println("Found a MPU-6050 sensor");

      // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
      if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) { // Address 0x3C for 128x32
        Serial.println(F("SSD1306 allocation failed"));
        for (;;)
          ; // Don't proceed, loop forever
      }

      display.display();
      delay(500); // Pause for 2 seconds
      display.setTextSize(1);
      display.setTextColor(WHITE);
      display.setRotation(0);
    }

    void loop() {
      sensors_event_t a, g, temp;
      mpu.getEvent(&a, &g, &temp);

      display.clearDisplay();
      display.setCursor(0, 0);

      display.println("Accelerometer - m/s^2");
      display.print(a.acceleration.x, 1);
      display.print(", ");
      display.print(a.acceleration.y, 1);
      display.print(", ");
      display.print(a.acceleration.z, 1);
      display.println("");

      display.println("Gyroscope - rps");
      display.print(g.gyro.x, 1);
      display.print(", ");
      display.print(g.gyro.y, 1);
      display.print(", ");
      display.print(g.gyro.z, 1);
      display.println("");
      display.display();
      delay(100);
    }

Now, while debugging when I disable Serial logs and comment all Serial.print then the above code runs properly, logo is displayed, accelerometer and gyro both the data are displayed on OLED properly.

Compiler Log for non-working code is:
Sketch uses 21980 bytes (71%) of program storage space. Maximum is 30720 bytes.
Global variables use 761 bytes (37%) of dynamic memory, leaving 1287 bytes for local variables. Maximum is 2048 bytes.

The setup I am using as Arduino Nano, MPU6050 connected over I2C (address 0x68), SSD1306 based 0.96" 128x64 display over I2C (address 0x3D). I am using A4 and A5 pin of Arduino Nano as I2C. Both device are connected over same bus. I am using breadboard for testing.

PS: Both the code compiles without error or warning

title: Serial and I2C not working together

Answers: 2

body:
The SSD1306 uses a *lot* of RAM. Pretty much all your RAM.  Serial also uses quite  a bit of RAM.  The two struggle to work together.

There is a special "text only" SSD1306 library that uses considerably less RAM: https://github.com/greiman/SSD1306Ascii

body:
Thank you Majenko...

It was low RAM problem.
SSD1306 takes 1K, with MPU6050 the and serial print which I have included the remaining RAM is 5 bytes only, hence the initialization issue.
I followed simple guideline to reduce RAM footprint

Read this thread https://stackoverflow.com/questions/8649174/checking-memory-footprint-in-arduino

Code to print available SRAM.

```cpp
Serial.print(availableMemory());

// free RAM check for debugging. SRAM for ATmega328p = 2048Kb.
int availableMemory() {
    // Use 1024 with ATmega168
    int size = 2048;
    byte *buf;
    while ((buf = (byte *) malloc(--size)) == NULL);
        free(buf);
    return size;
}
```


body:
my new Nano 33 BLE Sense arrived today.  I'm working on a project to send data from the the Nano via an Xbee S2C module to a receiver module connected to a Nano 33 IoT.  I had the project working before using an MPU6050 and Mega 2560 board which worked (using Software Serial on the Mega).  On the IoT side, I am using 'Uart XBeeRx  (&sercom0, 5, 6, SERCOM_RX_PAD_1, UART_TX_PAD_0);' to process the data from the Xbee.  Having tried this syntax on the BLE Sense I hit problems and after some Googling found a different syntax.  However my new code isn't working in so far as it compiles, uploads and then crashes the BLE Sense (serial port disappears from tools and the onboard LED blinks slowly and erratically).  I need to keep resetting the board and suspect there is some issue with my hardware serial implementation.  I've cut the code down to simply send accelerometer data.  My code is as follows - the EasyTransfer library simplifies the Xbee comms.  Any help appreciated!

    #include <EasyTransfer.h>
    #include <Arduino_LSM9DS1.h>

    UART XBeeTx (digitalPinToPinName(6), digitalPinToPinName(5), NC, NC);

    EasyTransfer ET;

    struct SEND_DATA_STRUCTURE {

      float xAcc;
      float yAcc;
      float zAcc;

    };

    SEND_DATA_STRUCTURE myData;

    // ================================================================
    // ===                      INITIAL SETUP                       ===
    // ================================================================

    void setup() {

    XBeeTx.begin(9600);

    ET.begin(details(myData), &XBeeTx);

    }

    // ================================================================
    // ===                    MAIN PROGRAM LOOP                     ===
    // ================================================================

    void loop() {

      float x, y, z;

    if (IMU.accelerationAvailable()) {
        IMU.readAcceleration(x, y, z);

      }

      myData.xAcc = x;
      myData.yAcc = y;
      myData.zAcc = z;

      ET.sendData();

    }

title: Problems with Hardware Serial (UART) on Nano 33 BLE Sense

Answers: 1

body: You can't make calls to IMU if you haven't initialised it with IMU.begin()


body:
The current code is used to gather the state of 12 infrared beams and log them to an SD card using the real time clock to mark the time. The code uses a switch to turn the device on and off and an LED to indicate if data is being written to the SD. When we later looked at the data on the SD card the refresh rate was slowly decreasing and we ended up with only 10 logs a second after a few hours. Why is this happening and how is it fixed?
```
#include <SD.h>   //For talking to SD Card
#include <Wire.h>  //For RTC
#include "RTClib.h" //For RTC

//Define pins
//SD card is on standard SPI pins
//RTC is on Standard I2C Pins
const int CS_PIN   = 53;

//Default rate of 25ms
int refresh_rate = 25;

//Define RTC object
RTC_DS1307 RTC;

//Initialize variables
String year, month, day, hour, minute, second, time, date;

#define SENSOR1 22
#define SENSOR2 23
#define SENSOR3 24
#define SENSOR4 25
#define SENSOR5 26
#define SENSOR6 27
#define SENSOR7 32
#define SENSOR8 33
#define SENSOR9 34
#define SENSOR10 35
#define SENSOR11 36
#define SENSOR12 37
#define LEDPIN 6
#define SWITCH 10

// variables will change:
int sensorState1 = 0, lastState1 = 0;
int sensorState2 = 0, lastState2 = 0;
int sensorState3 = 0, lastState3 = 0;
int sensorState4 = 0, lastState4 = 0;
int sensorState5 = 0, lastState5 = 0;
int sensorState6 = 0, lastState6 = 0;
int sensorState7 = 0, lastState7 = 0;
int sensorState8 = 0, lastState8 = 0;
int sensorState9 = 0, lastState9 = 0;
int sensorState10 = 0, lastState10 = 0;
int sensorState11 = 0, lastState11 = 0;
int sensorState12 = 0, lastState12 = 0;

//Variable for reading the Switch Status
int SWITCHSTATE ;

//define integers for sensor change
int SensorChange1 = 0;
int SensorChange2 = 0;
int SensorChange3 = 0;
int SensorChange4 = 0;
int SensorChange5 = 0;
int SensorChange6 = 0;
int SensorChange7 = 0;
int SensorChange8 = 0;
int SensorChange9 = 0;
int SensorChange10 = 0;
int SensorChange11 = 0;
int SensorChange12 = 0;

void setup()
{
  // initialize the sensor pin 24 as an input:
  pinMode(SENSOR1, INPUT);
  digitalWrite(SENSOR1, HIGH); // turn on the pullup  // initialize the sensor pin 25 as an input:
  pinMode(SENSOR2, INPUT);
  digitalWrite(SENSOR2, HIGH); // initialize the sensor pin 26 as an input:
  pinMode(SENSOR3, INPUT);
  digitalWrite(SENSOR3, HIGH); // initialize the sensor pin 27 as an input:
  pinMode(SENSOR4, INPUT);
  digitalWrite(SENSOR4, HIGH); // initialize the sensor pin 28 as an input:
  pinMode(SENSOR5, INPUT);
  digitalWrite(SENSOR5, HIGH); // initialize the sensor pin 29 as an input:
  pinMode(SENSOR6, INPUT);
  digitalWrite(SENSOR6, HIGH);  // initialize the sensor pin 30 as an input:
  pinMode(SENSOR7, INPUT);
  digitalWrite(SENSOR7, HIGH);  // initialize the sensor pin 31 as an input:
  pinMode(SENSOR8, INPUT);
  digitalWrite(SENSOR8, HIGH);  // initialize the sensor pin 32 as an input:
  pinMode(SENSOR9, INPUT);
  digitalWrite(SENSOR9, HIGH);  // initialize the sensor pin 33 as an input:
  pinMode(SENSOR10, INPUT);
  digitalWrite(SENSOR10, HIGH);  // initialize the sensor pin 34 as an input:
  pinMode(SENSOR11, INPUT);
  digitalWrite(SENSOR11, HIGH);  // initialize the sensor pin 35 as an input:
  pinMode(SENSOR12, INPUT);
  digitalWrite(SENSOR12, HIGH);   // initialize the LED pin as an output:

// initialize the LED pin as an output:
  pinMode (LEDPIN, OUTPUT);

// initialize the SWITCH pin as an output:
  pinMode (SWITCH, INPUT);

// setpin 19 as high (5V) and 18 as low
  pinMode(19, OUTPUT);
  pinMode(18, OUTPUT);
  digitalWrite(19, HIGH);
  digitalWrite(18, LOW);

  Serial.begin(9600);
  Serial.println(F("Initializing Card"));

 //CS pin, and pwr/gnd pins are outputs
  pinMode(CS_PIN, OUTPUT);

  //Initiate the I2C bus and the RTC library
  Wire.begin();
  RTC.begin();

  //If RTC is not running, set it to the computer's compile time
  if (! RTC.isrunning())
  {
    Serial.println(F("RTC is NOT running!"));
    RTC.adjust(DateTime(__DATE__, __TIME__));
  }

  //Initialize SD card
  if (!SD.begin(CS_PIN))
  {
    Serial.println(F("Card Failure"));
    return;
  }
  Serial.println(F("Card Ready"));

  //Read the configuration information (speed.txt)
  File commandFile = SD.open("speed.txt");
  if (commandFile)
  {
    Serial.println(F("Reading Command File"));

    while(commandFile.available())
    {
      refresh_rate = commandFile.parseInt();
    }
    Serial.print(F("Refresh Rate = "));
    Serial.print(refresh_rate);
    Serial.println(F("ms"));
    commandFile.close();
  }
  else
  {
    Serial.println(F("Could not read command file."));
    return;
  }

}

void loop()
{
  SWITCHSTATE = digitalRead(SWITCH); //read input value
  if (SWITCHSTATE == LOW)
 {
   digitalWrite(LEDPIN, LOW);
 }
  else
 {
   digitalWrite(LEDPIN, HIGH);

// read the state of the sensor value:
  sensorState1 = digitalRead(SENSOR1);
  sensorState2 = digitalRead(SENSOR2);
  sensorState3 = digitalRead(SENSOR3);
  sensorState4 = digitalRead(SENSOR4);
  sensorState5 = digitalRead(SENSOR5);
  sensorState6 = digitalRead(SENSOR6);
  sensorState7 = digitalRead(SENSOR7);
  sensorState8 = digitalRead(SENSOR8);
  sensorState9 = digitalRead(SENSOR9);
  sensorState10 = digitalRead(SENSOR10);
  sensorState11 = digitalRead(SENSOR11);
  sensorState12 = digitalRead(SENSOR12);

  //Get the current date and time info and store in strings
  DateTime datetime = RTC.now();
  year  = String(datetime.year(),  DEC);
  month = String(datetime.month(), DEC);
  day  = String(datetime.day(), DEC);
  hour  = String(datetime.hour(), DEC);
  minute = String(datetime.minute(), DEC);
  second = String(datetime.second(), DEC);

  //Concatenate the strings into date and time
  date = year + "/" + month + "/" + day;
  time = hour + ":" + minute + ":" + second;

  if (sensorState1 == HIGH)
  {
   SensorChange1 = 1;
  }
  else
  {
   SensorChange1 = 0;
  }
  if (sensorState2 == HIGH)
  {
   SensorChange2 = 1;
  }
  else
  {
   SensorChange2 = 0;
  }
  if (sensorState3 == HIGH)
  {
   SensorChange3 = 1;
  }
  else
  {
   SensorChange3 = 0;
  }
  if (sensorState4 == HIGH)
  {
   SensorChange4 = 1;
  }
  else
  {
   SensorChange4 = 0;
  }
  if (sensorState5 == HIGH)
  {
   SensorChange5 = 1;
  }
  else
  {
   SensorChange5 = 0;
  }
  if (sensorState6 == HIGH)
  {
   SensorChange6 = 1;
  }
  else
  {
   SensorChange6 = 0;
  }
  if (sensorState7 == HIGH)
  {
   SensorChange7 = 1;
  }
  else
  {
   SensorChange7 = 0;
  }
  if (sensorState8 == HIGH)
  {
   SensorChange8 = 1;
  }
  else
  {
   SensorChange8 = 0;
  }
  if (sensorState9 == HIGH)
  {
   SensorChange9 = 1;
  }
  else
  {
   SensorChange9 = 0;
  }
  if (sensorState10 == HIGH)
  {
   SensorChange10 = 1;
  }
  else
  {
   SensorChange10 = 0;
  }
  if (sensorState11 == HIGH)
  {
   SensorChange11 = 1;
  }
  else
  {
   SensorChange11 = 0;
  }
  if (sensorState12 == HIGH)
  {
   SensorChange12 = 1;
  }
  else
  {
   SensorChange12 = 0;
  }

  File dataFile ;
  dataFile = SD.open("log1.csv", FILE_WRITE);
  if (dataFile)
    {
      dataFile.print(date);
      dataFile.print(F(","));
      dataFile.print(time);
      dataFile.print(F(","));
      dataFile.print(SensorChange1);
      dataFile.print(F(","));
      dataFile.print(SensorChange2);
      dataFile.print(F(","));
      dataFile.print(SensorChange3);
      dataFile.print(F(","));
      dataFile.print(SensorChange4);
      dataFile.print(F(","));
      dataFile.print(SensorChange5);
      dataFile.print(F(","));
      dataFile.print(SensorChange6);
      dataFile.print(F(","));
      dataFile.print(SensorChange7);
      dataFile.print(F(","));
      dataFile.print(SensorChange8);
      dataFile.print(F(","));
      dataFile.print(SensorChange9);
      dataFile.print(F(","));
      dataFile.print(SensorChange10);
      dataFile.print(F(","));
      dataFile.print(SensorChange11);
      dataFile.print(F(","));
      dataFile.print(SensorChange12);
      dataFile.println( );
      dataFile.close(); //Data isn't actually written until we close the connection!

      //Print same thing to the screen for debugging
      Serial.println();
      Serial.print(date);
      Serial.print(F(","));
      Serial.print(time);
      Serial.print(F(","));
      Serial.print(SensorChange1);
      Serial.print(F(","));
      Serial.print(SensorChange2);
      Serial.print(F(","));
      Serial.print(SensorChange3);
      Serial.print(F(","));
      Serial.print(SensorChange4);
      Serial.print(F(","));
      Serial.print(SensorChange5);
      Serial.print(F(","));
      Serial.print(SensorChange6);
      Serial.print(F(","));
      Serial.print(SensorChange7);
      Serial.print(F(","));
      Serial.print(SensorChange8);
      Serial.print(F(","));
      Serial.print(SensorChange9);
      Serial.print(F(","));
      Serial.print(SensorChange10);
      Serial.print(F(","));
      Serial.print(SensorChange11);
      Serial.print(F(","));
      Serial.print(SensorChange12);

    }
    else
    {
     Serial.println(F("Couldn't open log file"));
    }

  lastState1 = sensorState1;
  lastState2 = sensorState2;
  lastState3 = sensorState3;
  lastState4 = sensorState4;
  lastState5 = sensorState5;
  lastState6 = sensorState6;
  lastState7 = sensorState7;
  lastState8 = sensorState8;
  lastState9 = sensorState9;
  lastState10 = sensorState10;
  lastState11 = sensorState11;
  lastState12 = sensorState12;

  delay(refresh_rate);
  }

  }
```
[![Frequency over time as graphed in R][1]][1]

  [1]: https://i.stack.imgur.com/ZBZx1.jpg

title: Why is our refresh rate consistently decreasing in logging on SD card?

Answers: 1

body:
I don't have certain answer for you, but a deep suspicion.  <s>If I get bored I'll confirm it.</s> Confirmed below.

In each pass of `loop()`, you have:

```c++
  dataFile = SD.open("log1.csv", FILE_WRITE);
```

In short, finding the end of the file is linear operation in a FAT filesystem.  It must follow the [allocation chain][1] to find (or create), the last cluster of the file.  The allocation chain is sort like a linked list with the links themselves being the only thing in linked list structure; their numbers are mapped onto the cluster numbers.  So you're traversing a linked list, except you may be doing it across multiple sectors of an SD card, which is comparatively expensive.

So by reopening repeatedly in `loop()`, you're forcing it to perform this lengthening process each time, apparently because of:

```c++
dataFile.close(); //Data isn't actually written until we close the connection!
```

The part of `.close();` that does this is [made available][2] to you as `.flush();`, without needing to close the file and forget where the current cluster is.

In other words, you should be able to `open()` the file once in `setup()` and replace your `.close()` in `loop()` with a `.flush()`.

That said, you needn't and probably shouldn't flush on every record write.  If you're doing this so that you can shut the device down, you might want to just add a push-button that does the closing or flushing and then waits in the tight loop until it's power cycled.

Confirmation Test  Results
==========================

In short, yes, there's a measurable, file-size related cost to opening the file for write and seeking to the end. And it's just a fact about the FAT filesystem and noticeable because it's impractical to load the whole allocation table into memory on a small Arduino.  It would normally (e.g on the desktop) be loaded into memory and you'd scarcely notice the difference in opening files of different sizes.

In my one tested scenario for my setup the numbers predict that when the file grows to approximately 155 Meg, it will take about a tenth of a second to open.

This test involved:
* An Arduino UNO.
* 2 GB FAT16 formatted card.
* Arduino AVR core version 1.8.3
* SD card library version 1.2.4.

Your results will probably vary widely with MCU type and filesystem block size, but so long as you're using a Arduino with a SD library that minimizes memory footprint, you'll have a noticeable increasing open time with larger file sizes.

The below is going to be a bit nerdy, but since people seem to be interested in it, I'm giving some detail.  Arduino code follows at the bottom for what was used to collect the data that produced the graph.

I emptied a 2 GByte SD card.  This included removing the "System Volume Information" that windows (or perhaps the card maker) had put on there, and
confirmed that were were no allocated clusters, no file chains.  Under these conditions the file should just grow in consecutive sectors on the card; at
least as presented by the card, as in: if we ignore anything the card might be doing for wear-leveling.  The pattern used in the program makes it pretty easy
to just look at a raw image of the card and see that this is what happened.

Anyway, with my setup these are some results:

[![Graph of real timings.][4]][4]

The 98304 sector count on the right refers to a file of roughly 50 Meg.

This SD card is FAT16 formatted, something I hadn't noticed until I ran the numbers on that staircase pattern and found them defying expectations by a factor of 2.

Being FAT16, each FAT table sector, has 512/2 = 256 entries in it.  Each entry number corresponds to one cluster (block), which for my SD card's filesystem happens to be 32 kByte, or 64 count of 512-byte sectors.   So every FAT table sector (in my case) is responsible for locating 64 * 256 = 16,384 file sectors.  In other words, the staircase pattern appears to reflect the fact that following the allocation chain for our consecutive file means reading another FAT table sector for every 16,384 sectors of the file, hence the jumps at those intervals.

* If you used a fragmented file it would need to do this more often and the performance would look worse.  *I did inspect the SD card to confirm that it was written sequentially.*

* If you use FAT32, you can expect it to take longer because each FAT sector will store half as many cluster references.

* If you use smaller cluster (block) size, then it will take longer because each enter in the FAT sector covers less file content.

Test code
---------

```c++
//
// Tested on an UNO with Arduino Core version 1.8.3
// 2 GByte SDCard
//

#include <SD.h> // Version 1.2.4 as of test.
#include <SPI.h>

static constexpr int PIN_SDCARD_SHIELD_CHIP_SELECT = 10;
static constexpr int PIN_HALT_TEST                 =  2;

static const char test_filename[] = "testfile.txt";

struct test_state : Printable {
  uint32_t      sector_counter = -1;
  unsigned long open_duration  =  0;

  size_t printTo(Print& p) const override {
    auto r = p.write('[');
    r     += p.print(sector_counter);
    r     += p.write(':');
    r     += p.print(open_duration);
    r     += p.write(']');
    return r;
  }

  void update(unsigned long new_open_duration) {
    open_duration = new_open_duration;
    ++sector_counter;
  }
};

//
//
//
void write_numbered_sector(
  Print &p,
  const test_state &state
) {
  static constexpr size_t SECTOR_SIZE            = 512;
  static constexpr size_t CR_LF_SIZE             =   2;

  const auto printed_test_state_len = p.print(state);

  const auto xs_to_write =
      SECTOR_SIZE
    - printed_test_state_len
    - CR_LF_SIZE;

  for (size_t i = xs_to_write; i != 0; --i) {
    p.write('X');
  }

  p.write('\r');
  p.write('\n');
}

//
//
//
void setup() {
  pinMode(PIN_HALT_TEST, INPUT_PULLUP);

  Serial.begin(9600);

  if (!SD.begin(PIN_SDCARD_SHIELD_CHIP_SELECT)) {
    Serial.println(F("Card initialization failed."));
    halt_test();
  }

  SD.remove(test_filename);
}

//
//
//
void blink_forever() {
  pinMode(LED_BUILTIN, OUTPUT);
  while (true) {
    static bool led_state = false;

    led_state = !led_state;
    digitalWrite(LED_BUILTIN, led_state);
    delay(100);
  }
}

//
//
//
void halt_test() {
  SD.end();
  SPI.end();
  Serial.end();

  blink_forever();
}

//
//
//
void loop() {
  static test_state state;

  Serial.flush();
  const auto started_opening = micros();
  File testfile = SD.open(test_filename, FILE_WRITE);
  const auto done_opening = micros();

  const auto open_duration = done_opening - started_opening;

  state.update(open_duration);

  write_numbered_sector(
    testfile,
    state
  );
  testfile.close();
  Serial.print(micros());
  Serial.print(' ');
  Serial.println(state);

  const auto user_requested_halt = (digitalRead(PIN_HALT_TEST) == LOW);
  if (user_requested_halt) {
    Serial.println(F("Test halt requested."));
    halt_test();
  }
}

//  vim:sw=2:ts=2:et:nowrap:ft=cpp:
```

  [1]: https://en.wikipedia.org/wiki/Design_of_the_FAT_file_system#Cluster_map
  [2]: https://www.arduino.cc/en/Reference/FileFlush
  [3]: https://arduino.stackexchange.com/users/42982/chris-h
  [4]: https://i.stack.imgur.com/szi8q.png


body:
What's the low level difference between `if(Serial.available() > 0)` and `while(Serial.available() > 0)`? On what conditions would you choose one over the other?

I was testing my codes on 4 daisy chained 74HC595 shift registers controlling multiple LEDs. The code takes in a number from the serial monitor and displays it out in binary via the LEDs. Here is the code below that worked:

    #define latchPin 8  //ST_CP pin of 74HC595
    #define clockPin 9  //SH_CP pin of 74HC595
    #define dataPin 7   //DS pin of 74HC595

    //number of 74HC595 in daisy chain
    #define numOfDaisyChainReg 4

    byte registerVal[numOfDaisyChainReg];

    void setup() {
        Serial.begin(115200);
        pinMode(latchPin, OUTPUT);
        pinMode(clockPin, OUTPUT);
        pinMode(dataPin, OUTPUT);
    }

    void loop() {

      while (Serial.available() > 0) {

        uint32_t num = Serial.parseInt();
        Serial.print(num, DEC);
        Serial.print(" : ");
        Serial.println(num, BIN);

        //breaks the recieved int into 4 unsigned bytes
        //and assigns the byte value into the "registerVal" array
        for (uint8_t a = 0; a < numOfDaisyChainReg; a++) {
          registerVal[a] = (num >> (numOfDaisyChainReg - (a + 1)) * 8) & 0xFF;
          Serial.print("registerVal["); Serial.print(a); Serial.print("] = ");
          Serial.println(registerVal[a], BIN);
        }

        //writes the 4 bytes into the shift register
        digitalWrite(latchPin, LOW);
        for (uint8_t x = 0; x < numOfDaisyChainReg; x++) {
          shiftOut(dataPin, clockPin, MSBFIRST, registerVal[x]);
        }
        digitalWrite(latchPin, HIGH);

      }

    }

Originally, I had `if(Serial.available() > 0)` and that didn't work as no LEDs lit up despite everything else in the code working as it was expected. Switching to `while(Serial.available() > 0)` solved that problem. Anyone have any idea why that's the case?

title: if(Serial.available()>0) VS while(Serial.available()>0)

Answers: 2

body:
Some implementations of the Arduino core have features that need `loop()` to exit regularly.  Although it's not often used, the [`serialEvent()` is an example][1] of one such thing, at least in the [AVR Arduino core][2].

The ESP8266 Arduino core appears to do some [task scheduling][3] when `loop()` exits, among other things.

For your particular use case, it may make no difference at all, probably doesn't.  It *may* not even generate different code once compiled.  If you were doing something where you could not afford to exit `loop()`, run other stuff and re-enter `loop()` to run your code for a second pass, then there might be a performance reason to use your own while loop inside `loop()`.  In your code as it currently is, the eventual blocking on `Serial` writes will end up limiting the execution to the same speed.

  [1]: https://www.arduino.cc/reference/en/language/functions/communication/serial/serialevent/
  [2]: https://github.com/arduino/ArduinoCore-avr/blob/1.8.3/cores/arduino/main.cpp#L47
  [3]: https://github.com/esp8266/Arduino/blob/2.7.4/cores/esp8266/core_esp8266_main.cpp#L198

body:
I figured out why `while(Serial.available()>0)` and `if(Serial.available() > 0)` would or would NOT work in terms of my shift register code. It has to do with the serial monitor **line feed and carriage return setting**! If it isn't set to no line ending, it will either not register the input number or reset it back to zero right after the input is read. Learned to always check the line return option in the serial monitor! With this solved, the original question is nothing more than a general `if` vs `while` statement; which I already know the answer.

**Thanks to everyone who contributed to this question!** It did help me understand a lot more about `Serial.available()` in general. @jsotola gave a really good [article][1]. Combined with this [YouTube video][2], it makes a lot more sense now.

  [1]: http://majenko.co.uk/blog/reading-serial-arduino
  [2]: https://youtu.be/qCjCRBLv_VM


body:
Adding another flow sensor to sketch

I have a water flow sketch I use for my freshwater consumption.  I would like to adapt it to use for diesel fuel consumption.  The difference is with a diesel motor the fuel pump sucks more fuel than it burns from the fuel tank and simply returns the excess to the fuel tank.  ie there are 2 hoses from the fuel tank, one to the motor, and one back to the tank.  The difference between what went to the motor and what went back to the tank is how much fuel the motor burned.

So my plan is to have 2 flow sensors (Yf-s201), and subtract the out put of one from the other and print the difference.

I have a sketch that already works to print L/m and total L.  For one sensor on PIN D2.
I have defined another sensor on PIN D3.

    byte sensorInterrupt = 0;  // 0 = digital pin 2
    byte sensorPin       = 2;

    byte sensorInterrupt2 = 1;  //11 = digital pin 3
    byte sensorPin2       = 3;

My first road block is to print them individually. as is they both just add to a single total.

I have tried to just copy bits of code and add a "2" but I really don't have any programing knowledge so I am just stabbing in the dark.   I don't understand how to call upon the value the code has calculated.

This is the whole sketch:

    /*
    Liquid flow rate sensor -DIYhacking.com Arvind Sanjeev

    Measure the liquid/water flow rate using this code.
    Connect Vcc and Gnd of sensor to arduino, and the
    signal line to arduino digital pin 2.

     */
    // include the library code:
    #include <Wire.h>
    #include <LiquidCrystal_I2C.h>

    LiquidCrystal_I2C lcd(0x27,20,4);

    byte statusLed    = 13;

    byte sensorInterrupt = 0;  // 0 = digital pin 2
    byte sensorPin       = 2;

    byte sensorInterrupt2 = 1;  // 1 = digital pin 3
    byte sensorPin2       = 3;

    // The hall-effect flow sensor outputs approximately 4.5 pulses per second per
    // litre/minute of flow.
    float calibrationFactor = 7.55;  //biger more / min

    volatile byte pulseCount;

    float flowRate;
    unsigned int flowMilliLitres;
    unsigned long totalMilliLitres;

    unsigned long oldTime;

    void setup()
    {

      // Initialize a serial connection for reporting values to the host
      Serial.begin(9600);
    lcd.init();
    lcd.backlight();
         lcd.begin(16, 2);
       lcd.clear();
       lcd.setCursor(0,0);
       lcd.print("S.V. SAVANNAH");
       lcd.setCursor(0,1);
       lcd.print("DAY TANK FLOW METER");

      // Set up the status LED line as an output
      pinMode(statusLed, OUTPUT);
      digitalWrite(statusLed, HIGH);  // We have an active-low LED attached

      pinMode(sensorPin, INPUT);
      digitalWrite(sensorPin, HIGH);

      pulseCount        = 0;
      flowRate          = 0.0;
      flowMilliLitres   = 0;
      totalMilliLitres  = 0;
      oldTime           = 0;

      // The Hall-effect sensor is connected to pin 2 which uses interrupt 0.
      // Configured to trigger on a FALLING state change (transition from HIGH
      // state to LOW state)
      attachInterrupt(sensorInterrupt, pulseCounter, FALLING);
    }

    /**
     * Main program loop
     */
    void loop()
    {

       if((millis() - oldTime) > 1000)    // Only process counters once per second
      {
        // Disable the interrupt while calculating flow rate and sending the value to
        // the host
        detachInterrupt(sensorInterrupt);

        // Because this loop may not complete in exactly 1 second intervals we calculate
        // the number of milliseconds that have passed since the last execution and use
        // that to scale the output. We also apply the calibrationFactor to scale the output
        // based on the number of pulses per second per units of measure (litres/minute in
        // this case) coming from the sensor.
        flowRate = ((1000.0 / (millis() - oldTime)) * pulseCount) / calibrationFactor;

        // Note the time this processing pass was executed. Note that because we've
        // disabled interrupts the millis() function won't actually be incrementing right
        // at this point, but it will still return the value it was set to just before
        // interrupts went away.
        oldTime = millis();

        // Divide the flow rate in litres/minute by 60 to determine how many litres have
        // passed through the sensor in this 1 second interval, then multiply by 1000 to
        // convert to millilitres.
        flowMilliLitres = (flowRate / 60) * 1000;

        // Add the millilitres passed in this second to the cumulative total
        totalMilliLitres += flowMilliLitres;

        unsigned int frac;

        // Print the flow rate for this second in litres / minute
        Serial.print("Flow rate: ");
        Serial.print(int(flowRate));  // Print the integer part of the variable
        Serial.print("L/min");
        Serial.print("\t");       // Print tab space

        // Print the cumulative total of litres flowed since starting
        Serial.print("Output Liquid Quantity: ");
        Serial.print(totalMilliLitres);
        Serial.println("mL");
        Serial.print("\t");       // Print tab space
      Serial.print(totalMilliLitres/1000);
      Serial.print("L");

          lcd.clear();
          lcd.setCursor(4,0);
          lcd.print(int(flowRate));  // Print the integer part of the variable
          lcd.print("L/min ");

        // Print the cumulative total of litres flowed since starting
        lcd.setCursor(2,1);
        lcd.print("Total ");
      lcd.print(totalMilliLitres/1000.00);
      lcd.print("L");

        // Reset the pulse counter so we can start incrementing again
        pulseCount = 0;

        // Enable the interrupt again now that we've finished sending output
        attachInterrupt(sensorInterrupt, pulseCounter, FALLING);
      }
    }

    /*
    Insterrupt Service Routine
     */
    void pulseCounter()
    {
      // Increment the pulse counter
      pulseCount++;
    }'''

title: Adding another flow sensor to sketch

Answers: 2

body:
Your code currently does not use the second flow sensor. I guess you have problems in designing the code, so I try to walk you trough.

First let's look at the prerequisites, that are needed for the two flow sensors. You already have defined the pins of the flow sensors. You are also defining the number of the corresponding interrupts. In fact you don't have to do that. You can easily get the number of the interrupt through the function `digitalPinToInterrupt(pin)`. So we are left with the pin definition. I would suggest using clearer names:

    int flow_out_pin = 2;
    int flow_in_pin = 3;

`flow_out` meaning leaving the tank, `flow_in` coming back into the tank.

Then in `setup()` we need to initiate the pins. You have this

    pinMode(sensorPin, INPUT);
    digitalWrite(sensorPin, HIGH);

This can be then made shorter in one line per sensor:

    pinMode(flow_out_pin, INPUT_PULLUP);
    pinMode(flow_in_pin, INPUT_PULLUP);

Now we attach the interrupts to the pins:

    attachInterrupt(digitalPinToInterrupt(flow_out_pin), flowOutPulseCounter, FALLING);
    attachInterrupt(digitalPinToInterrupt(flow_in_pin), flowInPulseCounter, FALLING);

I used the mentioned function to get the interrupt number and changed the name of the ISR. Here comes a different principle, than your firstly intended way: I would let the sensors count in their own ISR and own variables and only calculate the difference to display it. For that we need to define our 2 ISRs:

    void flowOutPulseCounter()
    {
        flowOutPulseCount++;
    }
    void flowInPulseCounter()
    {
        flowInPulseCount++;
    }

The count variables of course need to be defined (globally at the top of the sketch):

    volatile byte flowOutPulseCount = 0;
    volatile byte flowInPulseCount = 0;

Now we have left the code in `loop()`, which calculates flowrate, fill level and such and displays them. First: When handling interrupt data in the main code, you want to absolutely minimize the time spend with the interrupts deactivated (since in that time you might miss pulses and thus introduce errors). Normally you would just copy the data into local variables, turn on the interrupts again and do the calculation with the local variables. Something like this (inside the `millis()` if statement):

    // Detach interrupts
    detachInterrupt(digitalPinToInterrupt(flow_out_pin));
    detachInterrupt(digitalPinToInterrupt(flow_in_pin));

    // copy pulse count variables
    byte local_flow_out_count = flowOutPulseCount;
    byte local_flow_in_count  = flowInPulseCount;

    // reset pulse counter variables
    flowOutPulseCount = 0;
    flowInPulseCount = 0;

    // Reattach interrupts
    attachInterrupt(digitalPinToInterrupt(flow_out_pin), flowOutPulseCounter, FALLING);
    attachInterrupt(digitalPinToInterrupt(flow_in_pin), flowInPulseCounter, FALLING);

    // Do calculations using above local variables and display the results
    ...

For the calculations you would then calculate a flow rate and the total flow from each pulse count. With that you can then calculate the total net flow and the fill level.

Note: You might wanna change the variable type for the counters to `unsigned int` to get a greater margin, before they overflow, since that would mean incorrect results and it doesn't hurt you to use it.

body:
As chrisl already provided a very good answer, I am just adding some
notes here to complement it.

The variable `pulseCount` is only 8-bits. It will overflow if the flow
rate gets above 33.7 L/min. If the possibility exists that the
actual flow exceeds this rate, then, as pointed out in chrisl's answer,
you should use a 16-bit counter. If, on the other hand, you are sure
that this value cannot be exceeded, then you can keep an 8-bit counter,
and benefit from the fact that accesses to 8-bit values are _atomic_.
This means you do not need to ever disable interrupts:

```c++
// In global scope:
byte oldPulseCount;

// Within loop(), once per second:
byte newPulseCount = pulseCount;  // atomic read
byte pulseCountDifference = newPulseCount - oldPulseCount;
oldPulseCount = newPulseCount;  // save current value
```

then you compute the flow rate from `pulseCountDifference`. Note that
overflows of `pulseCount` are harmless, as the difference
`newPulseCount - oldPulseCount` wraps modulo 256 to the correct value.
Note also that `pulseCount` is never reset, as doing so could lead to
miscounting whenever an interrupt fires after `pulseCount` is read but
before it is reset.

> ```c++
> // Note the time this processing pass was executed. Note that because
> // we've disabled interrupts the millis() function won't actually be
> // incrementing right at this point, but it will still return the value
> // it was set to just before interrupts went away.
> oldTime = millis();
> ```

This comment is wrong. The statement `detachInterrupt(sensorInterrupt)`
disables _only_ an external interrupt. It does not disable interrupts
globally, and specifically does not disable the timer interrupt that
increments `millis()`. There is therefore no guarantee that the various
calls to `millis()` will return the same value within one iteration.
Instead, `millis()` should be called only once, and its value
remembered:

```c++
void loop()
{
    unsigned long now = millis();  // save this value
    if (now - oldTime >= 1000) {
        // ...
        oldTime = now;
    }
}
```

Note that I use `>=` for checking the delay: with the `>` operator the
period is at least 1001 ms.

> ```c++
> flowMilliLitres = (flowRate / 60) * 1000;
> ```

This is incorrect. It should be

```c++
flowMilliLitres = (flowRate / 60) * (now - oldTime);
```

for the same reason that `now - oldTime` is used in the computation of
`flowRate`. It may be noted that this can be simplified to

```c++
flowMilliLitres = (1e3/calibrationFactor/60) * pulseCountDifference;
```

as the factors `now - oldTime` cancel out.


body:
I'm interested in writing an "Arduino core" (i. e. porting Arduino to a new MCU and new board(s)).  I'm having trouble finding much documentation on how to do so.  Am I missing something?

[This page](https://www.arduino.cc/en/guide/cores) says "anyone may develop a core for their own boards following the rules and requirements we have issued."  So, where are those "rules and requirements?"

I found something called the "[Platform Specification](https://arduino.github.io/arduino-cli/latest/platform-specification/)", which sounded promising, but it only documents the config files; it does not say anything about the code that needs to be written to support a new platform.

I found [ArduinoCore-API](https://github.com/arduino/ArduinoCore-API), which says it is the "hardware independent layer of Arduino core."  But it doesn't mention anything about how to write the hardware-dependent part of the core.

I'd be grateful if anyone could point me to the Arduino core documentation.  It's not turning up in my web searches.  Thanks!

**Clarifications:**

* Yes, I can look at existing cores as examples, but I'd rather have the documentation, as well.  Especially since existing cores may be of varying quality, or may not be up to the latest standard.  Documentation is always a good thing.
* The reason I want to write a core is because... I want to use an MCU which is not currently supported!  (Specifically, I want to add support for the [GD32F350](https://www.gigadevice.com/microcontroller/gd32f350cbt6/), but really that shouldn't be relevant to answering "Where is the documentation?")

title: Where is the documentation for writing an Arduino core?

Answers: 1

body:
There are two major parts to writing an Arduino core: the hardware independent portions and the hardware dependent.

The hardware independent portions are pretty much done for you in the ArduinoCore-API. However I wouldn't just use that verbatim but use it as a starting point and adapt it to your needs. This is because it actually has a couple of unresolved issues and not everything may 100% fit your needs. We don't use it for the chipKIT core because:

* It has an unresolved issue around the naming of the `String.h` file which conflicts with the libc's `string.h` on case insensitive filesystems
* Our USB stack is vastly different to how the Arduino "Pluggable USB" works
* We have extra facilities in a number of standard objects to make use of more efficient use of more advanced hardware

Once you have the hardware independent portion sorted you need to write, from scratch, the hardware dependent portion.  The basic list of functions you *need* to implement are listed in the [Arduino reference](https://www.arduino.cc/reference/en/). How you write them cannot be documented, since that depends on the hardware. And you may well need to (or want to) write considerably more functions that just those. For example on chipKIT as well as the standard `analogWrite()` function we also have functions to change the PWM frequency and resolution - things that aren't part of the "standard", but are incredibly useful.

A good starting point is to examine the Arduino.h file of an existing core (the AVR core is a good baseline) which will list most of the functions and their parameter/return types. That gives you what the functions expect to receive and what they should emit, but *how* those functions are written is completely down to you.

And then of course you have to implement the boards variants etc to make the whole things work...

Also, be warned that writing (and maintaining) a core is a long and involved process and will consume the rest of your life.


body:
Recently I started some tests controlling water heater with temperature sensor data as described in detail [here][1]

So far I've been testing a small dataset to control water temperature that is quite easy to write down by myself.

```
#include <NTPClient.h>
#include <WiFi.h>
#include <WiFiUdp.h>

//WiFi Conf
const char *ssid     = "ssid_addr";
const char *password = "wifi_password";
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP);
unsigned long current_time;

// Sensors Conf (fixed value just to test relay response)
float temperature = 30.5;

//Relay Conf
const int relay = 26;

struct SetPoint {
  unsigned long time;
  float temperature;
};

#define DATA_SIZE  8

SetPoint scen1[DATA_SIZE] = {
  {1616952559, 32.4},
  {1616952739, 10.2},
  {1616952859, 10.4},
  {1616952867, 40.2},
  {1616952927, 20.4},
  {1616952928, 35.2},
  {1616952945, 22.4},
  {1616952947, 28.2}
  };

unsigned int pos = 0;

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

  pinMode(relay, OUTPUT);

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

  timeClient.begin();

}

void loop() {
  timeClient.update();

  long current_time =  timeClient.getEpochTime();

  if (pos < DATA_SIZE && current_time >= scen1[pos].time) {
    set_thermostat(/*data[pos].temperature, temperature*/);
    pos++;
  }

  Serial.println(timeClient.getEpochTime());
  Serial.println(timeClient.getFormattedTime());
  Serial.println(pos);
  delay(3000);

}

void set_thermostat() {
  if (temperature < scen1[pos].temperature) {
    digitalWrite (relay, HIGH);
  }
  else if (temperature > scen1[pos].temperature) {
    digitalWrite (relay, LOW);
  }
}
```

But now I'm planning to use a larger file with different datapoints and an option is to store them in a sdcard and, then, the microcontroller parses each line to control the temperature with an interval of three hours.

There will be about 720 lines with the following structure ("Scen" is the temperature simulation scenarios that will be the reference to turn the relays on or off):

```
    Time,UNIX,Scen1,Scen2,Scen3
    21/04/2021 00:00:00,1618963200,"27.45","29.01","30.85"
    21/04/2021 21:00:00,1619038800,"26.16","27.82","29.75"
    21/04/2021 06:00:00,1618984800,"25.28","26.83","29.02"
    21/04/2021 09:00:00,1618995600,"24.62","26.49","28.51"
    21/04/2021 12:00:00,1619006400,"27.19","29.47","29.53"
    21/04/2021 15:00:00,1619017200,"30.65","34.07","30.50"
    21/04/2021 18:00:00,1619028000,"31.87","35.78","31.78"
    21/04/2021 21:00:00,1619038800,"30.43","35.20","30.88"
    22/04/2021 00:00:00,1619049600,"28.45","31.86","29.47"
```

The problem is that it is hard to find out how to parse data from the file into two variables (UNIX Time and temperature), for each temperature scenario, as used here:

```
struct SetPoint {
  unsigned long time;
  float temperature;
};

#define DATA_SIZE  8

//scenario 1 array
SetPoint scen1[DATA_SIZE] = {
  {1616952559, 32.4},
  {1616952739, 10.2},
  {1616952859, 10.4},
  {1616952867, 40.2},
  {1616952927, 20.4},
  {1616952928, 35.2},
  {1616952945, 22.4},
  {1616952947, 28.2}
  };

```

Is there an effective way to get what I'm looking for?

  [1]: https://arduino.stackexchange.com/questions/82148/reproduce-simulated-temperature-data-with-arduino/82151#82151

title: Parsing read SD file into 2 variables

Answers: 0


body:
I am trying to read data from the registers 6, 7, 8 and 9 of the STC3100 ([Data Sheet][1]) using an arduino uno.

I followed this tutorial: https://howtomechatronics.com/tutorials/arduino/how-i2c-communication-works-and-how-to-use-it-with-arduino/ And adjusted the device and register adress accordingly.

This isn't working and instead of returning the data on the register I'm just getting 16 over and over again.

Here is my code:

```
#include <Wire.h>
int ADXLAddress = 0x70;

#define X_Axis_Register_DATAX0 0x08

#define X_Axis_Register_DATAX1 0x09

#define Power_Register 0x00

int X0,X1,X_out;

void setup() {

  Wire.begin();

  Serial.begin(9600);
  delay(100);
  Wire.beginTransmission(ADXLAddress);
  Wire.write(Power_Register);
  Wire.write(16);
  Wire.endTransmission();
}
void loop() {
  delay(2000);
  Wire.beginTransmission(ADXLAddress);

  Wire.write(X_Axis_Register_DATAX0);
  Wire.write(X_Axis_Register_DATAX1);

  Wire.endTransmission();

  Wire.requestFrom(ADXLAddress,2);

  if(Wire.available()<=2) {
    X0 = Wire.read();
    X1 = Wire.read();
  }

  Serial.print("X0= ");
  Serial.print(X0, BIN);
  Serial.print("   X1= ");
  Serial.println(X1, BIN);
}
```

  [1]: https://www.st.com/resource/en/datasheet/stc3100.pdf

title: Can't read data from registers using I2C

Answers: 1

body:
The following code shows, how I would read from a STC3100. But I own none of them, so I can not try the code. I would be very surprised if it works directly. Use it as an example. Perhaps we could improve it together. ;-)

    #include <Wire.h>

    #define STC_ADDRESS 0x70
    #define MODE_REGISTER 0x00
    #define CURRENT_LOW_REGISTER 0x06
    #define VOLTAGE_LOW_REGISTER 0x08

    int voltage, current;
    int high_value = 0;

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

      Wire.begin();
      delay(100);
      // power on the STC
      Wire.beginTransmission(STC_ADDRESS);
      Wire.write(MODE_REGISTER);
      Wire.write(16);
      Wire.endTransmission();
    }

    void loop()
    {
      Wire.beginTransmission(STC_ADDRESS);
      Wire.write(VOLTAGE_LOW_REGISTER);
      Wire.requestFrom(STC_ADDRESS, 2);
      delay(500);
      if( Wire.available() > 0 )
      {
        voltage = Wire.read();
        //Serial.print("REG 8 = ");
        //Serial.println(voltage);
      }
      delay(500);
      if( Wire.available() > 0 )
      {
        high_value = Wire.read();
        //Serial.print("REG 9 = ");
        //Serial.println(high_value);
        voltage += (high_value << 8);
        //Serial.print("voltage = ");
        //Serial.println(voltage);

      }
      Wire.endTransmission();

      Wire.beginTransmission(STC_ADDRESS);
      Wire.write(CURRENT_LOW_REGISTER);
      Wire.requestFrom(STC_ADDRESS, 2);
      delay(500);
      if( Wire.available() > 0 )
      {
        current = Wire.read();
        //Serial.print("REG 6 = ");
        //Serial.println(current);
      }
      delay(500);
      if( Wire.available() > 0 )
      {
        high_value = Wire.read();
        //Serial.print("REG 7 = ");
        //Serial.println(high_value);
        current += (high_value << 8);
        //Serial.print("current = ");
        //Serial.println(current);
      }
      Wire.endTransmission();

      Serial.print("V= ");
      Serial.print(voltage);
      Serial.print("   C= ");
      Serial.println(current);
    }


body:
I'm trying to interface MCP3903. I haven't really don't any SPI interfacing before and I can't seem to find clear enough answer for newbs. Please bare with me.

I'm trying to use this library. http://www.kerrywong.com/2014/05/10/mcp3903-library/

On the website there is the following circuit diagram.

[![enter image description here][1]][1]

  [1]: https://i.stack.imgur.com/K79k8.png

I can see SDI, SDO pins on the ESP module, how do I connect the SCK and CS pins? If they can be any pins how do I declare them on the test program on the website?

Thank you

title: Interfacing SPI (MCP3903)

Answers: 1

body:
SPI0 and SPI1 are used internally to access the ESP32’s attached flash memory. SPI2 and SPI3 are general purpose SPI controllers, sometimes referred to as HSPI and VSPI, respectively. They are open to users.

A quick google search shows:

[![ESP32 Wroom Pinout][1]][1]

So you can use IO5, IO18, IO19 and IO23.

  [1]: https://i.stack.imgur.com/kzjwK.png


body:
I am reaching out for help on a project I am working on. We are trying to integrate a reaction torque sensor and I am having a hard time deciding how to go about it. Previously I assumed that like my load cell I would be able to use the HX711 module to connect my Torque sensor to my Arduino. The Torque sensors uses a Wheatstone bridge configuration, which is great for this module. The problem I ran into is that the TRT-25 Torque sensor requires an excitation voltage of 10V and my Arduino is only supplying 5V. When I tried powering my sensor separately with 10V I quickly found out that these HX711 modules are not designed to handle 10V...

Needless to say that I am now wondering how I should be power my sensor, but also which A/D converter can be used to get this working. The same manufacturer sells all the components to get this working, but it is hundreds of dollars more and our budget doesnt allow for it. I am posting links here so you can see the sensor. What I am considering now is finding a 10V source and connecting the signal pins to my analog pins on my Arduino. I am hoping based on the raw value I can compute a torque measurement based upon this small piece of information their tech support gave me.  (X mv/v * EXCITATION v = TORQUE in/lbs).

FYI, I dont have much more information outside of what it is on the site for the sensor. My project uses a small enclosure and I have a arduino proto shield to power my other 3 sensors. I am limited on space but could probably incorporate a small supply and replace the current HX711 module.

[HX711][1]

[https://www.transducertechniques.com/trt-torque-sensor.aspx][2]
[![S][3]][3]

  [1]: https://www.sparkfun.com/products/13879
  [2]: https://www.transducertechniques.com/trt-torque-sensor.aspx
  [3]: https://i.stack.imgur.com/v2JYq.png

title: TRT-25 and Arduino Uno

Answers: 0


body: I want to use the internal reference voltage (1.2V) of stm32f103 blue pill using Arduino IDE. I searched the whole internet but couldn't find anything. I need help with this. Thanks.

title: Stm32 Blue Pill Internal reference voltage Arduino IDE

Answers: 1

body:
There's no way of using the internal 1,2v reference as the ADC reference. (in the same way that you can do on an AVR)
You can only use the ADC to read the internal vref, and use that value to adjust the next ADC reading you take. Like a compensation factor.


body:
LM2596 is easy to use and cheap, but I have to adjust the output voltage using a screw driver. On the web, there was a "hack" that someone posted, but that hack does not seem as clean or stable as using LM2596 as it is intended to be used, using screw driver. Is there something that is easy-to-use just like LM2596, but has some pins that can be used to dynamically adjust the output voltage using an Arduino?

[![enter image description here][1]][1]

  [1]: https://i.stack.imgur.com/xBM7E.jpg

title: Programmatically-adjustable buck converter module?

Answers: 1

body:
The hack you described is most likely just feeding voltage from filtered PWM signal generated by microcontroller to the feedback loop of LM2596. I think you can get good enough noise performance with this approach if voltage change rate is not a concern. It all comes down to the PWM filter parameters. You can decrease noise by adjusting RC filter parameters (increasing capacitor and resistor values). It will cause increased delay in voltage change, but it will reduce the noise from PWM signal. Also, you can increase the PWM frequency by avoiding standard analogWrite which has pretty low frequency and configuring a separate timer for PWM generation.
Alternatively, if you need some specific voltages, you can replace the potentiometer with a fixed value resistor array connected in parallel and connect each resistor though separate low power MOSFET. This way, you can connect and disconnect a specific resistor which will change the total resistance of the array, changing the output voltage. It will only allow changing voltage by steps and the step size is dictated by the number of resistors, but the noise performance will be the same as using a potentiometer.


body:
Can anyone please tell me how to declare a char variable using a few integers?

I need to declare a byte information for `shiftOut()` function as char.

```
int a = 0;
int b = 1;
int c = 0;
int d = 1;
int e = 1;
int f = 0;
int e = 0;
int f = 1;

char information[] = {"B" + a + b + c + d + e + f};

void setup() {
  Serial.println(information);
}

void loop() {
  shiftOut(pin, pin, MSBFIRST, information);
}
```

In command `Serial.println(information);` I want to get back `B01011001`

Now the output I am getting `⸮⸮`

Of course the simpliest way to create that will be:

`char information[] = "B01011001";`

But I need to change the individual bits in `int bit =` variable.

Please note that substition `int bit =` with `char bit =` is unable for my code, using int of value of individual bits is necessarily. Because I am using my project with blynk, and there is function `a = param.asInt();` ,  `param.asChar();` does not exist.

How to do that?

Thank you for responses!

title: How to declare char array[] using integers?

Answers: 1

body:
I think you are getting something wrong about `shiftOut()`. It will transfer exactly 1 byte (or 1 `char`). It does not take an array as parameter. I guess you want to write the 8 bits, that you are defining with your `int`s, as one byte out. Defining at byte directly would look like this:

    byte information = 0b00101100;

The `0b` tells the compiler, that the following number is encoded in binary. So you have one single byte, that contains all your information (all the bits). Then you can do

    shiftOut(data_pin, clock_pin, MSBFIRST, information);

(Please note, that the data_pin and the clock pin need to be different).

If you want to print the `information` variable to Serial, showing the binary representation, you can use the corresponding parameter of the `print()` function.

    Serial.print(information, BIN);

Will print the binary representation (zeros and ones as text) of the variable. So, to get "B1011001", you would do:

    Serial.print("B");
    Serial.println(information, BIN);

Note, that the `print()`/`println()` function will remove all leading zeros.

---

How to put the `information` byte with your `int`s? Each of them is either zero or one and represents one bit. So you can use the bitwise operators to put them together:

    information = (a << 7) | (b << 6) | (c << 5) | (d << 4) | (e << 3) | (f << 2) | (g << 1) | h;

For each `int` only the first (Least significant) bit is important, since the others are always zero (because the int can be only one or zero). So we shift the `int` value to the left by the number of the corresponding bit minus 1 (so shifting `a` 7 places to the left to put its least significant bit to the most significant bit of `information`. We are doing that for all our `int` values. Then we put them all together into one byte by using the `|` (bitwise OR) operator.

**Note:** We don't know, where these `int`s are coming from. Even when stating, that you absolutely need those `int`s, you could organize them in an array instead of single variables. That would look like this:

    int int_data[8] = {0, 0, 1, 0, 1, 1, 0, 0};
    ...
    // in a function (like loop() or setup())
    byte information = 0;
    for(int i=0;i<8;i++) information |= int_data[7-i] << i;

It's up to you, if you want to do that.


body:
Here's a small problem I encountered while I was trying to make this small header file `Devices.h`:
 >Is it possible to use templates with abstract classes ? If yes, how and how can I use that abstract class to derive another class ?

Here's the contents of the header file :
```
#ifndef Devices_h
#define Devices_h

/* Initial build for MCUOS
Anybody can edit this according to their device needs */

#include "Arduino.h"

template < typename datatype>

class Device_Handler
{
    // a class to handle devices
 public:
  virtual void write_to_device(datatype *send_data)= 0; // write data to device
  virtual void read_from_device(datatype *store_location)= 0 ; // read data from device to location
  virtual void clear_device() = 0; // clear device state
};

class Serial_Handler:public Device_Handler<char*>
{
   public:
          void write_to_device(char *send_data);
          void read_from_device(char *store_location);
          void clear_device();
};

void Serial_Handler<char*>::write_to_device(char *send_data){
        Serial.println(*send_data);
 }

void Serial_Handler<char*>::read_from_device(char *store_location){
       *store_location = Serial.read();
}

void Serial_Handler::clear_device(){
        Serial.flush();
}

#endif
```

This is a small project I am trying at home nowadays (that MCUOS thing up there), also considering it a learning opportunity. I am not sure if I wrote the code in the header the right way. Initially, I made the `Device_Handler` class and used it in my sketch to craft the `Serial_Handler` class, but then it showed an error that the compiler expected a class name before the '{' character right at the place where I started writing the code for the derived class. Thus I decided to move the code for the derived class to the header, but I decided to seek your advice before heading further as I fear that more errors may come up and as I am kind of a beginner at C++.

Thanks in advance !

EDIT : I also doubt if it was because I wrote a comment near the starting line of the abstract class as the syntax highlighter here showed the comments in colour.

**Edit**: I resolved the issue up there (it was due to the misplaced comment), but a new issue has popped up saying that it expected an initialiser before the '<' token at the places where I had defined the functions in the derived class. This is where my actual is.

My snippets of main concern:
```
void Serial_Handler<char>::write_to_device(char *send_data){
        Serial.println(*send_data);
 }

void Serial_Handler<char*>::read_from_device(char *store_location){
       *store_location = Serial.read();
}
```

I doubt if these will be able to handle long sentences or have syntax errors.

**Edit**
I decided to move forward despite errors. Here's how I remade my header file:

```
#ifndef Devices_h
#define Devices_h

/* Initial build for MCUOS
Anybody can edit this according to their device needs */

#include "Arduino.h"

template < typename datatype>
class Device_Handler
{
               // a class to handle devices
 public:
  virtual void write_to_device(datatype *send_data)= 0; // write data to device
  virtual void read_from_device(datatype *store_location)= 0 ; // read data from device to location
  virtual void clear_device() = 0; // clear device state
};

class Serial_Handler:public Device_Handler<char*>
{
   public:
          void write_to_device(char *send_data);
          void read_from_device(char *store_location);
          void clear_device();
};

void Serial_Handler::write_to_device(char *send_data){
        Serial.println(*send_data);
 }

void Serial_Handler::read_from_device(char *store_location){
       *store_location = Serial.read();
}

void  Serial_Handler::clear_device(){
        Serial.flush();
}

#endif
```

Here's the sketch code:
```
#include <Devices.h>

Serial_Handler myserial;
char storage = '\0';
char test_string[] = "Hello";

void setup() {
  Serial.begin(9600);
  myserial.write_to_device(test_string);
  myserial.read_from_device(&storage);
}

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

}
```
(I know that the code up there may also be faulty)
and errors come up:
```
Arduino: 1.8.13 (Windows 10), Board: "Arduino Uno"
Devices_Test:3:16: error: cannot declare variable 'myserial' to be of abstract type 'Serial_Handler'

 Serial_Handler myserial;

                ^~~~~~~~

In file included from C:\Users\<smbdy>\Documents\Arduino\Devices_Test\Devices_Test.ino:1:0:

C:\Users\<smbdy>\Documents\Arduino\libraries\Devices/Devices.h:19:7: note:   because the following virtual functions are pure within 'Serial_Handler':

 class Serial_Handler:public Device_Handler<char*>

       ^~~~~~~~~~~~~~

C:\Users\<smbdy>\Documents\Arduino\libraries\Devices/Devices.h:14:16: note:  void Device_Handler<datatype>::write_to_device(datatype*) [with datatype = char*]

   virtual void write_to_device(datatype *send_data)= 0; // write data to device

                ^~~~~~~~~~~~~~~

C:\Users\<smbdy>\Documents\Arduino\libraries\Devices/Devices.h:15:16: note:  void Device_Handler<datatype>::read_from_device(datatype*) [with datatype = char*]

   virtual void read_from_device(datatype *store_location)= 0 ; // read data from device to location

                ^~~~~~~~~~~~~~~~

exit status 1

cannot declare variable 'myserial' to be of abstract type 'Serial_Handler'

```

How should I resolve this?

title: Help On Creating Derived classes in Headers

Answers: 1

body:
You are on the track, but it needs some adjustments:

    template < typename datatype>
    class Device_Handler
    {
        // a class to handle devices
        public:
            virtual void write_to_device(datatype *send_data)= 0; // write data to device
            virtual void read_from_device(datatype *store_location)= 0 ; // read data from device to location
            virtual void clear_device() = 0; // clear device state
    };

    class Serial_Handler:public Device_Handler<char> // instead of char*
    {
       public:
           void write_to_device(char *send_data) override;
           void read_from_device(char *store_location) override;
           void clear_device() override;
    };

    void Serial_Handler::write_to_device(char *send_data){ // It's not template, so no template specialization
            Serial.println(*send_data);
     }

    void Serial_Handler::read_from_device(char *store_location){
           *store_location = Serial.read();
    }

    void Serial_Handler::clear_device(){
            Serial.flush();
    }

The alternative is:

    template < typename datatype>
    class Device_Handler
    {
        // a class to handle devices
        public:
            virtual void write_to_device(datatype send_data)= 0; // write data to device
            virtual void read_from_device(datatype store_location)= 0 ; // read data from device to location
            virtual void clear_device() = 0; // clear device state
    };

    class Serial_Handler:public Device_Handler<char*>
    {
       public:
           void write_to_device(char *send_data) override;
           void read_from_device(char *store_location) override;
           void clear_device() override;
    };


body:
I´m trying to make a pause in a loop, but just for the first time it loops. The next loops i would like the program to NOT do the pause. Just once time, each time a button is pressed. Does anybody knows how to do it?
Thanks!
This is the code i want to pause just once:

    void loop() {
      if(digitalRead(switch_pin) == LOW){
        digitalWrite(led_green_pin,LOW);
        digitalWrite(led_red_pin,HIGH);
        lastMotionState    = currentMotionState;
        currentMotionState = digitalRead(MOTION_SENSOR_PIN); //
          if (currentMotionState == LOW && lastMotionState == HIGH) {
          servo.write(90);
          }
          else
          if (currentMotionState == HIGH && lastMotionState == LOW) { // pin state change: HIGH -> LOW
          servo.write(0);
          }
      }

title: How do I pause a loop just once?

Answers: 2

body:
The following code will pause (Give some delay) when it runs for the first time and also when you press the button.

```

void loop() {
  static int status = true;
  if(status){
    //Pause
    delay(15);
    status=false;
    return;
  }

  if(digitalRead(switch_pin) == LOW){
    digitalWrite(led_green_pin,LOW);
    digitalWrite(led_red_pin,HIGH);
    lastMotionState    = currentMotionState;
    currentMotionState = digitalRead(MOTION_SENSOR_PIN); //
      if (currentMotionState == LOW && lastMotionState == HIGH) {
       servo.write(90);
      }
      else if (currentMotionState == HIGH && lastMotionState == LOW) { // pin state change: HIGH -> LOW
       servo.write(0);
      }
  }
  else{
    status = true;
  }
}
```

Give delay according to your need.

body:
This is pretty simple, although you shouldn't see any difference, because `loop()` is running a lots of times in one second. But:

```cpp
bool firstrun = true;
void loop() {
  if(firstrun == true){};
  else{
    if(digitalRead(switch_pin) == LOW){
      digitalWrite(led_green_pin,LOW);
      digitalWrite(led_red_pin,HIGH);
      lastMotionState    = currentMotionState;
      currentMotionState = digitalRead(MOTION_SENSOR_PIN); //
        if (currentMotionState == LOW && lastMotionState == HIGH) {
          servo.write(90);
        }
        else if (currentMotionState == HIGH && lastMotionState == LOW) { // pin state change: HIGH -> LOW
          servo.write(0);
        }
    }
  }
  firstrun = false;
}
```