text:
Arduino 4wd rover
Guys i have made an arduino 4wd rover using L298N BRIDGE MODULE, HC-05 and Arduino uno but the power supply output of L298N was very low that even 1 motor is working too slow so please help me with power out put please...
Here is the code...
#define enA 9
#define in1 4
#define in2 5
#define enB 10
#define in3 6
#define in4 7

int xAxis, yAxis;
int  x = 0;
int  y = 0;

int motorSpeedA = 0;
int motorSpeedB = 0;

void setup() {
  pinMode(enA, OUTPUT);
  pinMode(enB, OUTPUT);
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(in3, OUTPUT);
  pinMode(in4, OUTPUT);

  Serial.begin(38400); // Default communication rate of the Bluetooth module
}

void loop() {
  // Default value - no movement when the Joystick stays in the center
  xAxis = 510;
  yAxis = 510;

  // Read the incoming data from the Smartphone Android App
  while (Serial.available() >= 2) {
    x = Serial.read();
    delay(10);
    y = Serial.read();
  }
  delay(10);

  // Makes sure we receive corrent values
  if (x > 60 & x < 220) {
    xAxis = map(x, 220, 60, 1023, 0); // Convert the smartphone X and Y values to 0 - 1023 range, suitable motor for the motor control code below
  }
  if (y > 60 & y < 220) {
    yAxis = map(y, 220, 60, 0, 1023);
  }

  // Y-axis used for forward and backward control
  if (yAxis < 470) {
    // Set Motor A backward
    digitalWrite(in1, HIGH);
    digitalWrite(in2, LOW);
    // Set Motor B backward
    digitalWrite(in3, HIGH);
    digitalWrite(in4, LOW);
    // Convert the declining Y-axis readings for going backward from 470 to 0 into 0 to 255 value for the PWM signal for increasing the motor speed
    motorSpeedA = map(yAxis, 470, 0, 0, 255);
    motorSpeedB = map(yAxis, 470, 0, 0, 255);
  }
  else if (yAxis > 550) {
    // Set Motor A forward
    digitalWrite(in1, LOW);
    digitalWrite(in2, HIGH);
    // Set Motor B forward
    digitalWrite(in3, LOW);
    digitalWrite(in4, HIGH);
    // Convert the increasing Y-axis readings for going forward from 550 to 1023 into 0 to 255 value for the PWM signal for increasing the motor speed
    motorSpeedA = map(yAxis, 550, 1023, 0, 255);
    motorSpeedB = map(yAxis, 550, 1023, 0, 255);
  }
  // If joystick stays in middle the motors are not moving
  else {
    motorSpeedA = 0;
    motorSpeedB = 0;
  }

  // X-axis used for left and right control
  if (xAxis < 470) {
    // Convert the declining X-axis readings from 470 to 0 into increasing 0 to 255 value
    int xMapped = map(xAxis, 470, 0, 0, 255);
    // Move to left - decrease left motor speed, increase right motor speed
    motorSpeedA = motorSpeedA - xMapped;
    motorSpeedB = motorSpeedB + xMapped;
    // Confine the range from 0 to 255
    if (motorSpeedA < 0) {
      motorSpeedA = 0;
    }
    if (motorSpeedB > 255) {
      motorSpeedB = 255;
    }
  }
  if (xAxis > 550) {
    // Convert the increasing X-axis readings from 550 to 1023 into 0 to 255 value
    int xMapped = map(xAxis, 550, 1023, 0, 255);
    // Move right - decrease right motor speed, increase left motor speed
    motorSpeedA = motorSpeedA + xMapped;
    motorSpeedB = motorSpeedB - xMapped;
    // Confine the range from 0 to 255
    if (motorSpeedA > 255) {
      motorSpeedA = 255;
    }
    if (motorSpeedB < 0) {
      motorSpeedB = 0;
    }
  }
  // Prevent buzzing at low speeds (Adjust according to your motors. My motors couldn't start moving if PWM value was below value of 70)
  if (motorSpeedA < 70) {
    motorSpeedA = 0;
  }
  if (motorSpeedB < 70) {
    motorSpeedB = 0;
  }
  analogWrite(enA, motorSpeedA); // Send PWM signal to motor A
  analogWrite(enB, motorSpeedB); // Send PWM signal to motor B
}

What is the battery? Are you using geared motors?

I am using 9v battery and yes it is a geared motor.....

A wimpy PP3? ...?

The 9V battery is meant for low power applications. You will need to find another powersource

While your primary problem is improper battery selection (try 6 to 8 AA cells) also beware that the L298 (and L293D, etc) is an antiquated, horribly lossy driver.  These really shouldn't be sold for Arduino or other low-voltage projects - they continue to be because people keep copying a mistake that was already wrong even when it was made now many years ago.  Typically when using AA cells and an L298, you need an extra cell or two in the pack just to offset the L298's losses.

Can i use a powerbank with 10000 Mah battery...?

@CodeGorilla That question doesn't have an answer though.

You need more power!
The formula for power is Volts * Amps. A PP3 has about 500mAh, which means its can (in theory) output 9V at 500mA for an hour, which means you have about 4.5 watts.
So what power do your motors need? I'll assume they are about 1.5W motors, which means you need 6W to drive all the motors.
Your PP3 can output 6W, but it won't last long if it does and it will get hot.  Also, if you have 12V motors and are only giving the 9V then they are going to be asking for 1/3 more amps to balance the equation and get their power.  You are probably asking the PP3 to supply 1A which means it will last less than 30 minutes if it is brand new and good quality.
A "simple" solution would be to use two (or more) batteries in parallel.  Parallel gives you more power without changing the voltage.  A better solution would be to look at alternative battery packs, a couple or LiPo 3.7V 1100mAh battery packs, a sealed lead acid gel (heavy).  An even better solution would be to see if you can get lower power motors that can supply the same torque.
Failing that, get a meaty desktop power supply and a long cable :)

Can i use a powerbank with 10000 Mah battery...?

Maybe -\o/-  It will either work or it won't


text:
How to write a code to detect how many times the IR detector has detected an IR signal.... HELP
I am trying to write a code so that I can detect how many times the IR detector has detected the IR signal from the IR transmitter.

Welcome to Arduino:SE. What have you managed to do so far?. You might find this helpful: How to ask a good question for Arduino Stack Exchange

Its quite simple:
IRDetectorLibraryObject ir;
int counter = 0;

void setup()
{
    ir.setup();
}
void loop ()
{
    if (ir.detectedSignal())
    {
      ++counter;
    }
}

Of course all that relies on you having an IR detector library like the one i imagined you had, and you only wanting to count the detections and never know what the value is, but apart from that...

It would be great if you can also give us the circuit diagram...

The compiler says it cannot recognize the data type of IRDetectorLibraryObject

It wont recognise it because you need to find one that is compatible with your hardware and use that name instead.  As for a circuit diagram that depends on you hardware, if you don't specify that then I can only guess that you need to plug the wires from the IR detector into a microprocessor, and you might want to power the uP from a 5v source, but your hardware may be different to the hardware I am imagining you have.

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/

sort: votes


text:
Two pots controlling 2 servos -- odd behavior
I'm trying to control 2 servos with 2 pots. I thought I could just amend the tutorial code by adding in the extra pot on a1 and extra servo on d8 (am using a Nano).
#include <Servo.h>

Servo myservo;  // create servo object to control a servo
Servo myservo_2;

int potpin = 0;  // analog pin used to connect the potentiometer
int potpin_2 = 1;
int val;    // variable to read the value from the analog pin
int val_2;

void setup() {
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object
  myservo_2.attach(8);
}

void loop() {
  val = analogRead(potpin);            // reads the value of the potentiometer (value between 0 and 1023)
  val_2 = analogRead(potpin_2);
  val = map(val, 0, 1023, 0, 180);     // scale it to use it with the servo (value between 0 and 180)
  val_2 = map(val_2, 0, 1023, 0, 180);
  myservo.write(val);                  // sets the servo position according to the scaled value
  myservo_2.write(val_2);
  delay(15);                           // waits for the servo to get there
}

...but the servos only respond to one of the pots (on a0) & both move to the same position regardless of what value is on a1.
Am I missing something really obvious? Why is the value on a1 ignored & why is the value mapped from a0 sent to both d8 & d9?
I have swapped out the pot on a1 just in case it was faulty but I get the same behavior.
EDIT: Added schematic

EDIT: I swapped out the Nano for another Nano but that failed to upload the sketch. So I put the original back in & now evrything is working fine!
Darn'd if I can get my head around it, possibly a bad connection with the bread board?
Anyway all working now thanks for your suggestions.

How are your potentiometers connected?

between the + & - rails with the sliders connected to a0 & a1. Works fine for the unaltered single servo code from the tutorial

added schematic for clarity

Use A0 and A1 in your code for the analog pins instead of 0 and 1.

Using A0 & A1 has made no difference to the behavior

That the reading from a0 and send it to both servos but reverse one of them (180-value).

I have no idea whats wrong with your system, but this might help you diagnose it.
#include <Servo.h>

static const size_t MaxServos = 2;              // The number of pots and servos attached
const int servoPins[MaxServos] = {9, 8};        // The pins that the servos are controlled through
const int potpins[MaxServos] = {A0, A1};        // analog pin used to connect the potentiometer
Servo myservo[MaxServos];                       // create servo object to control a servo

void setup ()
{
    for (size_t index = 0; index < MaxServos; ++index)
    {
        myservo[index].attach (servoPins[index]);
    }
}

void loop ()
{
    for (size_t index = 0; index < MaxServos; ++index)
    {
        readAndSet (potpins[index], myservo[index]);
    }
    delay (15);                           // waits for the servo to get there - might want to multiply a value by the number of degrees turned to give a better value.
}

// \brief   Read the specified analog pin and set the server proportionally
// \param   The analog pin that the pot is connected to.
// \param   The servo that will be moved
void readAndSet (const int& pin, Servo& servo)
{
    const int value = analogRead (pin);            // reads the value of the potentiometer (value between 0 and 1023)
    const int mappedValue = map (value, 0, 1023, 0, 180);     // scale it to use it with the servo (value between 0 and 180)
    servo.write (mappedValue);                  // sets the servo position according to the scaled value
}

I have refactored your code to eliminate the duplication.  This means you will get more test coverage and you should find the bug quicker.  You could add a Serial print statement to the readAndSet function to ensure that you are passing and calculating the right values, but I suspect you are.
There appears to be nothing wrong with the code, so is it possible that there is some hardware limitation?  Is there a short between the lines that causes the pot on A1 to be bypassed?

thanks, what is size_t? I edited my question, once I swapped out then replaced the orignal Nano the system works as expected.

its an unsigned int.  You only need to count from 0 to +0xffff so don't bother using an int.

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/


text:
if/else statements without comparison operators and curly braces
I recently came across this code in a tutorial. The code works, but this form of syntax seems to differ quite a bit from https://www.arduino.cc/reference/en/language/structure/control-structure/if/, as it's lacking comparison operators and curly braces for statements. Can someone please run down why this works?
for (int i = 0; i < 15; i++)
{
lcd.setCursor(i, 1);
if (pressed[i])
  lcd.print("X");
else
  lcd.print(" ");

if (justpressed[i])
  digitalWrite(led, HIGH);
else
  digitalWrite(led, LOW);
 }

Arduino uses C++ programming language with specific libraries and .ino file conversion to C++ http://www.cplusplus.com/doc/tutorial/

About the missing conditions, e.g.:
if (pressed[i])

If is supposed to be a boolean, this is the prefered way, as long as the boolean has value zero (0) when false and nonzero when true. It is the same as writing:
if (pressed[i] != 0)

It is not usual to do this for integers, only for booleans.
About the brackets: If you have only one statement the brackets can be omitted. But it is quite a bad programming practice, since sooner or later you add a statement, without the brackets added and you have a bug introduced.
If you really want to shorten it than instead of
if (justpressed[i])
  digitalWrite(led, HIGH);
else
  digitalWrite(led, LOW);

use
digitalWrite(justpressed[i] ? HIGH : LOW);

This is called the Ternary operator.
update
Using the remark of wondra but with the ternary operation your code can be
for (int i = 0; i < 15; i++)
{
    lcd.setCursor(i, 1);
    lcd.print   (     pressed    [i] ? "X"  : " ");
    digitalWrite(led, justpressed[i] ? HIGH : LOW);
}

Just for fun of it, even the printing if/else can be much shortened: lcd.print(" X"[!!pressed[i]]);

@wondra right ... but most have to read a few times to see why it works.. I would it change to lcd.print(pressed[i] ? "X" : " "); probably.

Sadly, fun =/= smart in most cases. Fully agree - if the code is to be ever maintained one should stick to the most straight-forward solution (whatever that is it expected to be for the poor fellow doing the code maintenance).

True, in the organization I work for the ternary operation is allowed, but only in trivial cases like that, if bigger expressiosn are taken into account the if/else should be used. Btw; to make it shorter you can probably even put everything in the for statement (not loop).

It's actually called the "Conditional Operator". It just so happens to be the only ternary operator.

@wondra I don't know arduino, but if this is really C++ like another comment said then you'd be passing a char instead of a string to lcd.print(). It's not a problem if lcd.print is a polymorphic method that is also made to work with chars, but that's not necessarily the case, so that could be a bug. Strive not to write simple ideas in a complex manner, but to write complex ideas in a simple manner.

Small nit-pick: shouldn't it be equal to saying if (pressed[i] == 1), not if (pressed[i] != 0)?

@McMastery Actually it's not the same ... there is a convention (not always true, especially in C), that a boolean FALSE value is 0, and a TRUE value is non zero. In your case, if TRUE would be 255 it would go wrong.

@MichelKeijzers Ah, sorry. I thought the convention was the other way around for some reason

if (something) is the same as if(something!=0), if condition is a non-zero value, it is considered as fulfilled condition, read about the Conditionals - The true or false story
For single line statements you don't need to use curly braces. But using the braces makes the code more readable and the code is less prone to errors

It's worth noting that curly braces on single-line statements can definitely help prevent some insidious bugs: remember Apple's famous SSL bug? Curly braces almost certainly would have avoided that, or at least made it more clear where the error was.

@ke4ukz I think the fear of repeating that SSL bug is over stated. If you're going to use an inline if statement, do it ... in... line. Don't put it on a new line. if (someEarlyExitCondition()) return; never hurt anyone, if it was all in one line. The new line+indent that people put whenever they use inline if statements always confused me. It's just so unnecessary!

@Alexander I agree: inline for inline, curly braces for indenting/multiple lines


text:
Interfacing MPU6050 with Arduino through Simulink S-function
I am interfacing MPU6050 with Arduino using Simulink S-function builder.
I'm implementing MPU6050_DMP6 code in Simulink s-function builder by following this video. By following this tutorial I implemented the S-function as:
I set sample time 0.05 in s-function builder block and number of discrete state=1 and sample mode = 1.
in the libraries tab I put the following code:

#include <math.h>
#ifndef MATLAB_MEX_FILE
int counter=0;
#include <Arduino.h>
#include "I2Cdev.h"
#include "I2Cdev.cpp"

#include "helper_3dmath.h"
#include "MPU6050_6Axis_MotionApps20.h"
#include "MPU6050.h" // not necessary if using MotionApps include file
#include "MPU6050.cpp" // not necessary if using MotionApps include file
// Arduino Wire library is required if I2Cdev I2CDEV_ARDUINO_WIRE implementation
// is used in I2Cdev.h
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
    #include "Wire.h"
    #include "Wire.cpp"
    #include "utility/twi.h"
    #include "utility/twi.c"
#endif
// class default I2C address is 0x68
// specific I2C addresses may be passed as a parameter here
// AD0 low = 0x68 (default for SparkFun breakout and InvenSense evaluation board)
// AD0 high = 0x69
MPU6050 mpu;

#define OUTPUT_READABLE_YAWPITCHROLL

// uncomment "OUTPUT_READABLE_REALACCEL" if you want to see acceleration
// components with gravity removed. This acceleration reference frame is
// not compensated for orientation, so +X is always +X according to the
// sensor, just without the effects of gravity. If you want acceleration
// compensated for orientation, us OUTPUT_READABLE_WORLDACCEL instead.
//#define OUTPUT_READABLE_REALACCEL

// uncomment "OUTPUT_READABLE_WORLDACCEL" if you want to see acceleration
// components with gravity removed and adjusted for the world frame of
// reference (yaw is relative to initial orientation, since no magnetometer
// is present in this case). Could be quite handy in some cases.
//#define OUTPUT_READABLE_WORLDACCEL

// uncomment "OUTPUT_TEAPOT" if you want output that matches the
// format used for the InvenSense teapot demo
//#define OUTPUT_TEAPOT

#define INTERRUPT_PIN 2  // use pin 2 on Arduino Uno & most boards
#define LED_PIN 13 // (Arduino is 13, Teensy is 11, Teensy++ is 6)
bool blinkState = false;

// MPU control/status vars
bool dmpReady = false;  // set true if DMP init was successful
uint8_t mpuIntStatus;   // holds actual interrupt status byte from MPU
uint8_t devStatus;      // return status after each device operation (0 = success, !0 = error)
uint16_t packetSize;    // expected DMP packet size (default is 42 bytes)
uint16_t fifoCount;     // count of all bytes currently in FIFO
uint8_t fifoBuffer[64]; // FIFO storage buffer

// orientation/motion vars
Quaternion q;           // [w, x, y, z]         quaternion container
VectorInt16 aa;         // [x, y, z]            accel sensor measurements
VectorInt16 aaReal;     // [x, y, z]            gravity-free accel sensor measurements
VectorInt16 aaWorld;    // [x, y, z]            world-frame accel sensor measurements
VectorFloat gravity;    // [x, y, z]            gravity vector
float euler[3];         // [psi, theta, phi]    Euler angle container
float ypr[3];           // [yaw, pitch, roll]   yaw/pitch/roll container and gravity vector

// packet structure for InvenSense teapot demo
uint8_t teapotPacket[14] = { '$', 0x02, 0,0, 0,0, 0,0, 0,0, 0x00, 0x00, '\r', '\n' };

// ================================================================
// ===               INTERRUPT DETECTION ROUTINE                ===
// ================================================================

volatile bool mpuInterrupt = false;     // indicates whether MPU interrupt pin has gone high
void dmpDataReady() {
    mpuInterrupt = true;
}
#endif

in the discrete update tab I have implemented following code:
if (xD[0]!=1){
#ifndef MATLAB_MEX_FILE
       // join I2C bus (I2Cdev library doesn't do this automatically)
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
        Wire.begin();
        Wire.setClock(400000); // 400kHz I2C clock. Comment this line if having compilation difficulties
    #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
        Fastwire::setup(400, true);
    #endif

    // initialize serial communication
    // (115200 chosen because it is required for Teapot Demo output, but it's
    // really up to you depending on your project)
    Serial2.begin(115200);
//     while (!Serial); // wait for Leonardo enumeration, others continue immediately

    // NOTE: 8MHz or slower host processors, like the Teensy @ 3.3v or Ardunio
    // Pro Mini running at 3.3v, cannot handle this baud rate reliably due to
    // the baud timing being too misaligned with processor ticks. You must use
    // 38400 or slower in these cases, or use some kind of external separate
    // crystal solution for the UART timer.

    // initialize device
    Serial2.println(F("Initializing I2C devices..."));
    mpu.initialize();
    pinMode(INTERRUPT_PIN, INPUT);
    // verify connection
    Serial2.println(F("Testing device connections..."));
    Serial2.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed"));

    // wait for ready
   // Serial2.println(F("\nSend any character to begin DMP programming and demo: "));
   // while (Serial2.available() && Serial2.read()); // empty buffer
   // while (!Serial2.available());                 // wait for data
   // while (Serial2.available() && Serial2.read()); // empty buffer again

    // load and configure the DMP
    Serial2.println(F("Initializing DMP..."));
    devStatus = mpu.dmpInitialize();

    // supply your own gyro offsets here, scaled for min sensitivity
    mpu.setXGyroOffset(220);
    mpu.setYGyroOffset(76);
    mpu.setZGyroOffset(-85);
    mpu.setZAccelOffset(1788); // 1688 factory default for my test chip

    // make sure it worked (returns 0 if so)
    if (devStatus == 0) {
        // turn on the DMP, now that it's ready
        Serial2.println(F("Enabling DMP..."));
        mpu.setDMPEnabled(true);
        // enable Arduino interrupt detection
        Serial2.println(F("Enabling interrupt detection (Arduino external interrupt 0)..."));
        attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), dmpDataReady, RISING);
        mpuIntStatus = mpu.getIntStatus();
        // set our DMP Ready flag so the main loop() function knows it's okay to use it
        Serial2.println(F("DMP ready! Waiting for first interrupt..."));
        dmpReady = true;

        // get expected DMP packet size for later comparison
        packetSize = mpu.dmpGetFIFOPacketSize();
    } else {
        // ERROR!
        // 1 = initial memory load failed
        // 2 = DMP configuration updates failed
        // (if it's going to break, usually the code will be 1)
        Serial2.print(F("DMP Initialization failed (code "));
        Serial2.print(devStatus);
        Serial2.println(F(")"));
    }
    #endif

  xD[0]=1;
 }

and in output tab I have implemented this code:
if (xD[0]==1){
    #ifndef MATLAB_MEX_FILE
// if programming failed, don't try to do anything
    if (!dmpReady) {
        return;
    }

    // wait for MPU interrupt or extra packet(s) available
    while (!mpuInterrupt && fifoCount < packetSize) {
        // other program behavior stuff here
        // .
        // .
        // .
        // if you are really paranoid you can frequently test in between other
        // stuff to see if mpuInterrupt is true, and if so, "break;" from the
        // while() loop to immediately process the MPU data
        // .
        // .
        // .
    }

    // reset interrupt flag and get INT_STATUS byte
    mpuInterrupt = false;
    mpuIntStatus = mpu.getIntStatus();

    // get current FIFO count
    fifoCount = mpu.getFIFOCount();
    // check for overflow (this should never happen unless our code is too inefficient)
    if ((mpuIntStatus & 0x10) || fifoCount == 1024) {
        // reset so we can continue cleanly
        mpu.resetFIFO();
        // otherwise, check for DMP data ready interrupt (this should happen frequently)
    } else if (mpuIntStatus & 0x02) {
        // wait for correct available data length, should be a VERY short wait
        while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount();
        // read a packet from FIFO
        mpu.getFIFOBytes(fifoBuffer, packetSize);

        // track FIFO count here in case there is > 1 packet available
        // (this lets us immediately read more without waiting for an interrupt)
        fifoCount -= packetSize;

#ifdef OUTPUT_READABLE_QUATERNION
        // display quaternion values in easy matrix form: w x y z
        mpu.dmpGetQuaternion(&q, fifoBuffer);
        // Serial.print("quat\t");
        // Serial.print(q.w);
        // Serial.print("\t");
        // Serial.print(q.x);
        // Serial.print("\t");
        // Serial.print(q.y);
        // Serial.print("\t");
        // Serial.println(q.z);
#endif

#ifdef OUTPUT_READABLE_EULER
        // display Euler angles in degrees
//         mpu.dmpGetQuaternion(&q, fifoBuffer);
//         mpu.dmpGetEuler(euler, &q);
//         Serial.print("euler\t");
//         Serial.print(euler[0] * 180/M_PI);
//         Serial.print("\t");
//         Serial.print(euler[1] * 180/M_PI);
//         Serial.print("\t");
//         Serial.println(euler[2] * 180/M_PI);
#endif

#ifdef OUTPUT_READABLE_YAWPITCHROLL
        // display Euler angles in degrees
        mpu.dmpGetQuaternion(&q, fifoBuffer);
        mpu.dmpGetGravity(&gravity, &q);
        mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
        *roll = ypr[0] * 180/M_PI;
        *pitch = ypr[1] * 180/M_PI;
        *yaw = ypr[2] * 180/M_PI;
        Serial2.print("ypr\t");
        Serial2.print(ypr[0] * 180/M_PI);
        Serial2.print("\t");
        Serial2.print(ypr[1] * 180/M_PI);
        Serial2.print("\t");
        Serial2.println(ypr[2] * 180/M_PI);
#endif

#ifdef OUTPUT_READABLE_REALACCEL
        // display real acceleration, adjusted to remove gravity
        mpu.dmpGetQuaternion(&q, fifoBuffer);
        mpu.dmpGetAccel(&aa, fifoBuffer);
        mpu.dmpGetGravity(&gravity, &q);
        mpu.dmpGetLinearAccel(&aaReal, &aa, &gravity);
        // Serial.print("areal\t");
        // Serial.print(aaReal.x);
        // Serial.print("\t");
        // Serial.print(aaReal.y);
        // Serial.print("\t");
        // Serial.println(aaReal.z);
#endif

#ifdef OUTPUT_READABLE_WORLDACCEL
        // display initial world-frame acceleration, adjusted to remove gravity
        // and rotated based on known orientation from quaternion
        mpu.dmpGetQuaternion(&q, fifoBuffer);
        mpu.dmpGetAccel(&aa, fifoBuffer);
        mpu.dmpGetGravity(&gravity, &q);
        mpu.dmpGetLinearAccel(&aaReal, &aa, &gravity);
        mpu.dmpGetLinearAccelInWorld(&aaWorld, &aaReal, &q);
        // Serial.print("aworld\t");
        // Serial.print(aaWorld.x);
        // Serial.print("\t");
        // Serial.print(aaWorld.y);
        // Serial.print("\t");
        // Serial.println(aaWorld.z);
#endif

#ifdef OUTPUT_TEAPOT
        // display quaternion values in InvenSense Teapot demo format:
        teapotPacket[2] = fifoBuffer[0];
        teapotPacket[3] = fifoBuffer[1];
        teapotPacket[4] = fifoBuffer[4];
        teapotPacket[5] = fifoBuffer[5];
        teapotPacket[6] = fifoBuffer[8];
        teapotPacket[7] = fifoBuffer[9];
        teapotPacket[8] = fifoBuffer[12];
        teapotPacket[9] = fifoBuffer[13];
        Serial.write(teapotPacket, 14);
        teapotPacket[11]++; // packetCount, loops at 0xFF on purpose
#endif

        // blink LED to indicate activity
        // blinkState = !blinkState;
        // digitalWrite(LED_PIN, blinkState);
    }

#endif
}

The solver I'm using is fixed-step discrete solver.
I build the S-function and then the model successfully. When I run the simulation in the external mode using Arduino mega there are jump and glitches in the output raw, pitch and roll angles as shown in the
However, when I plotted the same code through Arduino IDE and monitor data on serial plotter there is no glitches and jumps in angles.
I have also change the baud rate to 115200, solver to auto and sample time of s-function but the problem remain to persist.
Any help would be appreciated!
Thanks in advance!

Measurement sometime lost due to serial communications between Arduino and Simulink. So raw data have some glitches in output values. In order to solve the issue, we have to use state estimation to solve this problem.

Could you please expand on your answer as it does not meet the quality standards for this site. Please see How to write a good answer for Arduino Stack Exchange

To add to the answer above, you are limited by the serial speed of the USB, i.e. USB 2.0 is around 12 Mbps, as well as what your hardware can manage. Also, Simulink uses about 25% of each time step simply for maintaining communication and it is unclear how bandwidth is used by this.
A simple rule of thumb is to work out how much data you are trying to log and at what frequency as this should give you an idea if you are trying to log too much and hence Simulink won't catch all the data and you end up with the blip you have in the scope.
For context, I have been making a wheel speed calculation algorithm and was losing data simply because it wasn't possible to log the volume of data I wanted at high frequency (i.e. 5000 Hz). If you think about logging 3 int8 values at 5000 Hz you are talking 120 kkps, this should give some idea as to how this can get out of control with more signals or larger data types like double.

Yes, this problem exists and may be in even higher data rate. I think the efficient way is to tackle this problem in the Simulink model as I mentioned using state estimation may using Kalman filter in that way we got very reliable results.


text:
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?

Sorry, maybe I don't understand your point but an esp8266 far exceeds that current draw. Would those numbers not confirm my concern?

Sorry, I mis-read.

No problem. If the numbers are correct though, it sort of answers at least a portion of the question.

Absolute maximum current for a pin is 40mA. A transistor/mosfet would be a good solution. Make sure all other pins going to the ESP are set to LOW before turning off the power to the ESP. Voltage on the input pins of the ESP should not exceed its Vcc, which will become 0Volt once you turn off the transistor.

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.

Might need transistors between the Aduino and the ESP8266 to break the Rx/Tx lines. Otherwise they could go higher (due to the USB interface on the Arduino, which is connected to D0/D) then the ESP8266's VCC pin and could damage the diode clamp's on the ESP8266 inputs, or possibly appear to phantom power it.

I will try to find one that suits my needs and try it out. Regarding the tx/rx lines I set them both to LOW and INPUT before cutting the power. Would that be enough or will the above still be an issue?

That is good. That is really all you need to do.

In my case VCC will be 3.3V and since GPIO is also from the same power source it will also be 3.3V. Also, once the circuit is cut off from power, I would like to put the attiny85 in sleep mode and not use any power for a while. If I understand this correctly, a P-channel MOSFET needs power to cut the power, is that correct? With this in mind, is this component still the one I want? Sorry, I might not have explained this very well in my question.

It needs a voltage. No (or miniscule) current though. The gate is like a capacitor. Once charged it doesn't draw anything to speak of - only tiny leakage current too small to measure.

Oh now I understand! Thank you so much. Will digitalWrite(pin, LOW) "pull the gate down"? Guess the only thing to look for now is one that has a volt range within 3.3V and try it out!

Yep, LOW is "on", and "INPUT" or "HIGH" are off.

Would this one be a good choice? I'd rather have one with pins like a "normal" transistor, but it doesn't matter that much. Why are the voltages negative?
http://www.onsemi.com/pub/Collateral/FDN302P-D.PDF

That's pretty good, yes. The voltages are relative to source, and the source is the highest potential in a P fet, so everything is below it.

Just curious, would keeping the p channel mosfet gate high in this circuit even with the resistor draw current (obviously yes, but pretty low) while an n channel would not draw any current at all while the circuit is open and gate pulled low? I’m using batteries in this project so every uA is precious.

No, it won't. The gate is like a capacitor. Once charged nothing more flows.

Perfect! Thank you so much for your help!


text:
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?

You want to use the USB MIDI interface the Leonardo can create? No - the ATMega2560 doesn't have a native USB interface. You want to use some Serial-to-MIDI bridge software, or re-program the ATMega16U2 USB interface chip? Sure, you can use that then.

ok thanks i thought because the atmega has the scl sda connections it would be possible.can the atmega 2560 be used as a midi controller at all?

You want to use some Serial-to-MIDI bridge software, or re-program the ATMega16U2 USB interface chip? Sure, you can use that then.

Mega2560 also has 4 hardware serial ports. Serial() can be left alone for programming via the PC. Serial1, Serial2, Serial3 can all have Serial/USB chips added to talk to MIDI, after all it's just a Atmega16U2 that is programmed as needed.

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.


text:
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 withidentification 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)

this does not appear to be Arduino related .... please clarify, if the Arduino sends out "What Topic is this?" on the serial port, what device is receiving the string and acting on it in the way that you describe?

Updated for clarification the code listed is running on the Arduino which is responsible for giving appropriate commands to the Science child device

the Arduino does not have the capacity to compile code at runtime

I don't think I need to compile code at runtime, I just need to know how to read Serial to determine if I should initialize a Biology or Chem class. Everything should already be compiled.

I'm sorry I'm not making myself clear... My question is "how do I make Factory Class create an instance of  Class A or Class B based on information the Factory Class constructor receives from Serial?"

What have you tried so far to either research the Serial class or to code serial receiving? What baud rate are you using, etc.

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.


text:
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:

When I use digitalOutput the lights are too dim.
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

Is your strip also 1m as described in the article?

@chrisl no, its 5m long

why are you applying -12V to a +12V pin?

@jsotola I'm not, I forgot to rotate the outlet

as you've tagged this question with esp8266 - it may be worth noting, that the PWM range for esp8266 is 0...1023, whereas I believe arduino has a range of 0...255 - so, if your code only uses a range up to 255, you're only using 1/4 of maximum, hence ... DIM :p

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

So wich transistor can I use? The fact that my strip is 5m long changes anything?

What is the total current drawn on each channel of the strip? The TIP31 is not what is making your LEDs dim, it's the resistor value on the base of the transistor which is limiting the current that the transistor will allow. If you use a 150ohm resistor, you will max out your power supply before you max out the transistor.

Sorry, misread your answer. The lowest resistor I have right now is 220ohms, meaning the maximum current I can get will be 750mA, is my math correct? Also, how do I calculate the maximum amperage? If I cut the led strip I will need less amps, right?

Put two 220ohm resistors in parallel to make a 110ohm equivalent.

The maximum drive current for a GPIO on the ESP8266 is only 12mA. So the lowest value you could use is 225 Ohms. Either get a different transistor, or wire two of them in a darlington-pair.

I'm a little confused. The resistor TIP31 will always multiply the inputted amps? What will happen if I use a 220ohm resistor? Could it damage the board? On the given circuit, will the output be ((3,3/225) * 50 * 50) 36A? How can I calculate the output amps?

Schematic in the update is kinda weird. It can't be working for 12V led strip with common anode

@NicosKaralis It's not that easy. The transistor has something called "datasheet" and it says exactly what the maximum C-E current is. Also you have to count with heat dissipation (= current * voltage drop)

@KIIV I’m more lost than when I’ve started. Can I use a 480ohm with a single TIP31C? How can I calculate the maximum current allowed and the optimal current? (Based on amount of leds)

@NicosKaralis Maximum current is fixed (in TIP31 datasheet). The collector-emitter current is roughly Current gain times current between base and emitter. Led strip current is known, it's about 20mA per three LEDs for each color (again you need its datasheet or you can measure it).

@KIIV ok, Maximum Collector Current 3A, I have 300 LEDs (5m strip with 60leds/m) meaning the optimal current is 2A. How do I calculate current gain and the current between base and emitter?


text:
data streaming using Bluetooth + RFduino
I am trying to send ECG data using RFduino. I am using two RFduino modules. The transmitter module is using the device code while the receiver is using the host code. I have common baud rate between the two modules which is 250k. I have an issue with the first data that comes to the receiver . Always a question mark is displayed in the beginning as shown in the figure below:

I do not want this question mark to appear at the beginning because it is making issues in the analysis side.
Codes:
device:
/*
This sketch demonstrates how to send structured data from a Device
to a Host in a Gazell network.

Written by (VLorz) Victor Lorenzo.

You are free to use this code.
*/

#include <RFduinoGZLL.h>
#include "myStruct.h"

/* This instance will be sent over GZLL */
static my_struct_t  theStruct;

/* And this variable is for timing */
static long PrevTime;

/* It would be nice to know if the host received the packet */
static bool   Acked;
static int    AckedCount;

void setup()
{
  // Initialize the structure to a known state;
  //theStruct.OneByte = 1;
  //theStruct.OneDWord = 0x02030405;
  theStruct.ECG = 0x0000;
  //theStruct.Count = 0;
  Serial.begin(250000);
  //pinMode(3, INPUT); // Setup for leads off detection LO +
  //pinMode(2, INPUT); // Setup for leads off detection LO -
  Serial.println("CLEARDATA"); //clears up

  Serial.println("RESETTIMER"); //resets timer to 0
  // start the GZLL stack;
  Serial.print( F("GZLL init...") );
  Serial.println( RFduinoGZLL.begin( DEVICE0 ) );

  Serial.println( F("Running") );

  /* Force the first xmit */
  PrevTime = millis() - 1001;
  Acked = false;
}

void loop()
{
  long  Now;

  Now = millis();

  if (4 <= Now - PrevTime) {
    Acked = false;

    // This is simply for making something change;
    theStruct.Count++;
    theStruct.ECG  = analogRead(2);
    // So we send the struct to the host;
    RFduinoGZLL.sendToHost( (char*)&theStruct, sizeof(theStruct) );

    PrevTime = Now;
  }

  if (Acked) {
    Acked = false;
    //Serial.print( "Ack received for Count = " );
    //Serial.println( AckedCount );
    Serial.println(theStruct.ECG );
  }
}

void RFduinoGZLL_onReceive(device_t device, int rssi, char *data, int len)
{
  // What we expect here is the host sending the value in the Count field from
  // the structure we have sent;
  if (len == 1)
    AckedCount = (uint8_t)*data;
  else
    AckedCount = -1;

  Acked = true;
}

The host:
/*
This sketch demonstrates how to send structured data from a Device
to a Host in a Gazell network.

Written by (VLorz) Victor Lorenzo.
You are free to use this code.
*/

#include <RFduinoGZLL.h>
#include "myStruct.h"

/* This instance will be filled with data received over GZLL */
static my_struct_t  theReceivedStruct;

/* It would be nice to know if the host received the packet */
static bool   DataReady;

void setup()
{
  Serial.flush();
  Serial.begin(250000);

  // start the GZLL stack;
 // Serial.print( F("GZLL init...") );
  Serial.println( RFduinoGZLL.begin( HOST ) );
  //Serial.println( F("Running") );

  DataReady = false;
}

void loop()
{
  if (DataReady) {
    //Serial.println( "Data received!!!" );
    //Serial.print( F("OneWord=") );
    Serial.println( theReceivedStruct.ECG, DEC );
    //Serial.print( F("Count=") );
    //Serial.println( theReceivedStruct.Count );
   // Serial.println( "" );
    DataReady = false;
  }
}

void RFduinoGZLL_onReceive(device_t device, int rssi, char *data, int len)
{
  //
  // IMPORTANT!!! This function runs under interrupt context!!!
  //

  if (DataReady) {
    // Do not overwrite our buffer;
    return;
  }

  if (len != sizeof(theReceivedStruct)) {
    // Ignore packets with wrong length!!!
    return;
  }

  // Copy the data to our structure buffer;
  for (char* lpDest = (char*)&theReceivedStruct; len > 0; len--) {
    *lpDest = *data;
    lpDest++;
    data++;
  }

  // ...and signal the application the data is ready
  DataReady = true;

  RFduinoGZLL.sendToDevice( device, theReceivedStruct.Count );
}

Can you include the output with all of the debugging un-commented on the host?

@Craig  what do you mean .?  To remove the comments of serial commands  in the setup() or loop ??

Yes. uncomment the Serial.print and Serial.println lines in both setup() and loop().  That extra output will be useful in debugging the problem.


text:
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.

Lean C syntax. Code goes in functions!

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);
}

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;
}


text:
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

Learn the syntax of a properly constructed MIDI file and write the Arduino sketch to create the file on an SDCard.  This may be easier said than done as I suspect an artist seldom plays a musical phrase the exact same way twice.

@st2000 Why would it matter if they play it differently another time? Record what they actually played. What they might play another time is irrelevant.

Which Arduino do you have in mind? There are quite a few these days.

You are correct @MarkSmith.  WRT MIDI recordings, I always want to commit the recording to sheet music.  As such, I'm constantly thinking in terms of "what is a quarter note". Similar to your auto's GPS snapping you to the nearest road despite your actual location.  If that is not needed here - they you are correct - just record what is played and play it back.

Updated the question with specifications.

I just want to record whatever is being played.

@st2000 I tried to learn the syntax by downloading a MIDI file from online, and reading them with a text editor. The text wasn't even letters so I just gave up on that.

If anyone has done it before, I guess I can take the time to read about MIDI syntax. If the music is simple, is it possible to do it with no encoded characters?

I did it before, and it is not complicated at all. Only thing that took me some time to understand is the way how the "time" is encoded in midi files. Take a look here, someone was building simple midi file from scratch in hex editor

If you don't have a SD card interface then I hope you are using level shifters for the data lines. Like this: http://www.gammon.com.au/images/Arduino/Micro_SD_breakout.png The chip on the right does the level shifting.

@NickGammon What exactly does level shifting do? I am using SPI interface for communication, and resistors in voltage regulators to drop it to 3.3V. I basically made it from this: https://nathan.chantrell.net/20111128/diy-micro-sd-shield-for-arduino/

Level shifting is catering for (say) running a 3.3V device from a 5V device. Your resistors, acting as voltage dividers, will reduce the 5V down to 3.3V. That device is relying upon the Arduino recognising 3.3V as HIGH which is slightly an edge case (the minimum for HIGH is 3V if you are running at 5V). A proper level shifter actually shifts 3.3V up to 5V, and 5V down to 3.3V depending on which way the signal is travelling. You can buy them fairly cheaply, or make them: http://www.hobbytronics.co.uk/mosfet-voltage-level-converter

Thank you for the explanation, I will look into this as well, although what I have seems sufficient for the time being.

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:

https://en.wikipedia.org/wiki/Pitch_wheel
http://sites.uci.edu/camp2014/2014/04/30/managing-midi-pitchbend-messages/

My project doesn't actually have anything connected to a MIDI port; its just reading from/writing to files.

Although what you've done is really cool

Ah, OK. So my answer doesn't really address your question. I got the idea into my head that your device outputs MIDI codes and you wanted to turn them into a disk file.

I've updated my answer to give a lot more detail about how you might do it.

I've updated my answer to give an example of a complete sketch that does this.

Wow. I would've never expected such an elaborate answer. Give me a few days to understand it all. I have limited experience of all this but I will try to see if I can understand it!

Ok so I think I understand how the MIDI syntax works. On a theremin the note would always be on so that byte would always by 0x90, right?

I'm reading about the pitch bending and also trying to figure out how to convert a frequency value to a note + pitchbend... also where would I write the pitchbend byte - after the note number byte?

No, they are two different commands. 0x90 is "note on". There would be no point in sending lots of "note on" unless they were for different notes. And the pitchbend is a separate command. If the pitchbend range was big enough you could just do a single "note on" and then just bend it up or down as your hand moved, but the range might be too small for that. It might just bend up from C to D. I think you might have to experiment with that. Are you planning to play this on another MIDI device, or just play it back on your own theramin?

The ultrasonic sensors aren't very good so the note is constantly fluctuating even if the hand controlling it is not moving. I still want it to be recording those anyway, so why isn't sending lots of "note on"s appropriate? The refresh rate on the ultrasonic sensors are pretty fast, I would guess around 15ms per note.

On the second link you gave me, it says: "The amount of alteration in pitch caused by the pitchbend value is determined by the receiving device". So I guess I will have to experiment to see how much one pitchbend value changes the frequency by, but it probably wont be able to go a few octaves, which was what I was hoping for.

If the pitch bend value translates to different frequency changes based on what type of receiver is playing, then that defeats the purpose of using MIDI to record and playback. I think I might just use some type of custom file format, as it won't be compatible with other instruments anyway...

Yes, well for recording and playing back on your own device, a custom file format would be much simpler. You could basically just record the raw data from the sensors (and a time difference). Then when they go to play it back, make the code think this raw data has just been received and it should reproduce it perfectly.

This answer is pure gold. I just built a pass-through MIDI recorder that sits between a device with midi-out (e.g. a novation launchkey) and device with midi-in (e.g., an ASIO audio interface) so that even if you're not running something that comes with "always-on recording" like FL Studio or Ableton, you won't lose that sweet riff you were noodling on an hour ago. To keep it simple I was writing the data as CSV file rather than as .mid, but thanks to your answer that changes today.

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)


text:
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?

What do you mean by the 20 MHz version exactly? Are you suggesting that the Attiny85 comes in different speed grades? Where is the documentation supporting that?

Digikey has no in-stock 8MHz flavored devices - can you provide links to these devices that supposedly come in different speeds?

Here's the list I had narrowed down to: https://www.digikey.com/products/en/integrated-circuits-ics/embedded-microcontrollers/685?k=attiny85&k=&pkeyword=attiny85&pv16=7409&FV=1f140000%2Cffe002ad&quantity=0&ColumnSort=1000008&page=1&stock=1&pageSize=500 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 is, is it expecting a specific clock speed that these aren't set to out of the box?

See my amended answer.

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.

I believe your theory to be correct as the ones with a higher MHz rating appear to be more expensive. Thanks!


text:
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:

Can the ESP8266 module count impulses during one of the sleep modes?
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)
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

This are multiple questions in one. But I will do my best to tackle them one by one.

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

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.

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.

Thank you for this elaborate answer. I was diving deep into the battery topic and I agree with your last statement using solar power. This is a good tutorial [link]https://www.youtube.com/watch?v=SPpgMl_TeIc. The only thing I will add is the AMS1117 to get back to 3.3V after boosting to 5V (not nice but 4.8V is min for AMS). Regarding the sleep mode, what about sending the ESP to soft-sleep letting it being waken up every time I receive an impuls, incrementing that to the counter and saving the new value by overwriting the old one in a non-volatile memory space and going back to sleep?

@Slev1n Yes, you could go into deep sleep and store it in RTC ram (NV-RAM). That will conserve it. But you will reset the chip, when you wake it. so you need a system that keeps track of what it is suppose to do. Or it will always do the same. It will better work to make a program that will send a package to the router then go back into deep sleep. The downside is that the ESP takes time to wake from deep-sleep. Light-sleep is much better for this workload. Again, this comment is getting too long, here is some info on how to implement it (https://www.youtube.com/watch?v=6SdyImetbp8)

Thank you for the link. For now I will try the solar panel approach as a prototyp but I learned a lot. Later I will switch to a complete low power Module from TI http://www.ti.com/tool/TIDA-00489 i just found.


text:
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 ..."));
      }

I can't quite follow this. The much obvious way to make this use a constant phone number this would be to load your number string into the char number[30]; variable and skip the entire readline process. You could also simple substitute char* number = "01234567..";. Is that what you want?

@MaximilianGerhardt
That's the problem. I can't just put in a number, it fails calling. As I wrote, I am not that familiar with Arduino but I think it wants the numbers as an array or something (that's why I gave you the readline function). I have tried a various ways to put in the number directly to the call function but none of the times did it go well.

All readline does is fill the number buffer with the data coming over serial while ignoring newlines. If you input some number "1234" over serial then it is equivalent to just putting char* number = "1234";. Are you absolutely sure that if you input the number over serial using readline it works, but putting the same number directly in the number variable doesn't? Can you show the code with which you tried that?

@MaximilianGerhardt
This is what I have tried. If it is a number it doesn't even recognize the number. When it is a string like here it inputs the number correctly but somehow it fails calling (I have done exactly as I did when it worked regarding the way I call the call function)

When calling through the shield, it prints in the serial (the library does). I can see the number it is trying to call which is only correct when I put in the numbers as a string. But the next serial print is the one I have defined to tell if there is an error: "Failed calling".

I see no logical reason why this should not work. Please post the entire code which is trying to call a hard-coded number and also the serial monitor output. If ARDUINO_FONA_DEBUG is defined in your library (here), you should see at least some more debug messages on what it's trying to do. What is the serial debug output compared to when you input it over Serial with the first version?

@MaximilianGerhardt, thank you so much for the help. I was confused about the string, numbers, buffers and so on which were the course for it to fail. It works now. Please leave an answer for closing this question

i think it's best if you write the answer yourself because I'm not sure what exactly you changed in the code so that it suddenly runs.

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.

Of course. I can't mark my own as correct before 22 hours have passed ..


text:
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

esp-link has some mqtt support

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.

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.