# Question
Title: Serial.read(); and state machine for AT commands
I have a strange type of issue: the index of the array doesn't increment and when I print the value from the *serialdata\[pointingfinger\]* it just gives me an empty space. This is a state machine (I guess) that should check what is the current char that's being written into the array and its position to avoid searching it later. When we have a finished line it changes the bigger state machine to another mode (that checks if four chars further is the command) when the processing is done it should get back getting the next line.

This is Arduino Leonardo and Serial is the USB and Serial1 is where I send and receive AT commands.

```
const long interval = 1000;
static long currentMillis;

char plussignpoint = 0; //To determine where is the + in +CCLK in the char array

char serialdata[256] = ""; //Array to store the chars before parsing

int rdpos = 0;

int pointingfinger = 0;

char timeen = 0;
byte stat0 = 0;
char futstat0 = 0;
char searchcharpos = 0;

char enabled = 0;

char searchchartype = 0;

char smsvalid = 0;

void setup()
{
  Serial.begin(9600);
  Serial1.begin(9600);
  Serial1.write("ATE0\r");
}

void loop() {
    if (millis() - currentMillis >= interval)
    {
      Serial1.print("AT+CCLK?\r"); //ask for the time

      enabled = 1;

      currentMillis = millis();
    }

    if (enabled == 1) {
      if (stat0 == 0) {
        if (Serial1.available () > 0) {
          pointingfinger++;
          serialdata[pointingfinger] = Serial1.read();
          if (serialdata[pointingfinger] == '+') {

            searchcharpos = pointingfinger;
            searchchartype = 1;
            futstat0 = 1;
          }
          else if (serialdata[pointingfinger] == '$') {
            if (smsvalid = 1) {
              searchcharpos = pointingfinger;
              searchchartype = 2;
              futstat0 = 2;
            }
            if (smsvalid = 0) {
              stat0 = futstat0;
              pointingfinger = 0;
            }
          }
          else if (serialdata[pointingfinger] == '\n') {
            stat0 = futstat0;
            pointingfinger = 0;
            enabled = 0;
          }
          else if (serialdata[pointingfinger] == '\r') {
            stat0 = futstat0;
            pointingfinger = 0;
            enabled = 0;
          }
          else {
            stat0 = 0;
            pointingfinger = 0;
          }
        }

        if (pointingfinger == 255) {
          pointingfinger = 0;
          enabled = 0;
        }

      }
    }
}

```

**EDIT:** I forgot to include what AT commands it should parse:

```
Arduino: AT+CCLK?

SIM800H: +CCLK: "04/01/01,01:35:31+00"

         OK

```

# Answer
> 2 votes
When checking value of `smsvalid` you use assignment operator `=` instead of comparison operator `==`.

```
            else if (serialdata[pointingfinger] == '$') {
                if (smsvalid == 1) {
                    searchcharpos = pointingfinger;
                    searchchartype = 2;
                    futstat0 = 2;
                }
                if (smsvalid == 0) {
                    stat0 = futstat0;
                    pointingfinger = 0;
                }
            }

```

And also you increment `pointingfinget` prior writing to `serialdata` buffer. This means that the first character will be written at index 1. So the first character serialdata will be zero, which means empty string.

```
      pointingfinger++;
      serialdata[pointingfinger] = Serial1.read();

```

There are many issues with your code, I pasted your code to online gdb c++ compiler, so you can play with it and see what is going on.

Those AT state machines aren't easy to finetune on Arduino. I spent a lot of time debugging similar code and found out that the best way is to unit test all possible situations in visual studio or xcode. Arduino is just C++ and if you copy/paste some portions of your code to C++ IDE, after implementing few functions or classes it should work. For example, to make your code working in XCode, I had to implement some dummy Serial1 class and simplify the loop code:

```
class _Serial1
{
    std::string buffer{"OK\r\n"};
public:
    int available()
    {
        return (int)buffer.size();
    }

    char read()
    {
        char c = buffer[0];
        buffer.erase(0, 1);
        return c;
    }
} Serial1;

void loop() {
    if (enabled == 1) {
        if (stat0 == 0) {
            if (Serial1.available () > 0) {
                pointingfinger++;
                serialdata[pointingfinger] = Serial1.read();
                if (serialdata[pointingfinger] == '+') {

                    searchcharpos = pointingfinger;
                    searchchartype = 1;
                    futstat0 = 1;
                }
                else if (serialdata[pointingfinger] == '$') {
                    if (smsvalid == 1) {  // ==
                        searchcharpos = pointingfinger;
                        searchchartype = 2;
                        futstat0 = 2;
                    }
                    if (smsvalid == 0) { // ==
                        stat0 = futstat0;
                        pointingfinger = 0;
                    }
                }
                else if (serialdata[pointingfinger] == '\n') {
                    stat0 = futstat0;
                    pointingfinger = 0;
                    enabled = 0;
                }
                else if (serialdata[pointingfinger] == '\r') {
                    stat0 = futstat0;
                    pointingfinger = 0;
                    enabled = 0;
                }
                else {
                    stat0 = 0;
                    pointingfinger = 0;
                }
            }

            if (pointingfinger == 255) {
                pointingfinger = 0;
                enabled = 0;
            }

        }
    }
}

```

And the compiler immediatelly pointed me at the incorrect assignments and also I was able to debug the code step by step and see what is happening inside.

In my situation I was interfacing SIMCOM900 gprs module and I made a state machine that allows me to write code like this:

```
virtual void Program()
{
    switch (Pc())
    {
        case 0: _ASSERT(strlen(mApn)>0);
                Stream() << "AT+CSTT=\"" << mApn << "\",\"\",\"\"\r\n";
                break;
        case 1: Expect("OK\r\n");
                if (Expect("+CME ERROR")) { Error("CME Error when attaching apn"); Return(false);}
                if (Timeout(25000)) Return(false);
            break;
        case 2: Stream() << "AT+CIICR\r\n"; break;
        case 3: Expect("OK\r\n");
                if (Timeout(15000)) Next(); break;
        case 4: Stream() << "AT+CIFSR\r\n"; break;
        case 5: if (ReadIpAddress()) Next();
                if (Timeout(2000)) Return(false); break; // longer?
        default: Return(true);
    }
}

```

Here is a bit older version of it: https://gist.github.com/gabonator/88b80d9c6b16d699d6f4234ebc3a2587

---
Tags: serial
---


# Question
Title: Using an Arduino as a Human Interface Device that sends analog inputs
I would like to have an arduino board act as a human interface device that can send analog inputs like joysticks.

As it currently stands I see two aproaches to this issue:

1. Use the arduino hid library and program all the reports in myself. This should be fairly simple but I can't seem to find any recourses that I actually understand. I get the idea of reports but I dont get how the report format is described to the OS. I also dont understand how drivers on the pc side of things play into this whole equation.
2. Write some software that makes a serial connection with the arduino and uses java's robot functionality (or similar) to controll a joystick, if even possible. This method would be much easier but would feel overall less polished.

Thank you for your help in advance!

# Answer
> 0 votes
https://github.com/MHeironimus/ArduinoJoystickLibrary does my first aproach. The limitations one what board it can be will not be an issue because I have an extra 32u4 board.

---
Tags: usb
---


# Question
Title: Passing reference to hardware between methods in custom class
I'm a C++ / Arduino newbie, trying to build a custom library for the first time. I created a unit called `CDSensors.cpp`, which has two methods, `SetupSensor` and `ReadSensors`. The sensor is a SparkFun accelerometer/magnetometer.

If there are any errors in the settings, the sensor returns all zeros for compass and accelerometer. If there is no pointer or other connection between the `SetupSensor` and `ReadSensor` methods, the sensor returns all zeros as if it hasn't been setup.

So I'm trying to pass a reference to the sensor library between the methods as shown with the Limu object in the code below. I now get mag data but the accelerometer returns all zeros so something in my object references is messing with the sensor setup? (the accelerometer works ok in the SparkFun demo code, on which my code is based).

Main.ino

```
#include <CDSensors.h>
#include <Wire.h>
#include <SPI.h>
#include <SparkFunMPU9250-DMP.h>

CDSensors* LSensors = &CDSensors     (0);
CDSerialPrint* LSerialPrint = &CDSerialPrint (0);
MPU9250_DMP Limu = MPU9250_DMP ();
unsigned long LTimeNow = 0;

struct meas {
  int BUx;
  int acc_x
};

struct meas r;

void setup() {
  LSensors->SetupSensors (Limu);
}

void loop() {
  LSensors->ReadSensors  (Limu, LTimeNow, r.BUx, r.acc_x);
  Serial.print((int) (r.BUx) );
  Serial.print((int) (r.acc_x) );
}

```

CDSensors.h

```
#ifndef CDSensors_h_h
#define CDSensors_h
#include <Wire.h>
#include <SPI.h>
#include <SparkFunMPU9250-DMP.h>

class CDSensors {
  public:
    CDSensors(int);
    static void SetupSensors(MPU9250_DMP *imu);
    void ReadSensors (MPU9250_DMP *imu, unsigned long& TimeNow, int&     BUx,int& BUy,int& BUz,int& acc_x,int& acc_y,int& acc_z,int& a0,int& a1,int& a2,int& a3 );
  private:
    int value;
};
#endif

```

CDSensors.cpp

```
#include <Wire.h>
#include <SPI.h>
#include <SparkFunMPU9250-DMP.h>
#include "CDSensors.h"

//MPU9250_DMP imu;
boolean       MPU9250_found = false;
unsigned long TimeNow = 0;
CDSensors::CDSensors(int givenValue) {
  value = givenValue;
}

static void CDSensors::SetupSensors(MPU9250_DMP imu) {
  if (imu.begin() != INV_SUCCESS) {
    while (1) {
      Serial.println("No MPU-9250 found, Check connections");
      delay(5000);
    }
  }
  imu.setSensors(INV_XYZ_ACCEL | INV_XYZ_GYRO | INV_XYZ_COMPASS);
  imu.setGyroFSR(2000);
  imu.setAccelFSR(2);
  imu.setLPF(188);
  imu.setSampleRate(100);
  imu.setCompassSampleRate(100);
}

void CDSensors::ReadSensors(MPU9250_DMP imu, unsigned long& TimeNow, int& BUx, int& acc_x) {
  TimeNow = millis();
  if (imu.dataReady()) {
    imu.update(UPDATE_ACCEL | UPDATE_GYRO | UPDATE_COMPASS);
  }
  BUx = imu.calcMag(imu.mx);
  acc_x = imu.calcAccel(imu.ax);
}

```

# Answer
> 1 votes
I don't think you are creating instances of these classes correctly. Instead of:

```
CDSensors*     LSensors      = &CDSensors     (0);
CDSerialPrint* LSerialPrint  = &CDSerialPrint (0);
MPU9250_DMP   Limu = MPU9250_DMP ();

```

How about:

```
CDSensors LSensors (0);
CDSerialPrint LSerialPrint (0);
MPU9250_DMP Limu;

```

I can't get your code to compile, but what I suggest looks a lot simpler.

---

Is your intention here:

```
if (imu.begin() != INV_SUCCESS)
  imu.setSensors(INV_XYZ_ACCEL | INV_XYZ_GYRO | INV_XYZ_COMPASS);
  imu.setGyroFSR(2000);
  imu.setAccelFSR(2);
  imu.setLPF(188);
  imu.setSampleRate(100);
  imu.setCompassSampleRate(100);

```

.. to really be:

```
if (imu.begin() != INV_SUCCESS)
  {
  imu.setSensors(INV_XYZ_ACCEL | INV_XYZ_GYRO | INV_XYZ_COMPASS);
  imu.setGyroFSR(2000);
  imu.setAccelFSR(2);
  imu.setLPF(188);
  imu.setSampleRate(100);
  imu.setCompassSampleRate(100);
  }

```

The indentation suggests so.

---

> if I understood correctly the class is created on startup with
>
> ```
>        CDSensors* LSensors = &CDSensors (0);
>
> ```
>
> and is then persistent.

`LSensors` is a persistent *pointer* but `CDSensors (0)` is a temporary object created for the purpose of doing an assignment. For example:

```
int foo = 2 + 3;

```

Now the compiler calculates 2 + 3 (giving 5), assigns that to foo, and then discards the temporarily-calculated 5 used to do the assignment.

In your case `CDSensors (0)` calls the constructor for CDSensors, creating a temporary object. Then the "&" operator takes its address (somewhere on the stack I would guess). This address is copied into LSensors. Then the object is destroyed because its lifetime is over. The compiler even warns you this is happening:

```
 CDSensors*     LSensors      = &CDSensors     (0);
                                                 ^
sketch_may07a:5: error: taking address of temporary [-fpermissive]

```

That means the pointer is now invalid because the underlying object (that it is pointing to) has now been discarded.

---

I've even seen people do something like this quite a bit:

```
     CDSensors LSensors = CDSensors (0);

```

This isn't so bad because pointers aren't involved, but it still involves making a temporary instance of the class, then *copying* that into LSensors, and discarding the original one.

*This* is how to make a new instance of a class:

```
 CDSensors LSensors (0);   // the actual class, not a pointer

```

Or if you want a pointer:

```
 CDSensors * pLSensors;  // a pointer to the class (initially NULL)

```

Then in `setup` you create the instance:

```
pLSensors = new CDSensors (0);

```

---
Tags: library, accelerometer, class, magnetometer, object-oriented
---


title: Strage delay needed after Serial.read()

text:
# Question
Title: Strage delay needed after Serial.read()
I'm using a RedBear Duo to read the Serial writes from a RedBear Nano v2. Basically, I use a digital pin of the Duo to raise an interrupt on the Nano. Once, the nano catches the interrupt it writes on its Serial.

You can find a minimum working example below:

### RedBear Duo

```
#include <Wire.h>

/*BLE and WiFi setup*/
#if defined(ARDUINO)
SYSTEM_MODE(MANUAL);
#endif

char incomingByte;   // for incoming serial data

void setup() {
    Serial1.begin(115200);     // opens serial port, sets data rate to 9600 bps
    delay(500);
    Serial1.println("Begin!");
    Serial2.begin(115200);

    pinMode(D5, OUTPUT);
}

void readSerial() {
    while (Serial2.available() > 0) {
        incomingByte = Serial2.read();
        Serial1.print(incomingByte);
    }
    Serial1.println(" ");

}

void loop() {
    digitalWrite(D5, HIGH);
    readSerial();
    delay(2);     // Here's the delay I'm talking about
    digitalWrite(D5, LOW);
    delay(1000);
}

```

### RedBear Nano

```
uint8_t fire;
void task_handle(void) {
    fire = 1;
}

void setup() {
    Serial.begin(115200);
    fire = 0;
    pinMode(D4, INPUT);
    attachInterrupt(D4, task_handle, RISING);
}

void loop() {
    if (fire == 1) {
        fire = 0;
        Serial.write("hello ");
        // Serial.println("fire");
        digitalWrite(D13, HIGH);
    }
    delay(150);
}

```

I found this question (https://electronics.stackexchange.com/questions/28739/arduino-delay-of-1ms-necessary-between-serial-read-and-serial-write), and I understood that the problem might be the fact that it takes a while to empty the Serial buffer.

However, I tried to bring the baudrate at 500000 (more than 3x) and still if I change the delay to delay(1), the code is not printing what it has received on the Serial.

I'm trying to understand what is really going on and why I need this delay(2).

Thanks a lot in advance!

# Answer
> 2 votes
Try this code: first delay produces 1ms pulse on pin D5. Without this delay the pulse could be too short for the nano to catch it (you can use delayUs and try finding the shortest interval that produces reliable result). We know that after this pulse, nano sends some data. So wait 100ms to collect it. If you call readSerial right after the pulse was sent, you won't get anything, because you need to wait at least for single byte transmission

```
void loop() {
    digitalWrite(D5, HIGH);
    delay(1);
    digitalWrite(D5, LOW);

    delay(100);
    readSerial();

    delay(1000);
}

```

# Answer
> 1 votes
This line is wrong:

```
attachInterrupt(D4, task_handle, RISING);

```

It should be:

```
attachInterrupt (digitalPinToInterrupt (4), task_handle, RISING);

```

In any case, attachInterrupt does not apply to D4, it is for D2 and D3 on the Atmega328P.

Note that the pin number is 4, not D4.

---
Tags: serial, interrupt
---


# Question
Title: samd21 linking, change the base addresse from the default
I'm working on creating a safe firmware upgrade for my adafruit feather m0. I understand from my CTO that wrote the previous upgrade that for either samd21 or all arm m0 (not sure which) the compiler compiles non relative addresses, meaning bx 0x3000 will jump to address 0x3000 and not 0x3000 bytes from my location. My goal is to split the flash into 4 banks:

1. bootloader (2k)
2. user data
3. firmware #1
4. firmware #2 which firmware will be booted is up to a flag in the flash do decide. i understand from my predecessor this is an issue since firmware#2 when loaded to ram might not run. I disagree and do believe simple changes in the .ld script should accomplish the task.

My only question to you guys is changing the .ld script .text address is enough ? i know the bootloader jumps to an address that was defined in the .ld script if it's not 0xFFFFFF (if the flash was written to). do i ned to change the .ld script to include two .text sections ? do i need to also define how they reside in the RAM as well ? any examples ? hint ?

Thanks.

# Answer
> 1 votes
A typical LD script consists of two sections - one that defines memory ("MEMORY") regions, and another that defines what to put in those memory regions ("SECTIONS").

To carve holes in an existing memory layout it is usually enough to just change the first section - the part that defines the layout of the memoy. Shrink and move existing blocks of memory and insert new ones.

For example you may have this at the moment:

```
MEMORY
{
  FLASH (rx) : ORIGIN = 0x00000000+0x2000, LENGTH = 0x00040000-0x2000 /* First 8KB used by bootloader */
  RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000
}

```

There is a hole already defined of size 0x2000 at the start of flash, and the sketch is loaded from 0x2000 onwards.

You may want to shrink and move that, and add a "user data" chunk. It's enough to just go:

```
MEMORY
{
  USERDATA (rx) : ORIGIN = 0x2000, LENGTH = 0x1000
  FLASH (rx) : ORIGIN = 0x3000, LENGTH = 0x00040000-0x3000
  RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000
}

```

(I collapsed some of the maths cus it's pointless). Now the flash area (where the sketch goes) has been shrunk by 0x1000 and moved an extra 0x1000 up the memory map. A USERDATA chunk has been inserted which you can then use later on if you so wish.

To make things get put in there by the linker script (you don't need to change anything else to move the sketch data...) you can define a new section in the later part of the linker script:

```
.userdata :
{
    KEEP(*(.userdata))
    KEEP(*(.userdata.*))
} > USERDATA

```

That should then place anything that you put in a `.userdata` section (or a subsection within that) within your sketch into the USERDATA chunk of flash - separate from your sketch.

```
(sketch)
const uint8_t __attribute__((section(".userdata"), used)) data[] = { 10, 100, 123, 177, 221, 49 };

```

However, if you plan to use it like EEPROM and only write to it using code in your sketch then you don't need to worry about anything like that - just carve out the hole. You can also provide some globals to help with your code, though:

```
(linker script)
PROVIDE(userdata_start = ORIGIN(USERDATA))
PROVIDE(userdata_length = LENGTH(USERDATA))

```

Then you can use those in your program to know where the USERDATA chunk is and how big it is (ideal if you ever choose to change it - no need to change your code, only the linker script).

---
Tags: flash, firmware, samd21g
---


# Question
Title: Is an atmega 2560 board compatible with the Adafruit Trellis?
I want to build a custom midi controller for my computer, and yes, Adafruit has a mini Untz project. For my purposes, I need more analog inputs than the Leonardo, and the only other option I can find is the atmega 2560. Can i use that?

# Answer
MIDI comes in many different arrangements.

The two most important ones for you are "MIDI Over USB" and "Traditional Serial MIDI".

The former encapsulates MIDI messages and sends them over USB to the computer. This is what you normally get when you plug in a USB-based MIDI instrument, or a USB to MIDI adapter cable.

The latter is a simple serial port running at a specific baud rate. It's generally opto-isolated as well.

On the Leonardo you can do either of those methods (you haven't mentioned which you use), but on the ATMega2560 you can only do the latter (that is, connect the board to a USB to MIDI adaptor cable). However the Arduino Mega2560 (Note: this is a board, what *you* talk about is *a bare chip*) has a USB interface chip that can be re-programmed to look like MIDI. That will bridge between the "traditional serial MIDI" to the "MIDI over USB". However doing so may impare your ability to program the board.

Another option is to use some PC-based Serial-To-MIDI bridge software which reads normal Serial data as provided by the Arduino and converts it into MIDI signals within your computer.

A third option is to step away from Arduino and choose a board that has both a native USB interface (with MIDI support in software) and more analog inputs. A board such as one of the Teensy 3.x range would probably suit you well.
> 1 votes

---
Tags: adafruit, midi, atmega2560
---


title: Attiny85 route vcc though output pin

text:
# Question
Title: Attiny85 route vcc though output pin
I'm still learning the basics so please bare with me if something seems unclear ;-)

I want to hook up an Attiny85 to a WiFi module (esp8266) and 2 sensors. The VCC will be provided by a battery pack and a step-up/step-down converter to ensure steady voltage without too much efficiency loss. Right now the modules are all hooked up to the VCC rail, together with the Attiny85 in one circuit.

I would like to take a sample, and then make as much of the circuit power down until the next reading with a 2 minute interval or so.

While looking for power saving modes for the esp8266 and struggling a bit with it, it got me thinking. What if I let Attiny85 handle the WiFi and sensors circuit via an OUTPUT pin and just turn that high or low. I read somewhere that an OUTPUT pin would not be able to supply as much current as if it was directly connected. That would probably be the case for me here since the WiFi module draws significant current.

Maybe using a transistor to "flip the switch" be a good solution instead if that is the case?

So my question is, is my way of thinking here even viable? How do I know what kind of max current can go through an OUTPUT pin?

# Answer
What you want is a P-channel MOSFET to control the power. Something with a nice low "logic level" gate threshold.

simulate this circuit – Schematic created using CircuitLab

R1 keeps it switched off. Set the output to LOW to pull the gate down and enable the MOSFET.

Be sure to "stop" your Serial connection and set both TX and RX pins to INPUT to prevent damage to the ESP8266 (or ATTiny) while powered off.
> 3 votes

---
Tags: esp8266, attiny85, electricity
---


# Question
Title: Reading values from TTP229 capacitive touch sensor on arduino
I would like to be able to read the raw capacitive sensor values from a TTP229 chip through i2c in Arduino. I have one of these breakout boards to play with :

My goal is to get values similar to those of the MPR121 or the Capacitive Sensor Arduino library where the reading changes depending on proximity and how hard you touch the pads. I have tested the following code but I'm only able to detect an on / off reading.

```
#include <Wire.h>
#define ttp229 ( 0xAF>>1 )

uint16_t data_out = 0;
uint16_t data1, data2;
int count = 0;
boolean count2 = false;
int button[16];
int oldata[16];

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

void loop()
{
    Wire.requestFrom( ttp229, 2, true );
    //delay(1);
    while( Wire.available() )
    {
        data1 = Wire.read();
        data2 = Wire.read();
        data_out = (data1<<8)|data2;

        for(int i=1;i<17;i++)
        {
            uint16_t contrast = 0x8000;
            if(data_out & contrast)
            {
                //Serial.println(i);
                button[count]=i;
                count++;
            }
            data_out<<=1;
        }
        if(count2)
        {
            switch(count)
            {
                case 1:
                if( oldata[0] == button[0] )
                {
                    Serial.println( button[0] );
                    delay( 20 );
                }
                break;
                case 2:
                if(oldata[0]==button[0]&&oldata[1]==button[1])
                {
                    for(int i = 0; i < 2; i++)
                    {
                        Serial.print( button[i] );
                        Serial.print("  ");
                    }
                }
                break;
            }
        }
        for( int i = 0; i < 16; i++ )
        {
            oldata[i] = button[i];
        }
        count = 0;
        count2 =! count2;
    }
}

```

Even if i just print out data1 and data2 from the example it doesn't seem to produce readings that change with the capacitance. I originally thought this was a hardware limitation but then I came across this TTP229 product that has a linear touch sensor built into it.

Does anyone have any experience with this sensor and how I can access the raw readings?

# Answer
> 2 votes
mpr121 gives raw values it has 12 electrodes/capacitance sensing inputs

https://www.sparkfun.com/datasheets/Components/MPR121.pdf https://github.com/BareConductive/mpr121/tree/public/MPR121/Examples/DataStream

---
Tags: sensors, arduino-nano, i2c, wire-library, capacitors
---


title: Factory Pattern on Arduino

text:
# Question
Title: Factory Pattern on Arduino
I'm looking to create a factory pattern to identify which of N objects is attached to my `Serial` port. Assuming each object has a unique response to the input stream `"What topic is this?"`, How can I get my `ScienceFactory` class to create my `Science` subclasses?

**EDIT 2** To clarify,

* *Arduino* sends `identification query` to *device*.
* *Device* responds with`identification string`
* *Arduino* receives `identification string`
* *Arduino* constructs correct `Science Child`

Looking at various examples, I've been able to get the following skeleton code:

```
class ScienceFactoy
{
    public:
      enum Subject {Biology, Chemistry, Physics};
      enum Subject Topic;
      bool GetTopic();
};

bool ScienceFactoy::GetTopic()
{
    Serial.println("What Topic is this?");
    /*The Device will respond with "Biology", "Chemestry" or "Physics"
    over Serial*/

    Topic=Biology;
      /*Instead of writing the Serial.read() logic,
      let's pretend the device is a Biology device*/

    if(Topic==Biology)
    {
        //Create Biology Science Class
        return true;
    }
    if(Topic==Chemistry)
    {
        //Create Chemistry Science Class
        return true;
    }
    if(Topic==Physics)
    {
        //Create Physics Science Class
        return true;
    }
    else
    {
        return false;
    }
}

class Science
{
    public:
      enum Subject {Biology, Chemistry, Physics};
      enum Subject Topic;
      //bool takeAttendance()
      //virtual void TestStudents();
      //virtual void PopQuiz();
      virtual void Free() = 0;
};

class Biology : public Science
{
    public:
    Biology(){Serial.println("Ready For Bio");}
      //bool DissectFrogs(){}
};

class Chemistry : public Science
{
    public:
    Chemistry(){Serial.println("Ready For Chem");}
      //bool MixChemicals(){}
};

class Physics : public Science
{
    public:
    Physics(){Serial.println("Ready For Physics");}
      //bool OpticsLab(){}
};

Science ConnectedClass;

void setup() {
  Serial.begin(9600);
  ScienceFactory ClassAtSerialPort; /*(Something happens that redefines
  ClassAtSerialPort to be the correct class)*/
  /*SerialOut "Ready For Bio\n" should happen here*/
  ConnectedClass=ClassAtSerialPort;

}

void loop() {
  if(ConnectedClass.Topic==Biology){DissectFrogs();};

}

```

However, I don't know where to go from here as my code is Arduino specific. (**Edit** changed the code so to something that compiles)

# Answer
This is not a simple solution because of the way your Factory and Science classes are structured.

Your Science class needs to hold an actual instance of itself for use when the loop wants to call the children. This instance will be called 'device' in my example.

```
class Science
{
    public:
      enum Subject {Biology, Chemistry, Physics};
      enum Subject Topic;
      //bool takeAttendance()
      //virtual void TestStudents();
      //virtual void PopQuiz();
      virtual void Free() = 0;
      Science* device;
};

```

In your GetTopic() call you then need to instantiate the actual child class

```
if(Topic==Biology)
{
    //Create Biology Science Class
    device = new Biology(); // with appropriate parms
    return true;
}

```

Then in your setup() you have to use the class that was created

```
ConnectedClass=ClassAtSerialPort.device;

```

So in the loop() code you call call the device specific method.

```
void loop() {
  if(ConnectedClass.Topic==Biology){connectedClass.doScience();};

}

```

There is problem with your approach you might still need to resolve. Relying on polymorphism like this is typically done by creating a common method in the parent that all the children override (ex. `doScience()`) and each child class does whatever is appropriate. You can have class specific methods but then you'll likely need to cast the device to the specifc class first.
> 2 votes

---
Tags: c++, class
---


title: RGB led strip is too dim

text:
# Question
Title: RGB led strip is too dim
I'm following this tutorial to build an Arduino powered RGB led strip controller but I'm facing two problems:

1. When I use `digitalOutput` the lights are too dim.
2. When I use `PWM` the leds change so slightly that I can barely detect a change.

These are the parts I'm using:

* Wemos D1 mini
* a USB cable to power the Wemos
* 1k ohm resistors
* TIP31c transistors
* A power outlet 12V 1A to power the strip (which works fine with the original controller unit)

The circuit connected as presented in the tutorial (like the circuit below) doesn't work, the board does not start.

If I disconnect the board GND from the outlet GND then the board starts but the leds are too dim to be visible

What am I doing wrong?

simulate this circuit – Schematic created using CircuitLab

# Answer
The Wemos D1 Mini is a 3.3V device. With a 1k base resistor, the most base current you're going to get is (3.3V / 1k ohm) = 3.3mA.

Looking at the datasheet, the current gain (h\_FE) for the TIP31 transistor is no more than 50. So the maximum current you will pass from collector to emitter is 50\*3.3mA = 165mA.

Your base resistor is too large and is limiting the current to your LED strip to no more than 165mA per channel. Try reducing the base resistor to 150 ohm. The TIP31 can handle continuous collector current of 3A, so you ought to be safe with a 1A power supply, and 150 ohm resistor.

**UPDATE:**

Per @Gerben's comment, the ESP8266 can source a maximum of 12mA from a GPIO pin, so you should not use lower than a 225 ohm base resistor on the initial TIP31. A Darlington pair would look something like:

simulate this circuit – Schematic created using CircuitLab
> 5 votes

---
Tags: esp8266, led-strip
---


# Question
Title: Can I program a 20MHz Attiny85 with the 8MHz Internal Clock option in the Arduino Software?
I'm looking at using the ATTiny85 for a project, but have run into a snag. After following the tutorial found at https://learn.sparkfun.com/tutorials/tiny-avr-programmer-hookup-guide, I've installed the necessary files to be able to program an ATTiny85; however, the options given under "Clock" are 1MHz and 8MHz internal, as well as 8, 10, and 20MHz external.

Normally this wouldn't be a problem, except Digikey has no in-stock 8MHz flavored devices in the package I need (SOIC-8, don't have a reflow setup to use the QFN package).

If I buy the 20MHz version, will I be able to program them with the Arduino IDE set to the "8MHz Internal" clock option?

# Answer
> 5 votes
I think you have the wrong end of the stick here. The Attiny85 is not a chip that comes in different speed versions. The datasheet mentions that it can run at 20 MHz. That doesn't mean you can buy a "20 MHz version". By selecting the appropriate clock option in fuses you can run at 20 MHz (or higher). From the datasheet:

> **High Frequency PLL Clock**
>
> There is an internal PLL that provides nominally 64 MHz clock rate locked to the RC Oscillator for the use of the Peripheral Timer/Counter1 and for the system clock source.

---

> I believe these to be pre-set from the factory for the various clock options - but will it matter when I try to program them with the Arduino software?

That list is weird, it doesn't specifically say they are pre-set to any speed. Personally I would regard that list as meaning that the higher speed ones are manufactured to better tolerances, if indeed it means anything at all.

Maybe when they manufacture them they do a quick test at various speeds, and ones that don't run at 20 MHz are put into a different batch.

The datasheet specifies the default clock settings, it would be weird if Atmel made them with different settings unless you placed a massive order.

As for programming them, by default they don't come with a bootloader, so you would need to use ICSP programming anyway. You would need (in any case) something like the AVRISP device (which connects via USB to your computer, and the other end goes to your chip to be programmed). Or you can make up something like my AVR hex programmer which lets you put a hex file from the IDE onto a MicroSD card, and then use that to program the ATtiny85.

In all of these cases you can change the fuses to do what you want, including the clock options you prefer.

There is a board you can buy which is a pre-made gadget using the code I mention above, where you just press a button and the chip is programmed, which would be helpful if you are doing a lot of them.

---
Tags: arduino-ide, attiny, attiny85
---


# Question
Title: I have the error: expected unqualified-id before 'if'
This is my Sketch or code:

```
const int EchoPin = 5;
const int TriggerPin = 6;
const int LedPin = 13;

void setup() {
 Serial.begin(9600);
 pinMode(LedPin, OUTPUT);
 pinMode(TriggerPin, OUTPUT);
 pinMode(EchoPin, INPUT);
 pinMode(13, OUTPUT);
}

void loop() {
 int cm = ping(TriggerPin, EchoPin);
 Serial.print("Distancia: ");
 Serial.println(cm);
 delay(1000);
}

int ping(int TriggerPin, int EchoPin) {
 long duration, distanceCm;
 digitalWrite(TriggerPin, LOW);
 delayMicroseconds(4);
 digitalWrite(TriggerPin, HIGH);
 delayMicroseconds(10);
 digitalWrite(TriggerPin, LOW);
 duration = pulseIn(EchoPin, HIGH);
 distanceCm = duration * 10 / 292/ 2;
 return distanceCm;
}

if (distanceCm <= 20) {
 digitalWrite(13, HIGH);
}

if (distanceCm >= 20) {
 digitalWrite(13, LOW);
}

```

The error appears in the second if.

# Answer
> 1 votes
The error is occurring because you have 2 **if** statements outside of a function. You could move them into the **ping()** function which would fix the error but there seems to be a logic error with the 2 if statements as well.

If **distanceCm** is 20, both if statements execute one right after another, so I doubt you'll see the LED turn on. Perhaps an **if/else** might work.

```
if(distanceCm < 21){
  digitalWrite(13, HIGH);
}
else{
  digitalWrite(13, LOW);
}

```

# Answer
> 1 votes
Error is because you close your ping method before the "if (distanceCm \>= 20)" clausule. This is a correct code:

```
const int EchoPin = 5;
const int TriggerPin = 6;
const int LedPin = 13;

void setup() {
 Serial.begin(9600);
 pinMode(LedPin, OUTPUT);
 pinMode(TriggerPin, OUTPUT);
 pinMode(EchoPin, INPUT);
 pinMode(13, OUTPUT);
}

void loop() {
 int cm = ping(TriggerPin, EchoPin);
 Serial.print("Distancia: ");
 Serial.println(cm);
 delay(1000);
}

int ping(int TriggerPin, int EchoPin) {
 long duration, distanceCm;
 digitalWrite(TriggerPin, LOW);
 delayMicroseconds(4);
 digitalWrite(TriggerPin, HIGH);
 delayMicroseconds(10);
 digitalWrite(TriggerPin, LOW);
 duration = pulseIn(EchoPin, HIGH);
 distanceCm = duration * 10 / 292/ 2;
  if (distanceCm <= 20) {
 digitalWrite(13, HIGH);
}

if (distanceCm >= 20) {
 digitalWrite(13, LOW);
}
 return distanceCm;
}

```

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


# Question
Title: MQTT bridging with Arduino and ESP8266 - What software should I use?
Sorry for the vagueness in my question, I am just looking for ideas to point me in the correct direction please...

I wish to connect many (read: 20+) different sensors to a local wifi network and have them all datalogged and controlled by a single server on the network. Pretty standard stuff for the home automation people etc. Some sensors are connected to esp8266 boards directly, others communicate via serial and will employ an 8266 to provide wifi.

I am having trouble deciding which direction to go or which software / firmware to combine since its changing rapidly and a fair number of tutorials are around but all have different approaches and end goals.

This must be entirely contained offline - I have a raspberry pi, a wireless router, and the various sensors (mostly arduino based).

Now from research it would seem I need to setup a serial to MQTT 'bridge' - and have the esps 'talk' to the pi by MQTT. And that the pi should be running 'mosquitto' if I wish the MQTT to be bi-directional (i.e. I can receive serial data AND send serial commands. I have never dealt with MQTT so I am trying to learn as I go.

I have been working for a time with 'ESP-Link' software and had success using it as a simple serial to tcp-ip bridge and using virtual serial ports to communicate with the attached device. However using virtual serial ports on the server is clunky, unreliable and not what I wish to do - does anyone know if it can be setup so I can send 'raw' serial messages over TCP to the server for use? And from the server to control the connected devices? Or if there is an easier way? I cannot modify all of the serial devices I wish to connect, so just want to get the data out/in and have it manipulated by the server where necessary.

In essence I wish to end up with several sensors all connected to the router, and logged / controlled through a web interface hosted on the PI, all 'offline' and contained. Eventually I would like the server to be able to recognize what devices it can 'see' automatically, however at this moment I simply wish to gain insight into how I can most easily achieve this? Or even if I am completely mistaken in my approach?

Thanks

# Answer
> 2 votes
MQTT is perfectly suited to this application. Here is an overview of a possible configuration. You should be able to find tutorials about each piece of the system.

On the Raspberry Pi:

* Setup a Mosquitto server that can receive messages published by the ESP devices.
* Write and run a MQTT client on the RPi that subscribes to the messages published by the ESP devices. This client would then store the data in some sort of permanent data store (database, flat files, whatever).
* Write and run on the RPi a web app that reads and presents the data from the data store.

On the ESP devices:

* Connect to the same wireless network as the RPi (or set up the RPi as an access point and have the devices connect to it)
* Read data from the sensors and publish it to the MQTT server on the RPi.

If you want to push data to the ESP devices -- have them subscribe to certain messages (topics) on the MQTT server and then publish messages in those topics on the server. Your web app could do this.

All of this can be done on an isolated network.

# Answer
> 1 votes
As you also asking about hardware I would recommend the following setup:

For sensors that only need to send data I would go with a ATtiny85. It has very low power consumption, is very small and easy to program. If you use 10-N of them then a programming board and only the micro controller will be cheaper and even smaller.

For sensors that have some logic on it, maybe multiple attached sensors I would go with a Wemos D1 Mini. It has build in WIFI, you can debug it, it is still very small and there are a ton of extension (shield) boards for it to speed up your development.

For the communication part I would go away from WIFI since 20+ devices can generate quiet some traffic. Also WIFI costs you a lot in terms of power consumption since it is not optimized for IoT (small data packages). I would add a 433mhz Mini Low Power RF Receiver/Transmitter to my IoT hardware and communicate through that. It has a long range and has a very small power footprint.

Additionally you could think about using a Wemos as MQTT gateway between your 433mhz devices and the WIFI instead of your proposed Raspberry Pi solution. The nice benefit is that you will have a dedicated device managing an MQTT gateway that is far less error-prone as a Linux server (Raspberry Pi) and you don't need to update as often as with the Pi to keep it secure. There is a Wemos D1 Mini Pro that has a better WIFI antenna and a little bit more power that could be perfect for this use case.

The MQTT protocol is perfect for a sensor network since it is optimized for low bandwidth, high latency, and fragile connections. It supports Quality of Service (QoS) and you can configure what shall happen if a device disconnects/is not reachable anymore. There are a lot of library's already available for MQTT so that the setup is very quick. HiveMq has a nice how to get started with MQTT guide for further reading.

---
Tags: serial, esp8266, wifi, mqtt
---


# Question
Title: Interesting issue with my wifi Car project
Hello so i build a nodemcu wifi controlled car, everything works fine expect i have one small issue, currently i have 2 9v batterys, one of them is connected to motor controller and other one is connected to nodemcu.. but the nodemcu's 9v battery gets hot in a minute and stops working. What am i doing wrong? + is connected to vcc and - is connected to grnd on nodemcu.

# Answer
> the nodemcu's 9v battery gets hot in a minute and stops working. What am i doing wrong?

You're using a 9V battery.

Those batteries are useless. They have very little capacity, and can provide very little current. The NodeMCU needs a *lot* of current.

Choose a better battery. Maybe a Li-Poly battery would be good (mobile phone batteries are good for this).
> 2 votes

---
Tags: esp8266, nodemcu
---


# Question
Title: how long should interrupting signal last?
I want to apply the interruption of a program with a RISING signal from a pin. How long should the signal rise to be considered as the interruption?

# Answer
> If edge or toggle interrupt is selected, pulses that last longer than one clock period will generate an interrupt. Shorter pulses are not recommended to generate an interrupt.

Source (page 91, chapter 17.2.1 "External Interrupt Control Register A")
> 4 votes

---
Tags: interrupt
---


# Question
Title: Running a HC-SR501 PIR Sensor constantly using battery
I am not sure if this is the correct forum since I tend to use the ESP8266 standalone and not together with the arduino nano. However, here is what I am planning.

I have a HC-SR501 PIR sensor, which I want to use to constantly track movements of animals outdoor. I dont want to go into further details, but 10 impulses per minute are expected (max. is 30/min) except for the night maybe. I am planning to count the impulses for one hour, than send the sum to a webserver using wifi and reset the counter. For powering I want a battery/akku solution (non-negotiable). Since the input of the PIR sensor is 4.8-20V I will directly connect it to the battery (provided the Voltage is high enough like with a 9V battery) and the ESP8266, which is used as WIFI station will be connected via an AMS1117 generating 3.3V.

WIFI Router which is connected to the internet is available and several sensor systems will be used to check several areas. Basic knowledge of using AT cmds or programming with Arduino IDE is given.

Questions:

1. Can the ESP8266 module count impulses during one of the sleep modes?
2. Do you have a less current consumpting module in mind allowing wifi transmittance? (LoRa or the NRF Module are not an option atm, since the router has to be used)
3. What kind of battery/akku would you suggest? Having sufficient voltage and capacity (mAh) and still being easy to handle?

Optimum lifetime for the beginning would be 1 month for the first prototype. Afterwards a SolarModule + Akku solution will be implemented, but the first prototype has to be finished simple and fast yet satisfying :)

kind regards

# Answer
> 2 votes
This are multiple questions in one. But I will do my best to tackle them one by one.

> 1. Can the ESP8266 module count impulses during one of the sleep modes?

The ESP8266 has different power modes. Short answer: As long as the CPU is running, yes.

Long answer: The ESP8266 has quite a few power modes. They are easily put:

* No-sleep (as high as 170 mA while communicating)
* Modem-sleep (15 mA Wifi is off, everything else is running)
* Light-sleep (0.9 mA CPU is put to sleep and system clock stopped, can be waken up by a external interrupted)
* Deep-sleep (20 uA Everything is off, basically it's powered down, but can wake itself on set intervals or reset it to wake it. everything in RAM is lost, except RTC RAM)

So if your sensor gives a pulse, you can use that as a interrupt and go to light-sleep. If you need to pull it, all you can do is modem-sleep.

ESP8266 power modes

> 2. Do you have a less current consumpting module in mind allowing wifi transmittance? (LoRa or the NRF Module are not an option atm, since the router has to be used)

Modem-sleep is your friend. Only connect to the router if there is data to send.

You can set up an AVR and use it in ultra low power mode and only turn on the esp if there is data to send. But explaining how to set that up goes way too far out of this scope.

> 3. What kind of battery/akku would you suggest? Having sufficient voltage and capacity (mAh) and still being easy to handle?

I can't choose a battery for you, there are just too many of them. But what I can do is tell you about how batteries work.

Take for example a 9 volt battery (not my first choice, you will see in a bit).

We take an energizer 522. It's a Alkaline battery and has 600 mAh. That means it can deliver 600 mA in one hour. But there is a catch. the more you draw from a Alkaline battery, the less capacity it will have.

It is 9 volts right? yes and no. you see. the voltage potential will drop (quite dramatically) over its lifetime.

A liniar voltage regulator (AMS1117) will take the needed mA of the output on the input and drop off the extra power as heat. So the battery will always have the same load (Yes, the esp8266 is a dynamic load, but lets keep it simple)

so lets say it's in modem-sleep (15mA). Lets divide 600 by 15, that is 40 hours of runtime. For simplicity I don't count the sensor itself.

9 volt block datasheet

The AMS1117 needs 1.5 volts more then its output voltage for ensuring a stable output. So that is 4.8 volts or higher. But no higher than 12 volts.

AMS1117 datasheet

Choose a battery that has enough mAh and isn't more then 12 volts and not lower than 5 when depleted. If using outside, check if its operating temp range is wide enough.

So basically try to lower your energy footprint as far as it can possibly go and then based on the new average power usage, find a battery that is big enough for the task.

Better yet, get a solar cell and a rechargeable battery. It has a full list of other problems, but this answer is a bit too long already and that topic is out of the current scope.

---
Tags: esp8266, battery
---


title: SyslogAppender for log4esp

text:
# Question
Title: SyslogAppender for log4esp
I'd like to "merge" two Arduino libraires, namely log4Esp on one side and Syslog on the other, hence creating a syslog appender for log4esp.

My problem is that log4esp's Appender prototype expects a method to return an instance of `Print` to which it'll write the message.

Syslog can't be used in this way.

**==\> Question :** How to create a "Print buffer" / where can I find which class extends `Print`?

# Answer
Class `Print` is a base class of Arduino streaming. `Stream` is a derived class and adds reading capability. `Print` has only one abstract method `write` to write one byte to output or buffer. It is easy to implement a derived custom class.

The classes derived from Stream are classes for hardware and software serial like HardwareSerial for Serial singletons and different software serial implementations. From Stream is derived class File of the SD and SPIFFS library, TwoWire class for Wire singleton object, etc.

Class Client is derived from class Stream and is a base class for Arduino standard TCP networking. Examples of derived classes are EthernetClient, WiFiClient. For UDP, class UDP is derived from Stream, of course with implementations like EthernetUDP, WiFiUDP.

You can see this in the source code in local source file folders or in GitHub repositories.
> 4 votes

---
Tags: esp8266, print, logging
---


# Question
Title: Saving a .txt file to SD Card and Reading each content data to txt file then save it to a variable
I am new to arduino I am trying to create an arduino project that Saving a .txt file to SD Card and Reading the txt file then save it to a variable data type "Long" named 'savednum'. I had successfully can save the txt file and read it, however the problem lies in storing the read txtfile, when I read the txtfile and stored it in savednum and then serial print the savednum it gives different/ random numbers which is not equal to the data in the .txtfile that I store and read. I am wondering what seem to be wrong? Any suggestion is really appreciated. I thank you in advance.

```
#include <TMRpcm.h>
 #include <SD.h>
 #include <SPI.h>
 #define SD_ChipSelectPin 4 //using digital pin 4 on arduino nano 328

 TMRpcm tmrpcm; // create an object for use in this sketch

File myFile;

char serialData;

int i = 0;
long n1 = 123456789;
long n2 = 245678918;

long savednum =0;

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

 }

Serial.print("Initializing SD card...");

 if (!SD.begin(SD_ChipSelectPin)) {
Serial.println("initialization failed!");
 while (1);
}
Serial.println("initialization done.");

 myFile = SD.open("NEWDATA.txt", FILE_WRITE);

if (myFile) {
Serial.print("Writing to NEWDATA.txt...");
myFile.println(n1);
myFile.println(n2);

myFile.close();
Serial.println("done.");
} else {

Serial.println("error opening NEWDATA.txt");
}

myFile = SD.open("NEWDATA.txt");
if (myFile) {
Serial.println("NEWDATA.txt:");

while (myFile.available()) {
  Serial.write(myFile.read());
// here the code I tried to read .txt file and store it in long
savednum = myFile.read();
Serial.println(savednum);
}

myFile.close();

}

}

void loop()
 {

  }

```

# Answer
> 0 votes
`myFile.read()` reads just one byte from the file - not the whole file or even a whole line.

You're reading one byte, then printing it. Then reading a second byte, storing that in a variable, then printing the variable. Then you loop back to the beginning again.

So you're printing alternate "odd" bytes, and storing / overwriting the variable with "even" bytes. So you just get nonsense.

You're storing the data in your file as ASCII text, so it's necessary to read the entirety of each line and then convert that string of characters into a number. Or read each character in turn and manipulate your total value for the line.

For example:

```
long savedNum = 0;
long numberOne = 0;

while (myFile.available()) { // Something left to read
    char c = myFile.read(); // Get the next character
    if (isdigit(c)) { // It's a number 0-9
        savedNum *= 10; // Make room by decimal shifting to the left
        savedNum += (c - '0'); // Convert the character to a number and add it to the total
    } else if (c == '\n') { // End of line
        Serial.print(F("The number is: "));
        Serial.println(savedNum); // Show us the number
        numberOne = savedNum;  // Store it somewhere else - enhance this for multiple numbers.
        savedNum = 0;  // Reset to 0 ready to read the next line
    }
}

```

The Arduino API (Stream class) also includes some handy helper functions, such as:

```
int num = myFile.parseInt(); // get the next integer

```

There's no `parseLong()` though, but despite its name, `parseInt()` actually returns a `long`. That reads characters up until it gets a non-numeric character and converts them to a long using the same method as in my example. It doesn't distinguish lines, though, so can be used to get separate numbers on the same line, such as `32847,2345534,12,-43`.

With your file though you may need to filter out the extra `\r` that may be in there from the line endings or you'll get missing numbers.

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


# Question
Title: Arduino program has suddenly stopped updating
I am writing a speedo/odometer program which was all working beautifully until I introduced an LCD screen and code for the LCD.

The screen works on power up, displays the distance recorded on an SD card, toggles from miles to km on the press of a button, but no longer runs my calculate method when invoked. The method has stopped working, or at least it's not updating with the latest information anymore when the method instructs it to. Any help would be greatly appreciated.

In case it matters, I am powering the project from an HTC one M8. Maybe it's lack of juice that is causing the issue, or just bad programming?

My code:

```
#include <Arduino.h>
#include <SPI.h>
#include <SD.h>;
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

int InterruptPin = 2;
//int PowerPin = 3;
int ButtonPin = 4;
int SDPin = 7;

volatile long km = 0; // SAVE
volatile float kmTemp = 0; // SAVE
volatile int kmrevs = 0; // SAVE
volatile long miles = 0; // SAVE
volatile float milesTemp = 0; // SAVE
volatile int milesrevs = 0; // SAVE

volatile int kph = 0;
volatile int mph = 0;
volatile unsigned long start = 0;
volatile unsigned long stop = 0;
volatile float secs = 0;
volatile float speed = 0;
volatile float temp = 0;

volatile int buttonState = 0;
volatile int lastButtonState = 0;
volatile boolean riding = false;

File myFile;

LiquidCrystal_I2C lcd(0x27, 16, 2);

void calculate(){
    riding = true;

    // KPH SPEED CALCULATOR
    stop = millis() - start;
    start = millis();
    temp = (float)stop;
    secs = temp / 1000;
    speed = 1.854 / secs;
    speed = speed * 3.6;
    kph = speed;

    // MPH SPEED CONVERTOR
    float x = kph * 0.6214;
    mph = x;

    // KM DISTANCE CALCULATOR
    kmrevs++;
    if (kmrevs == 540){
        km++;
        kmrevs = 0;
        kmTemp = kmTemp + 0.00116;
    }
    if (kmTemp >= 1.0){
        km++;
        kmTemp = kmTemp - 1.0;
    }

    // MILES DISTANCE CALCULATOR
    milesrevs++;
    if (milesrevs == 868){
        miles++;
        milesrevs = 0;
        milesTemp = milesTemp +0.072;
    }
    if (milesTemp >= 1.0){
        miles++;
        milesTemp = milesTemp - 1.0;
    }

    // PRINT DATA TO LCD & SERIAL
    buttonState = digitalRead(ButtonPin);
    if (buttonState == HIGH){
        lastButtonState = buttonState;
        Serial.print(kph);
        Serial.print("kph  ");

        Serial.print(km);
        Serial.print("km  (");
        Serial.print(kmTemp, 6);
        Serial.println(")  ");

        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print(kph);
        lcd.print("kph");
        lcd.setCursor(0,1);
        lcd.print(km);
        lcd.print("km");
    }
    if (buttonState == LOW){
       lastButtonState = buttonState;
        Serial.print(mph);
        Serial.print("mph  ");

        Serial.print(miles);
        Serial.print("miles  (");
        Serial.print(milesTemp, 6);
        Serial.println(")");

        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print(mph);
        lcd.print("mph");
        lcd.setCursor(0,1);
        lcd.print(miles);
        lcd.print("miles");
    }

    // SAVE DATA TO SD CARD
    SD.remove("test.txt");
myFile = SD.open("test.txt", FILE_WRITE);
    if (myFile) {
        myFile.print(km);
        myFile.print(" ");//
        myFile.print(kmTemp, 6);
        myFile.print(" ");//
        myFile.print(kmrevs);
        myFile.print(" ");//
        myFile.print(miles);
        myFile.print(" ");//
        myFile.print(milesTemp, 6);
        myFile.print(" ");//
        myFile.print(milesrevs);
        myFile.close();
    }
    else {
        // SD SAVE ERROR
        Serial.println("Save Error");
    }
}

void setup(){
    pinMode(ButtonPin, INPUT_PULLUP);
    pinMode(InterruptPin, INPUT);

    // POWER LCD SCREEN
    //lcd.begin(16,2);
    lcd.init();
    lcd.backlight();

    // LAUNCH SERIAL CONNECTION
    Serial.begin(9600);

    // LOAD DATA FROM SD CARD
    SD.begin(7);
    myFile = SD.open("test.txt", FILE_READ);
    if (myFile) {
       while (myFile.available()) {

       km = myFile.parseInt();
       kmTemp = myFile.parseFloat();
       kmrevs = myFile.parseInt();
       miles = myFile.parseInt();
       milesTemp=myFile.parseFloat();
       milesrevs = myFile.parseInt();

       }
    myFile.close();
    }
    else {
        Serial.println("Read Error");
    }

    // ATTACH INTERRUPTS
     attachInterrupt(digitalPinToInterrupt(2), calculate, RISING);

    // LOAD START SERIAL & LCD SPEED
    buttonState = digitalRead(ButtonPin);
    if (buttonState == LOW){
        // MPH DISPLAYED
        lastButtonState = buttonState;
        Serial.print("0mph  ");

        Serial.print(miles);
        Serial.print("miles  (");
        Serial.print(milesTemp, 6);
        Serial.println(")");

        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print(mph);
        lcd.print("mph");
        lcd.setCursor(0,1);
        lcd.print(miles);
        lcd.print("miles");
    }
    if (buttonState == HIGH){
        // KPH DISPLAYED
        lastButtonState = buttonState;
        Serial.print("0kph  ");

        Serial.print(km);
        Serial.print("km  (");
        Serial.print(kmTemp, 6);
        Serial.println(")  ");

        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print(kph);
        lcd.print("kph");
        lcd.setCursor(0,1);
        lcd.print(km);
        lcd.print("km");
    }
}

void loop(){
    buttonState = digitalRead(ButtonPin);

    // ZERO SPEED ON SLOW ROTATION
    if (riding == true){
    long period = millis() - start;
    if (period == 4150){
    if (buttonState == LOW){
        // MPH DISPLAYED
        lastButtonState = buttonState;
        Serial.print("0mph  ");

        Serial.print(miles);
        Serial.print("miles  (");
        Serial.print(milesTemp, 6);
        Serial.println(")");

        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print(mph);
        lcd.print("mph");
        lcd.setCursor(0,1);
        lcd.print(miles);
        lcd.print("miles");
    }
    if (buttonState == HIGH){
        // KPH DISPLAYED
        lastButtonState = buttonState;
        Serial.print("0kph  ");

        Serial.print(km);
        Serial.print("km  (");
        Serial.print(kmTemp, 6);
        Serial.println(")  ");

        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print(kph);
        lcd.print("kph");
        lcd.setCursor(0,1);
        lcd.print(km);
        lcd.print("km");
    }
    }
    }

    // CHANGE READING WHEN PRESSED
    if (buttonState != lastButtonState){
        long period = millis() - start;
        if (buttonState == HIGH && period < 4150){
        // KPH DISPLAYED
        lastButtonState = buttonState;
        Serial.print(kph);
        Serial.print("kph  ");

        Serial.print(km);
        Serial.print("km  (");
        Serial.print(kmTemp, 6);
        Serial.println(")  ");

        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print(kph);
        lcd.print("kph");
        lcd.setCursor(0,1);
        lcd.print(km);
        lcd.print("km");
        }
        if (buttonState == HIGH && period > 4150){
        // KPH DISPLAYED
        lastButtonState = buttonState;
        Serial.print("0kph  ");

        Serial.print(km);
        Serial.print("km  (");
        Serial.print(kmTemp, 6);
        Serial.println(")  ");

        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print(kph);
        lcd.print("kph");
        lcd.setCursor(0,1);
        lcd.print(km);
        lcd.print("km");
    }
    if (buttonState == LOW && period < 4150){
        // MPH DISPLAYED
        lastButtonState = buttonState;
        Serial.print(mph);
        Serial.print("mph  ");

        Serial.print(miles);
        Serial.print("miles  (");
        Serial.print(milesTemp, 6);
        Serial.println(")");

        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print(mph);
        lcd.print("mph");
        lcd.setCursor(0,1);
        lcd.print(miles);
        lcd.print("miles");
    }
    if (buttonState == LOW && period > 4150){
        // MPH DISPLAYED
        lastButtonState = buttonState;
        Serial.print("0mph  ");

        Serial.print(miles);
        Serial.print("miles  (");
        Serial.print(milesTemp, 6);
        Serial.println(")");

        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print(mph);
        lcd.print("mph");
        lcd.setCursor(0,1);
        lcd.print(miles);
        lcd.print("miles");
    }
    }
}

```

# Answer
Thanks guys, taking the labour out of the ISR has solved the problem perfectly. Unfortunately, the advice wasn't given as an answer so I'm unable to credit you for it, but appreciate the solutions given. Thanks.
> 1 votes

---
Tags: arduino-uno, c++, lcd, electronics, android
---


title: Which shield to use for GPRS?

text:
# Question
Title: Which shield to use for GPRS?
I'm planning to build a device that would read some sensor data and send it via GPRS, eg. once per day. (Not that original, yeah.) But my problem is choosing a GSM/GPRS shield.

The official shield has a **nice interface for doing an HTTP POST/GET**. OTOH, the shield seems to be sold out (and would be quite expensive anyway).

There seem to be other shields available, but their code examples tend to look **quite hacky**: the device waits for an arbitrary moment and then hopes that the server is done. That's IMO both inefficient or unreliable.

My question: which GSM/GPRS shield would you recommend, with these features:

* a sane library w/ examples, such as the official one
* an external antenna
* bonus: a competitive price
* another bonus: hopefully a "real" shield, so no soldering required and a few pins still easily usable for the sensors.

# Answer
I ended up ordering an **Elechouse board** which uses the M10 chip. Found one on eBay for 59 USD. It appears to work fine with the official library.

As the manual says, it must be given external power - the USB cable isn't enough!
> 2 votes

# Answer
That library should work with pretty much anything that has the M10 module on it.

I only have experience with the SIM900 modules. Found the cheapest one on EBay.

While interfacing with these things can be a challenge at first, you really just need to read the manual for all the AT commands and execute them. I've written a couple of functions that may help:

Note: you may safely replace all instances of `DEBUG_PRINT` and `DEBUG_PRINTLN` with `Serial.print` and `Serial.println`.

```
SoftwareSerial SIM900(7, 8);

/*
    Sends AT commands to SIM900 module.

    Parameter   Description
    command     String containing the AT command to send to the module
    timeout     A timeout, in milliseconds, to wait for the response

    Returns a string containing the response. Returns NULL on timeout.

*/
String SIMCommunication::sendCommand(String command, int timeout) {
    SIM900.listen();
    // Clear read buffer before sending new command
    while(SIM900.available()) { SIM900.read(); }

    SIM900.println(command);

    if (responseTimedOut(timeout)) {
        DEBUG_PRINT(F("sendCommand Timed Out: "));DEBUG_PRINTLN(command);
        return NULL;
    }

    String response = "";

    while(SIM900.available()) {
        response.concat((char)SIM900.read());
        delayMicroseconds(500);
    }

    return response;
}

/*
    Waits for a response from SIM900 for <ms> milliseconds

    Returns true if timed out without response. False otherwise.
*/
bool SIMCommunication::responseTimedOut(int ms) {
    SIM900.listen();

    int counter = 0;
    while(!SIM900.available() && counter < ms) {
        counter++;
        delay(1);
    }

    // Timed out, return null
    if (counter >= ms) {
        return true;
    }
    counter = 0;
    return false;
}

```
> 3 votes

# Answer
I would recommend the official Arduino GSM shield.
> 3 votes

# Answer
LinkitOne - ok not a shield but rather a compatible Arduino controller board with built-in GSM/GPRS/GPS/Wifi. comms library doesn't have as many diagnostic methods as e.g. the Adafruit one, but it was easy to setup and reliable. Main downside of the LinkitOne was that it uses a different processor from Arduinos so many of the Arduino libraries aren't compatible e.g. for I2C devices.

Adafruit Fona SIM808 2G Shield version. shield layout but stackable headers have to be bought and soldered seperately. Default pinouts work with Uno, but mods required for Mega. Library has lots of handy diagnostic methods (battery voltage, signal strength, etc). worked with giffgaff prepaid SIM but not vodafone for some reason. SMS worked ok. I could connect to GPRS but getting html from a website didnt' work.

DFRobot SIM808 GPS/GPRS/GSM Shield - Pre wired wirth stackable shield connectors, instructions to upload code and run the device are convoluted and vague. I Wasn't even able to get a basic connection to the Arduino to work. Either the library is very buggy or my device was faulty.

SEEEDStudio 113030009 GPRS Shield with Antenna and External SIM Holder V3.0 I'll probably tets this next..

Official Arduino GSM board DISCONTINUED

Sparkfun GSM/GPRS Module - SM5100B DISCONTINUED
> 0 votes

---
Tags: shields, tcpip, gsm
---


# Question
Title: ATtiny85 (Digispark) with 433mhz RF transmitter not working
I have the following components:

I got a communication flow transmit/receive working between two Wemos D1 and like to outsource the transmitting part now to a ATtiny85. I used the same code as for the Wemos:

```
#include <RCSwitch.h>

RCSwitch mySwitch = RCSwitch();

void setup() {
  pinMode(1, OUTPUT);
  mySwitch.enableTransmit(2);
}

void loop() {
    mySwitch.send("000110110001010100010001");
    digitalWrite(1, HIGH);
    delay(250);
    digitalWrite(1, LOW);
    delay(250);
}

```

But the serial monitor for the Wemos does not receive any communication. I went so far that I built up the communication between the two Wemos again and connected only the data pin of the transmitter to the ATtiny85 in order to exclude any voltage problems (ATtiny gets 5V, transmitter likes \<3.6V).

Now I am out of ideas. How can I debug the problem or what else can I try?

**Requested setup:**

# Answer
> 0 votes
I got it to work. The last comment of @Maximilian Gerhardt about I/O output got me thinking and I read up on it. So if I use 5V to power the ATtiny the I/O output voltage representation for 1 and 0 are significantly higher then with 3.3V. So now I underclocked the ATtiny to 8Mhz in order to use a 3.3V power supply. This way the I/O output matches the transmitters expectations. Now the communication is working.

Thanks for your help Max!

---
Tags: attiny, rf, digispark
---


# Question
Title: Serial Communication between ESP8266 and Arduino Uno
I want to send data from arduino to ESP8266. I have done all the RX and TX connections. The problem is that data is not sent every second, it stops after a single byte. When I remove the arduino cable then data is read.

My Arduino Code :

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

void loop() {

    Serial.write("50");
    delay(1000);
}

```

My ESP8266 Code :

```
void setup() {

Serial.begin(9600);

  // connect to wifi.
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);

  while (WiFi.status() != WL_CONNECTED) {

    delay(500);
  }
  Serial.println("Connected !");

}

void loop() {

 Serial.print(Serial.readString());

}

```

# Answer
Since you are Arduino Uno, it has only one `Serial`. This Serial can be used to transmit data in USART mode to another Serial Device as well as see any Debug data in the Serial terminal.

However, both the functionality can not be used simultaneously. The Tx Rx pair of Arduino can be connected to one pair of other device i.e. either to the computer via the cable or to the Tx Rx of ESP8266.

But if you really need to plug in the Uno to the computer and send data to ESP8266 simultaneously, then you have to use SoftwareSerial library to convert any digital pin to Tx Rx pin, and connect them to ESP8266 for transmitting data.
> 5 votes

# Answer
As explained by goddland\_16. Using Software Serial library will solve the issue. Code is given below. By Initializing other digital pin as communication pin, Interupption between Tx and Rx and to ESP8266 is seperated.

**Arduino UNO / Nano Code :**

```
/*
 * bismillah hir rahman nir raheem
 * UNO/Nano = Pin 7 & Pin 8
 * Note: Uno and ESP8266 cross connection
 */

#include <SoftwareSerial.h>

SoftwareSerial ArduinoUno(7,8);
String f;

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

void loop() {
    float i = (random(100) + 1);
    float j = (random(100) + 1);

    f = String('H') + String(i) + String('T') + String(j);
    ArduinoUno.println(f);
    delay(2000);
}

```

**ESP8266 Code :**

```
/*
 * bismillah hir rahman nir raheem
 * ESP8266 = Pin D7 & Pin D8
 * Note: Uno and ESP8266 cross connection
 */

#include <SoftwareSerial.h>
#include <ESP8266WiFi.h>

SoftwareSerial NodeMCU(D7,D8);

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

    pinMode(D7,INPUT);
    pinMode(D8,OUTPUT);
}

void loop() {
    String content = "";
    char character;

    while (NodeMCU.available()) {
       character = NodeMCU.read();
       content.concat(character);
    }

    if (content != "") {
        Serial.println(content);
    }

    Serial.println("Temperature");
    Serial.println(content.substring(1, 6));
    Serial.println("Humidity");
    Serial.println(content.substring(7, 12));
    delay(2000);
}

```
> 0 votes

---
Tags: serial, communication, esp8266
---


# Question
Title: Use a Unicode surrogate pair character in Arduino IDE
I'm writing a sketch for a Wemos D1 Mini to display a web page. This works and I can get Unicode characters to display, but if I try to use ones with surrogate pairs like 🔊 I get a compile error;

```
  s += "\uD83D\uDD0A";

```

Error

> \uD83D is not a valid universal character

How can I get this character in my code?

# Answer
> 1 votes
There is a nifty new feature in C++11 called string literal, this example shows how to use it with any single line or multi line or utf8 text. You just define starting and ending sequence, in following case `---` (starting sequence becomes `R"---(` and ending sequence `)---"`) and make sure that this sequence does not appear in encapsulated text. This is great for integrating websites into arduino projects:

```
static const char _index_html[] PROGMEM = R"---(
<html>
<head>
<link rel="icon" type="image/png" href="/favicon.png"/>
</head>
<body>
...
</body>
</html>
)---";

```

# Answer
> 0 votes
After some trial and error, I got it using the python style `u"\U0001F50A"` without the leading u of course

```
  s += "\U0001F50A";

```

Too bad I didn't think about googling the error msg, would have saved me some time.

---
Tags: arduino-ide
---


# Question
Title: Writing "theremin" outputs to a MIDI file on an SD card
I am making a musical instrument (theremin simulator). I want there to be a "record" capability which stores the volume and note the user is playing, into a MIDI file. Note this doesn't actually record audio, just data for the frequency and volume at a certain point in time.

So far I've done some research and have found how to play MIDI files (which is useful and I plan to take this on as well) and read/write to SD cards. However I haven't found a source which allows me to create and produce MIDI files.

How should I accomplish this feature?

Specs:

* I am using an Arduino Nano, I have an Uno too if needed
* The SD card is a 64GB micro SD, inserted into an SD adapter, with header pins soldered onto it. (I am too cheap to buy an actual shield)
* It was previously XCSD, I formatted it to FAT32 to be compatible with Arduino

Also: I am recording from a self built replica of a theremin, which is basically two ultrasonic sensor readings for volume and pitch. Is this "too basic" for a MIDI file type? *(Edit: I guess this is too advanced)*

**EDIT:** This project has been abandoned because of no good way to play **between** semitones (i.e. at specific frequencies), which is what I need for my theremin. Although there is the pitch bend functionality, the amount of pitch bend translates to different frequency changes based on the receiver.

Instead, I will create my own custom file to achieve the record/playback, because using the pitch bend + note method using MIDI is just too much work and it won't be compatible with other devices anyway.

Nick Gammon's answer is really thorough for those who **only** need to record/play specific **tones and semitones** in MIDI format.

Thanks

# Answer
The short answer would be "yes, it is possible". There are lots of gadgets around that record MIDI. They would have microprocessors in them, and they would have something like an SD card, which itself is like EEPROM in concept.

You may possibly have problems with storing the notes in RAM, and then writing them to the SD card fast enough not to lose some. Knowing the rate at which notes would arrive, the speed of the SD card, and the type of Arduino would help to answer if your specific case was likely to work.

I wrote a sketch that reads MIDI which shows that it is certainly possible to receive MIDI data and display it. Video of it running is here.

~~I don't personally know the format of MIDI files, but it is well documented.~~

(Edit) I do now - see further down.

Writing to SD cards is well documented. Making your idea work would be a case of taking stuff (like my code to decode MIDI), code to write to SD cards, and knowing the correct format.

---

**(Edited to add)**

See Standard MIDI-File Format Spec. 1.1 for an example of producing MIDI data. Also see The MIDI File Format and the Standard MIDI File (SMF) Format

Your basic technique would need to be (as suggested by gabonator):

* Write a header chunk to the file, for example:

```
  4D 54 68 64   // MThd
  00 00 00 06   // chunk length
  00 00         // format 0
  00 01         // one track
  00 60         // 96 pulses per quarter-note

```
* Write a track chunk to the file (the length will be updated later)

```
  4D 54 72 6B   // MTrk
  00 00 00 00   // <-- length to be updated later

```
* Write instrument configurations (with time delta values of zero), as an example from that page:

```
  00  FF 58 04  04 02 18 08  // 4 bytes; 4/4 time; 24 MIDI clocks/click,
                             // 8 32nd notes/ 24 MIDI clocks
                             // (24 MIDI clocks = 1 crotchet = 1 beat)
  00  FF 51 03  07 A1 20     // 3 bytes: 500,000 µsec/ quarter note
                             // = 120 beats/minute (500000 in hex is 0x07A120)
  00  C0 05                  // Ch.1 Program Change 5 = GM
                             // Patch 6 = Electric Piano 2

```
* When the player plays something, subtract the time that s/he last did something from the time now. This will give you the delta time.
* Convert the time difference to ticks. From the header line above we have 96 pulses per quarter note (PPQ), and 500,000 µs (500 ms) per quarter note. Thus one second would be two quarter notes (2 beats per second, and therefore 120 beats per minute) and one second is therefore 192 ticks). Therefore the number of ticks, based on the time difference in milliseconds, would be:

```
  unsigned long ticks = (time_difference * 192) / 1000

```
* Output the delta time as a variable length number, where the high order bit is set for each byte, as necessary, until what is left is \<= 0x7F. The page above gives sample code for that. For example, for a delta time of 199 ticks:

```
  Decimal time of 199 ticks -> 0xC7
  0xC7 -> 0b11000111
  Since that exceeds 127, split into two bytes:

  10000001  (the high order bits)
   ^^^^^^^  <- high order bits (the MSB must be one)
  01000111  (the low-order 7 bits)
   ^^^^^^^  <- low order bits (the MSB must be zero)

  Result is 0x81 0x47

```

Longer times may require even more bytes.

Something like this should do it (adapted from the linked page). Just change the Serial.write line to output to your disk file.

```
  void WriteVarLen (unsigned long value)
    {
    unsigned long buffer;

    buffer = value & 0x7f;
    while ((value >>= 7) > 0)
      {
      buffer <<= 8;
      buffer |= 0x80;
      buffer |= value & 0x7f;
      }

    while (true)
      {
      Serial.write (buffer & 0xFF);
      if (buffer & 0x80)
        buffer >>= 8;
      else
        break;
      }
    }   // end of WriteVarLen

```
* Follow the delta time immediately by the "note on" or "note off" byte (depending on whether they started or stopped playing a note). For example, "note on" for channel 1 would be 0x90 because 0x9n is a note on command and n is the channel number, zero relative. A "note off" for channel 1 would be 0x80.
* Follow the "note on" or "note off" by the note number (in other words, *which* note was just played or released) - one byte.

```
  Octave #  Note Numbers in decimal
            C   C#  D   D#  E   F   F#  G   G#  A   A#  B
  -1         0   1   2   3   4   5   6   7   8   9  10  11
  0         12  13  14  15  16  17  18  19  20  21  22  23
  1         24  25  26  27  28  29  30  31  32  33  34  35
  2         36  37  38  39  40  41  42  43  44  45  46  47
  3         48  49  50  51  52  53  54  55  56  57  58  59
  4         60  61  62  63  64  65  66  67  68  69  70  71
  5         72  73  74  75  76  77  78  79  80  81  82  83
  6         84  85  86  87  88  89  90  91  92  93  94  95
  7         96  97  98  99 100 101 102 103 104 105 106 107
  8        108 109 110 111 112 113 114 115 116 117 118 119
  9        120 121 122 123 124 125 126 127

```

Typically middle C is considered to be C4 (C in the 4th octave), however apparently that can vary between devices.
* Then output the velocity (one byte). A velocity of (decimal) 32 would be soft, 64 would be medium, 96 would be loud. The range for velocities is 0 to 127.
* Repeat the above (except for writing the chunks and the configuration) until the player decides to stop playing.
* Write an "end of track" marker:

```
  00  FF 2F 00    // Delta time zero, end of track

```
* Then seek back to the start of the file + where the length bytes are (18 bytes into the file by the looks of it) and update the length bytes (4 bytes).

---

# Example of producing a MIDI file

This example code writes out a MIDI file. As an input device I used a 16-key keypad like this:

The columns were connected to pins 0, 1, 2, 3 of the Arduino Uno, and the rows to pins 4, 5, 6, 7. This makes the ribbon cable from the keypad keep the pins in a natural order. If you use different pins just change the `keys` array in the sketch.

The library for keypads that I used is available at https://github.com/nickgammon/Keypad\_Matrix

This particular library supports n-key rollover and key-down and key-up events. That is particularly useful for music, because it lets you hold multiple keys down at once, and the appropriate events will be generated. Obviously you need a key-down event to generate "note on" and a key-up event to generate "note-off".

I laid out the keys like this:

```
C     C#    D     D#
E     F     F#    G
G#    A     A#    B
Down  Soft  Up    Record

```
* There is a "recording" LED connected to A0 which lights up when you start recording (by pressing the Record button).
* Press the Record button again to stop recording and finalize the file. It is important to stop recording properly and not just power off the device, because the length of the file needs to be written near the start.
* Press (and hold) Down alongside with another note to play an octave lower. Press (and hold) Up alongside with another note to play an octave higher.
* Press (and hold) Soft alongside with another note to play at a softer velocity.

Using a keypad matrix is logical, because most keyboard devices would use a matrix, to reduce the number of wires you have to run.

Note that the matrix needs diodes wired for each switch as described here because otherwise if you press 3 or more keys at once you will get "ghost" keys.

In my case I opened up the commercial keypad and soldered in the diodes.

---

I also used a Micro-SD breakout adapter, connected to the SPI pins of the Arduino, like this:

---

The SDFat library was an archived one that I keep here: http://gammon.com.au/Arduino/SdFat-master.zip (2.2 Mb)

Unzip that file, and from within the folders inside it, copy the SdFat folder into your "libraries" folder (which is under your Arduino sketchbook folder - not inside the Arduino application folder). Then restart the Arduino IDE.

The code definitely compiles with that (with a handful of warnings). The later library from https://github.com/greiman/SdFat may be an improvement but I haven't tested that.

---

To keep track of file numbers I used the EEPROMAnything library, a copy of which can be found at http://gammon.com.au/Arduino/EEPROMAnything.zip

Each time you start a new recording it adds one to the file number, which wraps around to 0000 once it reaches 9999.

---

If there is an error initializing the file system (eg. no SD card) then the LED blinks slowly. If the file can't be created the LED blinks rapidly.

---

You can choose a MIDI instrument by changing the line:

```
const byte PATCH_NUMBER = 4;   // electric piano 1

```

---

# Code

```
/*
 Sketch to write to a MIDI file from an instrument.
 Author: Nick Gammon
 Date:   10th May 2018

 Copyright 2018 Nick Gammon.

 PERMISSION TO DISTRIBUTE

 Permission is hereby granted, free of charge, to any person obtaining a copy of this software
 and associated documentation files (the "Software"), to deal in the Software without restriction,
 including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
 and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
 subject to the following conditions:

 The above copyright notice and this permission notice shall be included in
 all copies or substantial portions of the Software.

 LIMITATION OF LIABILITY

 The software is provided "as is", without warranty of any kind, express or implied,
 including but not limited to the warranties of merchantability, fitness for a particular
 purpose and noninfringement. In no event shall the authors or copyright holders be liable
 for any claim, damages or other liability, whether in an action of contract,
 tort or otherwise, arising from, out of or in connection with the software
 or the use or other dealings in the software.

*/

#include <Keypad_Matrix.h>
#include <SdFat.h>
#include <EEPROM.h>
#include <EEPROMAnything.h>

// For MIDI numbers see: http://www.pjb.com.au/muscript/gm.html
const byte PATCH_NUMBER = 4;   // electric piano 1

const byte RECORDING_LED = A0;

// bottom row changes things
const char DOWN_OCTAVE  = '-';
const char SOFT         = 's';
const char UP_OCTAVE    = '+';
const char RECORD       = 'r';

// how the keypad has its keys laid out
// capital letters are for sharps
const byte ROWS = 4;
const byte COLS = 4;
const char keys[ROWS][COLS] = {
  {'c', 'C', 'd', 'D'},
  {'e', 'f', 'F', 'g'},
  {'G', 'a', 'A', 'b'},
  {DOWN_OCTAVE, SOFT, UP_OCTAVE, RECORD},  // - = down octave, s = soft, + = up octave, r = start/stop record
};

const byte colPins[COLS] = {0, 1, 2, 3}; //connect to the column pinouts of the keypad
const byte rowPins[ROWS] = {4, 5, 6, 7}; //connect to the row pinouts of the keypad

// Create the Keypad
Keypad_Matrix kpd = Keypad_Matrix( makeKeymap (keys), rowPins, colPins, ROWS, COLS );

// file system object
SdFat sd;
const byte chipSelect = SS;

// the current file we are recording to
SdFile myFile;
// are we recording right now?
bool recording = false;

const byte MIDI_META_EVENT = 0xFF;
const byte MIDI_SET_TEMPO  = 0x51;
const byte MIDI_TIME_SIGNATURE = 0x58;
const byte MIDI_END_OF_TRACK = 0x2F;
const byte MIDI_PROGRAM_CHANGE = 0xC0;
const byte MIDI_NOTE_ON = 0x90;   // channel 1
const byte MIDI_NOTE_OFF = 0x80;  // channel 1

struct
  {
  char magic [4]; // MThd
  uint32_t length;
  uint16_t format;
  uint16_t tracks;
  uint16_t PPQ;    // pulses per quarter note
  } chunkHeader;

struct
  {
  char magic [4]; // MTrk
  uint32_t length;
  } trackHeader;

unsigned long trackHeaderPosition;
unsigned long timeLastAction;
int           nextFileNumber;

uint32_t changeEndianness32(uint32_t val)
{
  return (val << 24) |
        ((val <<  8) & 0x00ff0000) |
        ((val >>  8) & 0x0000ff00) |
        ((val >> 24) & 0x000000ff);
} // end of changeEndianness32

uint16_t changeEndianness16(uint16_t val)
{
  return (val << 8) | ((val >> 8) & 0x00ff);
} // end of changeEndianness16

void showError (const int delayTime)
  {
  while (true)
    {
    digitalWrite (RECORDING_LED, HIGH);
    delay (delayTime);
    digitalWrite (RECORDING_LED, LOW);
    delay (delayTime);
    }

  } // end of showError

void startRecording ()
  {
  EEPROM_readAnything (0, nextFileNumber);
  if (nextFileNumber > 9999 || nextFileNumber < 0)
    nextFileNumber = 0;

  char name[15];
  sprintf (name, "SONG%04d.MID", nextFileNumber++);

  // open the file for writing
  if (!myFile.open(name, O_WRITE | O_CREAT | O_TRUNC))
    showError (100);  // fast flash - never returns

  // update EEPROM for next time
  EEPROM_writeAnything (0, nextFileNumber);

  recording = true;
  digitalWrite (RECORDING_LED, HIGH);
  memcpy (chunkHeader.magic, "MThd", sizeof (chunkHeader.magic));
  chunkHeader.length = changeEndianness32 (
                       sizeof (chunkHeader.format) +
                       sizeof (chunkHeader.tracks) +
                       sizeof (chunkHeader.PPQ));

  chunkHeader.format = changeEndianness16 (0);
  chunkHeader.tracks = changeEndianness16 (1);
  chunkHeader.PPQ = changeEndianness16 (96);
  myFile.write (&chunkHeader, sizeof (chunkHeader));
  memcpy (trackHeader.magic, "MTrk", sizeof (trackHeader.magic));
  trackHeader.length = 0;   // to be filled in later
  trackHeaderPosition = myFile.curPosition ();
  myFile.write (&trackHeader, sizeof (trackHeader));

  struct
    {
    byte deltaTime = 0;
    byte metaCode [2] = { MIDI_META_EVENT, MIDI_TIME_SIGNATURE };
    byte length = 4;
    byte sig [2] = { 4, 2 };  // 4/4 time (denominator of 2 is 2^2)
    byte clocksPerClick = 24;  // MIDI clocks/click
    byte clocksPerBeat  = 8;
    }  timeSignature;

 struct
    {
    byte deltaTime = 0;
    byte metaCode [2] = { MIDI_META_EVENT, MIDI_SET_TEMPO };
    byte length = 3;
    byte usPerQuarterNote [3] = { 0x07, 0xA1, 0x20 };  // that is: 500000 µs per beat
    }  tempo;

 struct
    {
    byte deltaTime = 0;
    byte message =   MIDI_PROGRAM_CHANGE;
    byte patchNumber = PATCH_NUMBER;
    }  programChange;

  myFile.write (&timeSignature, sizeof timeSignature);
  myFile.write (&tempo, sizeof tempo);
  myFile.write (&programChange, sizeof programChange);
  timeLastAction = millis ();
  } // end of startRecording

void stopRecording ()
  {
  struct
    {
    byte deltaTime = 0;
    byte metaCode [2] = { MIDI_META_EVENT, MIDI_END_OF_TRACK };
    byte length = 0;
    }  endOfTrack;

  // write out "end of track" message
  myFile.write (&endOfTrack, sizeof endOfTrack);
  // find where we are
  unsigned long finalPosition = myFile.curPosition ();
  // go back to where the track header is
  myFile.seekSet (trackHeaderPosition);
  // work out how long the data was (excluding the headers)
  trackHeader.length = changeEndianness32 (finalPosition - trackHeaderPosition - sizeof (trackHeader));
  // update the file length
  myFile.write (&trackHeader, sizeof (trackHeader));

  myFile.close ();
  // ensure flushed to disk
  myFile.SdBaseFile::sync();

  // no longer recording, turn off recording LED
  recording = false;
  digitalWrite (RECORDING_LED, LOW);
  } // end of stopRecording

void writeVarLen(unsigned long value)
{
  unsigned long buffer;

  buffer = value & 0x7f;
  while ((value >>= 7) > 0)
  {
    buffer <<= 8;
    buffer |= 0x80;
    buffer |= value & 0x7f;
  } // end of while

  while (true)
  {
    myFile.write ((byte) (buffer & 0xFF));
    if (buffer & 0x80)
      buffer >>= 8;
    else
      break;
  } // end of while

}   // end of writeVarLen

// turn the keypad code into a note number
byte codeToNote (const char which)
{
  char notes [] = "cCdDefFgGaAb";
  char * pos = strchr (notes, which);
  if (pos == NULL)
    return 0;
  return pos - notes + 60;  // start at middle C (C4)
} // end of codeToNote

// do a note on or note off
void doNoteAction (const char which, const byte action)
{
  // we need to work out how many milliseconds have elapsed
  unsigned long now = millis ();
  unsigned long deltaTime = now - timeLastAction;
  // remember when we did this
  timeLastAction = now;
  // write out the delta time
  writeVarLen ((deltaTime * 192) / 1000);

  // note information
  struct
    {
    byte noteOn;
    byte whichNote;
    byte velocity;
    } playNote;

  playNote.noteOn = action;
  playNote.whichNote = codeToNote (which);
  if (kpd.isKeyDown (DOWN_OCTAVE))
    playNote.whichNote -= 12;  // one octave down
  else if (kpd.isKeyDown (UP_OCTAVE))
    playNote.whichNote += 12;  // one octave up

  playNote.velocity = 64;      // medium velocity
  if (kpd.isKeyDown (SOFT))
    playNote.velocity = 32;    // softer

  myFile.write (&playNote, sizeof (playNote));
} // end of doNoteAction

void startPlaying (const char which)
  {
  doNoteAction (which, MIDI_NOTE_ON);
  } // end of startPlaying

void stopPlaying (const char which)
  {
  doNoteAction (which, MIDI_NOTE_OFF);
  } // end of stopPlaying

void keyDown (const char which)
  {
  switch (which)
    {
    case 'c':
    case 'C':
    case 'd':
    case 'D':
    case 'e':
    case 'f':
    case 'F':
    case 'g':
    case 'G':
    case 'a':
    case 'A':
    case 'b':
      startPlaying (which);
      break;

    default:
      break;
    } // end of switch on which key
  } // end of keyDown

void keyUp (const char which)
  {
  switch (which)
    {
    case RECORD:
      if (recording)
        stopRecording ();
      else
        startRecording ();
      break;

    case 'c':
    case 'C':
    case 'd':
    case 'D':
    case 'e':
    case 'f':
    case 'F':
    case 'g':
    case 'G':
    case 'a':
    case 'A':
    case 'b':
      stopPlaying (which);
      break;

    default:
      break;
    } // end of switch on which key
  } // end of keyUp

void setup()
{
  kpd.begin ();
  kpd.setKeyDownHandler (keyDown);
  kpd.setKeyUpHandler   (keyUp);
  pinMode (RECORDING_LED, OUTPUT);

  if (!sd.begin (chipSelect, SPI_HALF_SPEED))
     showError (500);  // never returns

} // end of setup

void loop()
{
  kpd.scan ();
} // end of loop

```

---

> I am recording from a self built replica of a theremin, which is basically two ultrasonic sensor readings for volume and pitch. Is this "too basic" for a MIDI file type?

It looks like this could be possible by using the MIDI "pitch bend" message. You would need to determine where your note value was (presumably most of the time *between* the natural notes like C and C#) and then send a bend message or "Pitch Wheel Change" (0xE0 for channel 1) to modify the main note. The main note would need to be updated if you moved more than a couple of semitones away.

See:
> 5 votes

# Answer
Yes, read the MIDI file format specification. Create a single track midi file and append just note press / release commands / pitch or volume changes and delta times (reverse conversion of delta times to milliseconds is explained here). When you finish recording, just seek to the beginning of the file and update the track length value (total size of the appended buffer of midi commands)
> 3 votes

---
Tags: spi, sd-card, audio, midi
---


# Question
Title: Rewrite part of the example code from Adafruit FONA
Recently, I bought the FONA 800 shield from Adafruit. I have got it running with the examples and it plays very nicely.

I want to use the part of the example code which handles a call in my own sketch. The example code waits for a number to call which should be entered in the serial. I want to do the exact same thing, just with the phone number supplied from a variable in Arduino.

I have two possibilities: To supply the whole number when the call should be performed and to build up let's say an array every time a number is entered.

The code for performing a call:

```
// call a phone!
    char number[30];
    flushSerial();
    Serial.print(F("Call #"));
    readline(number, 30);
    Serial.println();
    Serial.print(F("Calling ")); Serial.println(number);
    if (!fona.callPhone(number)) {
      Serial.println(F("Failed"));
    } else {
      Serial.println(F("Sent!"));
    }

```

The flushSerial function:

```
void flushSerial() {
  while (Serial.available())
  Serial.read();
}

```

And the readline function:

```
uint8_t readline(char *buff, uint8_t maxbuff, uint16_t timeout) {
uint16_t buffidx = 0;
boolean timeoutvalid = true;
if (timeout == 0) timeoutvalid = false;

while (true) {
  if (buffidx > maxbuff) {
    //Serial.println(F("SPACE"));
    break;
  }

while (Serial.available()) {
  char c =  Serial.read();

  //Serial.print(c, HEX); Serial.print("#"); Serial.println(c);

  if (c == '\r') continue;
  if (c == 0xA) {
    if (buffidx == 0)   // the first 0x0A is ignored
      continue;

    timeout = 0;         // the second 0x0A is the end of the line
    timeoutvalid = true;
    break;
  }
  buff[buffidx] = c;
  buffidx++;
}

if (timeoutvalid && timeout == 0) {
  //Serial.println(F("TIMEOUT"));
  break;
}
  delay(1);
}
  buff[buffidx] = 0;  // null term
  return buffidx;
}

```

It is the readline function which should be edited. Right now it retrieves the number entered from serial.

I am kind of a newbie myself so I am not that familiar with data types and so on.

Thank you very much for any answers.

EDIT: The function without readline:

```
if (!fona.callPhone("12345678")) {
        Serial.println(F("Failed calling"));
      } else {
        Serial.println(F("Calling ..."));
      }

```

# Answer
> 1 votes
I had to enter the numbers as a string. Also I found out that I had set the variables in a wrong way.

The library for the FONA Shield needs the number to call as a string. They are creating it by assigning the input from serial to a char. The problem was that I tried to input numbers. Also, I found out that when I tried to work with variables instead of hard coded numbers I messed around in data types.

Final conclusion: When calling the fona.callPhone function, you have to put in a string containing the numbers instead of actual numbers.

---
Tags: arduino-uno
---