text:
MPU6050 does not give output
I need help getting my MPU 6050 to actually give me data. As of right now, my program is only reading 0s from the gyroscope and when I move it, the values all go to -1 and the program just stops until I close and reopen the serial monitor. I know this question has been asked multiple times before, but I've already looked at each of those questions and tried all of the fixes listed there, but not a single one has worked. The I2C scanner does find the sensor at 0x68, but that's only thing that works. These are all brand new boards that I got a couple days ago.
I've tried every library and every example sketch I could find. I've switched to 2 new boards. I've even tried looking at the datasheet for the MPU 6050 and reading/writing the registers directly and still I'm getting no results. The serial monitor either stays blank, shows only 0s or -1s, or just gives me garbage values that change randomly. Please help me.
I've wired the sensor like this (I'm currently on an Arduino Uno):
VCC ==> 5V
GND ==> GND
SCL ==> A5
SDA ==> A4
AD0 ==> digital 13 (set to LOW)
And the code I'm using is this:
#include <Wire.h>

const int addressPin = 13;

int gyroX, gyroY, gyroZ;

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

  //designating pins as I/O
  pinMode(addressPin, OUTPUT);

  //setting IMU address to 0x68 (LOW)
  digitalWrite(addressPin, LOW);

  initializeSensor();
}

void loop() {
  readGyro();

  Serial.print(gyroX);
  Serial.print("    ");
  Serial.print(gyroY);
  Serial.print("    ");
  Serial.println(gyroZ);
}

void initializeSensor() {
  //performing full device reset, disables temperature sensor, disables SLEEP mode
  Wire.beginTransmission(0x68);

  Wire.write(0x6B);
  Wire.write(0b10001000);

  Wire.endTransmission();

  //writing to gyro config register
  Wire.beginTransmission(0x68);

  Wire.write(0x1B);
  Wire.write(0b00001000);

  Wire.endTransmission();
}

void readGyro() {
  //requesting data from gyro data registers
  Wire.beginTransmission(0x68);

  Wire.write(0x43);

  Wire.endTransmission();

  Wire.requestFrom(0x68, 6);

  gyroX = Wire.read()<<8|Wire.read();
  gyroY = Wire.read()<<8|Wire.read();
  gyroZ = Wire.read()<<8|Wire.read();
}

P.S. I few weeks ago I posted a question about I2C devices and in it, I said I had managed to successfully read data from the sensor, but I found out later those were garbage numbers. :(

It would be good to link to the questions on which you tried all solutions so people know exactly what not to repeat.  If you can, inspect the signals with a scope.  One potential difference between the I2C scanner and libraries is the requested clock rate.

From the MPU-6000/MPU-6050 Register Map and Descriptions:

Section 4.28, Register 107 – Power Management 1 PWR_MGMT_1, pages 40 to 41:

Note:
When using SPI interface, user should use DEVICE_RESET (register 107) as well as SIGNAL_PATH_RESET (register 104) to ensure the reset is performed properly. The sequence used should be:

Set DEVICE_RESET = 1 (register PWR_MGMT_1)
Wait 100ms
Set GYRO_RESET = ACCEL_RESET = TEMP_RESET = 1 (register SIGNAL_PATH_RESET)
Wait 100ms

Section 4.26, Register 104 – Signal Path Reset SIGNAL_PATH_RESET, page 37:

Note: This register does not clear the sensor registers. The reset initializes the serial interface as well.

Section 3, Register Map, page 8:

The reset value is 0x00 for all registers other than the registers below.

Register 107: 0x40.
Register 117: 0x68.

This means that the PWR_MGMT_1 register defaults to sleep mode after a reset so it needs to be rewritten to disable sleep mode after commanding a reset.
void initializeSensor()
{
  //
  // Perfrom full reset as per MPU-6000/MPU-6050 Register Map and Descriptions, Section 4.28, pages 40 to 41.
  //

  // performing full device reset, disables temperature sensor, disables SLEEP mode
  Wire.beginTransmission(0x68);  // Device address.
  Wire.write(0x6B);              // PWR_MGMT_1 register.
  Wire.write(0b10001000);        // DEVICE_RESET, TEMP_DIS.
  Wire.endTransmission();
  delay(100);                    // Wait for reset to complete.

  Wire.beginTransmission(0x68);  // Device address.
  Wire.write(0x68);              // SIGNAL_PATH_RESET register.
  Wire.write(0b00000111);        // GYRO_RESET, ACCEL_RESET, TEMP_RESET.
  Wire.endTransmission();
  delay(100);                    // Wait for reset to complete.

  // Disable SLEEP mode because the reset re-enables it. Section 3, PWR_MGMT_1 register, page 8.
  Wire.beginTransmission(IMUAddress);   // Device address.
  Wire.write(0x6B);                     // PWR_MGMT_1 register.
  Wire.write(0b00001000);               // SLEEP = 0, TEMP_DIS = 1.
  Wire.endTransmission();
}

In the following code I've:

Modified readGyro() to implement 3 states (Request, Wait, and Read) and return true when 6 bytes have been read from the MPU-6050.

Added Blink Without Delay to loop() to see whether the MCU freezes which requires changing the ADO pin from pin 13 (the built-in led) to another pin, i.e. pin 12.

Added several Serial.print() statements for debugging to see where things go wrong.

Tweaked the code in response to comments.

#include <Wire.h>

const byte IMUAddress = 0x68;   // Added for readability and maintainability.
const byte addressPin = 12;     // Changed from 13 to 12 because 13 is built-in LED.

int gyroX, gyroY, gyroZ;

void setup()
{
  Wire.begin();
  Serial.begin(115200);
  Serial.println(F("\n\nMPU-6050 Test\n"));

  // Designating pins as I/O.
  pinMode(addressPin, OUTPUT);
  pinMode(LED_BUILTIN, OUTPUT);  // Added LED for heartbeat signal.

  // Setting IMU address to 0x68 (LOW).
  digitalWrite(addressPin, IMUAddress & 1);  // Added bit mask of bit 0.

  initializeSensor();
}

void loop()
{
  //
  // TASK 1: Blink without delay to indicate that MCU hasn't frozen.
  //
  const unsigned int INTERVAL = 250;
  unsigned long current_timestamp = millis();
  static unsigned long previous_timestamp = current_timestamp;
  static bool led_state = false;
  if (current_timestamp - previous_timestamp >= INTERVAL)
  {
    led_state = !led_state;
    digitalWrite(LED_BUILTIN, led_state);
    previous_timestamp += INTERVAL;
  }

  //
  // TASK 2: Read gyro.
  //
  if (readGyro())
  {
    Serial.print(gyroX);
    Serial.print(F("    "));
    Serial.print(gyroY);
    Serial.print(F("    "));
    Serial.println(gyroZ);
  }
}

void initializeSensor()
{
  //
  // Perform full reset as per MPU-6000/MPU-6050 Register Map and Descriptions, Section 4.28, pages 40 to 41.
  //

  Serial.print(F("Performing full reset of MPU-6050..."));

  Wire.beginTransmission(IMUAddress);   // Device address.
  Wire.write(0x6B);                     // PWR_MGMT_1 register.
  Wire.write(0b10001000);               // DEVICE_RESET, TEMP_DIS.
  Wire.endTransmission();
  delay(100);                           // Wait for reset to complete.

  Wire.beginTransmission(IMUAddress);   // Device address.
  Wire.write(0x68);                     // SIGNAL_PATH_RESET register.
  Wire.write(0b00000111);               // GYRO_RESET, ACCEL_RESET, TEMP_RESET.
  Wire.endTransmission();
  delay(100);                           // Wait for reset to complete.

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

  // Disable SLEEP mode because the reset re-enables it. Section 3, PWR_MGMT_1 register, page 8.
  Serial.print(F("Disabling sleep mode of MPU-6050..."));
  Wire.beginTransmission(IMUAddress);   // Device address.
  Wire.write(0x6B);                     // PWR_MGMT_1 register.
  Wire.write(0b00001000);               // SLEEP = 0, TEMP_DIS = 1.
  Wire.endTransmission();
  Serial.println(F(" Done."));

  //
  // Writing to gyro config register.
  //
  Serial.print(F("Configuring gyro of MPU-6050..."));
  Wire.beginTransmission(IMUAddress);   // Device address.
  Wire.write(0x1B);                     // GYRO_CONFIG register.
  Wire.write(0b00001000);               // +/-500 deg/s.
  Wire.endTransmission();
  Serial.println(F(" Done."));
}

typedef enum State
{
  Request,
  Wait,
  Read
};

bool readGyro()
{
  static State state = State::Request;

  switch (state)
  {
    case State::Request:
      // Request data from gyro data registers.
      Serial.print(F("Requesting data from gyro..."));
      Wire.beginTransmission(IMUAddress);   // Device address.
      Wire.write(0x43);                     // GYRO_XOUT_H register.
      Wire.endTransmission(false);          // Restart connection, i.e. keep alive.
      Wire.requestFrom(IMUAddress, 6);      // GYRO_XOUT_H, GYRO_XOUT_L, GYRO_YOUT_H, GYRO_YOUT_L, GYRO_ZOUT_H, GYRO_ZOUT_L.
      Serial.println(F(" Done."));
      state = State::Wait;
      Serial.print(F("Waiting for data from gyro..."));
      break;

    case State::Wait:
      // Wait for data to arrive into buffer.
      if(Wire.available() < 6)
      {
        //Serial.print(F("."));
        Serial.print(F(" "));
        Serial.print(Wire.available());  // Added to show bytes received.
      }
      else
      {
        Serial.print(F(" "));
        Serial.print(Wire.available());  // Added to show bytes received.
        Serial.println(F(" Done."));
        state = State::Read;
      }
      break;

    case State::Read:
      // Read data from gyro registers.
      Serial.print(F("Reading gyro data..."));
      gyroX = Wire.read() << 8 | Wire.read();
      gyroY = Wire.read() << 8 | Wire.read();
      gyroZ = Wire.read() << 8 | Wire.read();
      Serial.println(F(" Done."));
      state = State::Request;
      return true;  // Indicate data was received.
      break;
  }

  return false;  // Indicate no data received yet.
}

Update based upon RowanP's answer
While concentrating on the software issues I missed a crucial piece of information from the other datasheet (MPU-6000/MPU-6050 Product Specification), i.e. the electrical characteristics in Sections 6.3 and 6.4 on pages 14 and 15 showing a Vdd range of 2.375 V to 3.46 V:

6.4 Electrical Specifications, Continued

This will require level shifters  on the signals between the 3.3 V MPU-6050 and the 5 V Arduino.

Thanks for the help! I've looked through the checklist that RowanP gave me and fixed anything that I thought might have been wrong, including switching to the 3.3V pin for power on the Uno. I've also used your code and it appears to still only give 0s, but when I rotate the sensor about the y-axis the code gets stuck in the State :: Wait case and only prints periods (but the heartbeat light doesn't stop). Do you have any idea why?

@TobiasGuo, as others have said, the chip could be damaged by a 5 V supply. While 5 V is within the absolute maximum rating of 6 V, it's outside the recommended operating voltage. Do you have level shifters on SCL, SDA and ADO? Try replacing the period print with Serial.println(Wire.available()); to see how many bytes it manages to read.

@TobiasGuo, you could also print and test the return value of each Wire.endTransmission().

@TobiasGuo, did you get it working? I noticed from your question about accelerometer values that you changed the code, i.e. disabled the SLEEP mode without performing a reset because the reset re-enables SLEEP mode (Section 3, PWR_MGMT_1 register, page 8), and used keep-alive with Wire.endTransmission(false) before requesting data.

I haven't tried it yet. I was working on finding some level shifters to attach to the other pins on the MPU so I haven't been able to test the code yet. I will reply with another comment once I have and let you know how things are going! Thanks again for the help!

@TobiasGuo, here is a simple bi-directional level shifter. Click switches.

Thanks! That seems to have fixed the problem! I also switched to using the I2Cdev library and that helped streamline the process of communicating with the sensors, but now my MPUs are actually giving me the correct output!

A while ago while figuring out I2C difficulties of my own I did some research and listed out all the failure modes and test techniques I could think of regarding I2C. See I2C protocol doesn't work properly. I routinely go through the list now to tick off the things I need to check to get a new I2C connection working, usually it's something simple (fingers crossed). Do you have access to an oscilloscpe?
(Edit) This old post seems to describe a similar problem (only getting zeros) MPU6050 doesn't work. The consensus there was that the 3.3V MPU6050 had been connected to a 5V UNO, frying the MPU6050 chip. That sounds very like your situation.

Thanks for linking that checklist. I will run through that to see if I have missed anything or if there is anything else I can do to fix it. I was under the impression that the VCC pin on the MPU 6050 was designed to be able to handle a 5V power supply, but maybe I was wrong. I will definitely try switching to a 3.3V power supply!

What module are you using?  I'm using the DFRobots 6DOF module (https://wiki.dfrobot.com/6_DOF_Sensor-MPU6050__SKU_SEN0142_) and it works fine with a 5V supply.  You might also try taking a look at this (https://www.fpaynter.com/2019/10/basic-arduino-mpu6050-gy-521-test/) and related articles about the MP6050 on my website (fpaynter.com)

I went back and checked my most recent use of an MPU6050 module, and notwithstanding the link I posted in my answer, I agree with @user3765883, the modules I've had are 5V tolerant as well. I don't have a schematic, but looking at the module closely there is a power regulator onboard marked 4A20. Depending on the specific module you're using I think the previous link about the MPU6050 chip being 3.3 V may be a red herring!

OK, so there is evidence of at least two different types of modules in circulation. One with a 5 to 3.3 V power regulator and one without. See https://forum.arduino.cc/t/mpu6050-eagle-files-out-of-date/633197

I used 5 V from my Arduino to power the MPU6050, and it was fine. Check out: https://www.instructables.com/How-to-Make-a-Robot-Car-Drive-Straight-and-Turn-Ex/, which has very similar code.
Also, I typically avoid pin 13, since it performs some special additional function, unlike pin 2 to 12.


text:
How to use Serial.setTimeout()
I am just playing with the UART interface of my board to learn about how it works. Since I have only one board, I send data out just to receive them by my own board, which is working so far.
Now I wanted to find out what Serial.setTimeout() is for. As per description on the Arduino homepage, it sets the maximum time for to wait for data. The description says, upon others Serial.find() will use it.
So I set Serial.setTimeout() to 100ms, and between sending and trying to receive data, I put a delay of 500ms. Therefore my expectation would be, Serial.find() will not detect a message, since there is more than 100ms no traffic on the bus. But I am still recieving data, it seems that the Serial.setTimeout() has no effect.
What is wrong in my understanding/usage of Serial.setTimeout()?
Here is my example sketch:
#include <M5Stack.h> // needed for my board M5Stack

HardwareSerial Serial2(2); // R2: Recieve Serial2, 17: Transmit Serial2  --> connnect pin R2 and 17

unsigned char buf_recive[1];
unsigned char buf_transmit[2] = {0x42, 0x00};

void setup()
{
  M5.begin();
  Serial.begin(9600);    // setting baud rate for COM3
  Serial2.begin(9600);   // setting baud rate for M5Stack2M5Stack communication
  Serial2.setTimeout(100);    //set the Timeout to 100ms
}

void loop()
{
  delay(500);
  // send buf_transmit
  Serial2.write(buf_transmit, 2);
  delay(500);
  // detect first byte of recieve message
  if (Serial2.find(0x42))
  { //start to read when detect 0x42
    Serial2.readBytes(buf_recive, 1);
    Serial.println(buf_recive[0]);
  }
  buf_transmit[1] = buf_transmit[1] + 0x01; // just to see that something's going on
}

And here some prove, that I am still receiving data:

The bytes are received to rx buffer with interrupt in the core. The find() function finds them there after the 500 millis delay. Timeout is to wait for the next byte if the rx buffer is empty.
The timeout is good if you know that the other side sends a collection of characters or bytes. Like for example a line sent from Serial Monitor or a Http request on networking client. The transmition has small gaps between bytes, but you want to receive it at once. So a function waiting a little for the next byte is useful.
Serial, networking Client classes and other Arduino stream classes inherit reading functions from the Stream class. This class has all the read and parse functions. There are 3 non blocking functions available, read and peek. All other read and parse functions use the timeout and wait for the next byte if the rx buffer is empty.
try this sketch with Serial Monitor
void setup() {
  Serial.begin(115200);
  Serial.setTimeout(10000);
}

void loop() {
  if (Serial.available()) {
    String s = Serial.readString();
    s.trim();
    Serial.println(s);
  }
}

send a line from Serial Monitor. a couple of characters. then send fast another line and then wait longer then 10 secs and send one more.

I tried this by changing Serial2.write(buf_transmit, 2); to Serial2.write(buf_transmit[0]); delay(200);    Serial2.write(buf_transmit[1]);, which should simulate the gap between the bytes, but I am still receiving, obviously I have still not understood. Do you have a hint what I am doing wrong?

gap yes, but you read the rx buffer after both writes were received to rx buffer. you can't simulate it with one MCU

you can test it with Serial Monitor.

ok, doing it on one device seems stupid. Any idea how I could set a timeout on the Serial Monitor?

I added a test to answer

Thanks, that test helped a lot in understanding. Now I also got why it is not working with one MCO.

source: Stack Exchange

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

sort: votes


text:
make servo motor to increase/decrease degree
I'm trying to make servo motor to increase or decrease degrees according to user choice.
I've created an code that get input from the user via Serial and according to the input the motor increase or decrease.
But for some reason, when I call each of one of the function the motor start working without a break.
do I miss something over here?
 #include <Servo.h>

Servo servo1;
int currentAngle = 0;
String readString;
void setup()
{
   servo1.attach(8);
   Serial.begin(9600);
}
void increaseServo(){
  Serial.println('+');
  currentAngle += 5;
  servo1.write(currentAngle);
  delay(15);
}
void decreaseServo(){
  Serial.println('-');
  currentAngle -= 5;
  servo1.write(currentAngle);
  delay(15);
}
void loop()
{
  while(Serial.available()>0) //Allocating the data from Serial Monitor.
  {
    delay(3);
    char c = Serial.read();
    readString += c;
  }
  readString.trim();
  if (readString.length() > 0) {
    if(readString == "+"){ //increase
      increaseServo();
    }else if(readString == "-"){ //decrease
      decreaseServo();
    }
    readString="";
  }
  delay(1000);
}

Thanks for the help.

"But for some reason, when I call each of one of the function the motor start working without a break" - I don't quite understand, what exactly that means. Do you mean, that the motor will continuously move, as soon, as you send either + or - from the Serial Monitor?

Yes, Exactly the servo continue to move without stop

Which servo are you using? Common RC servos cannot run without stop, because they have a range of just about -90° to +90°.

@the_busy bee I am using FT90R

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


text:
Output voltage range between 0-5v
I am using arduino Uno/Mega.
I am trying to output a range of 0-5v volts using PWM.
Is it possible to do it?
It’s would be nice to see some code or instructions, as far I have seen, they used external Module to get that voltage range, maybe I am wrong or I didn’t understand them well.
Thanks!

If you want a steady stable voltage at that level then no it isn't possible without external circuitry.  If you just want PWM that averages at that level then check out the doc page for analogWrite on the arduino.cc website.  It's basic stuff.  Definitely not secret or hard to find.

just send it through a 2-stage low pass RC filter, then send the output to a unity gain opamp buffer, then send that through a series-pass voltage follower transistor if needed.

Short answer: No.
Arduino Unos and Megas have PWM (Pulse Width Modulation) output, which rapidly turn the output on and off with a varying "duty cycle" (The ratio of on time to off time.) That is not the same thing as an analog output voltage.
If you have a constant load you can build a low pass filter that will smooth the output to a slightly dirty DC output based on the PWM output.
You're better off using an external DAC (Digital to Analog Converter.) You send that a digital value and it converts it to a clean, filtered analog output. Most modern DACs are fast enough to output complex waveforms like music.
Edit:
The Arduino zero apparently has a built-in DAC with up to 10-bit resolution. you could use that to output a low current DC voltage. However the zero is a 3.3V device.

The Arduino is a digital device; each output pin is either HIGH (+5v) or LOW (0v = GND), not in between.
For certain types of devices (motors, LEDs) there is a technique you mentioned called PWM, pulse width modulation, which turns the output on and off rapidly. It's still just a square wave alternating between 0 and 5v but it's doing it really fast. So for an LED for example, your eye will make you think it's at half-brightness even though it is flashing on and off very quickly.
To do this you need to use a pin that has "analog" ability and use the "analogWrite" command.


text:
store multiple of float type on EEPROM
I have 7 float variables.
float temperature, differential, calibration,hta,lta,hha,lha;
I want to store them all on the EEPROM memory, how do I calculate the addresses given that there type is float.
Thanks!

create a struct and store the struct
#include <EEPROM.h>

const int DATA_ADDR = 0;

struct MyData {
  float temperature, differential, calibration,hta,lta,hha,lha;
};

MyData data;

void setup() {
  data.temperature = 1.2;

  EEPROM.put(DATA_ADDR, data);

  EEPROM.get(DATA_ADDR, data);
}

void loop() {

}

With the sizeof function:
int nrOfBytesOfTemperature = sizeof(temperature);

You can also use directly a type:
int nrOfBytesOfFloat = sizeof(float);


text:
read state from button to check if clicked
I"m kinda new here and new to the arduino framework.
I want to build a "menu" using LCD 20*4, so I want to detect "button clicked" event.
I've connected button to pin 8 and to ground, like this(please ignore the other wiring):

int leftButton = 8;

void setup() {
  pinMode(leftButton, INPUT);
  digitalWrite(leftButton, HIGH);
  Serial.begin(9600);

}
bool leftButtonClicked(){
  return digitalRead(leftButton);
}
void loop(){
  delay(20);
  Serial.println(digitalRead(leftButton));
}

I am receiveing on the serial 1 while the button is not clicked, and when its clicked I receive 0.
What is the problem? Thank you guys.

That's normal to wire a button so that it connects to ground when pressed.  That way you can use INPUT_PULLUP in your pinMode and you don't need any pull-up resistor.  So in normal cases your code will read a pressed button as 0 if you wired it the normal way.

Why do you think that this is a problem?

@Delta_G
so according to your saying, 1 mean unclicked, and 0 mean clicked.
is this the acceptable way for doing this?
there is an preffer method to isolate the clicked event?

According to my saying it depends on how you wire the button, but most people prefer to wire it so that 0 is pressed and 1 is unpressed.  You can wire it so that 1 is pressed, but that requires an extra resistor.

Also you need to change your pinMode to INPUT_PULLUP instead of just INPUT or you will start seeing random phantom button presses as the floating input picks up noise from the environment.

@Delta_G, yes I've updated the code.
there is an preffer method to isolate the clicked event?

What do you mean by "isolate the click event".  You test like you did with an if statement.  If the digitalRead returns false then the button was pressed and you do whatever it is that you want to do for that.  Arduino isn't really an event driven system.  You're writing code at a little more base level than that.

@Delta_G yes, I'm usally program on JS and etc, so its really weird for me the way of thinking in that programing way.

As you are a beginner, you seem to have some misconceptions:

Reading button state with digitalRead(): You thought something is wrong, because you thought that digitalRead() returns, if the button was pressed (thus 1 would mean pressed). But that is not directly the case. digitalRead() returns the electrical state of the corresponding pin (if the pin voltage is at ground level (0) or Vcc (supply voltage) level) (1)). This corresponds with the button depending on your wiring. I guess you copied the wiring somewhere in the internet. It shows the most common way of connecting a button. The button consists only of two contacts, which get pressed together, when you press the button. So the button can connect the pin to either ground or Vcc, but not to both. When the button is not pressed, the pin is connected to nothing, thus it is floating and the value changes erratically. This is solved with a pullup or pulldown resistor (a rather big resistor from the pin to either Vcc or ground), which sets the value of the pin, when the button is not pressed. That means, that you need 1 resistor for each button, that you want to use. The good news is: The Arduino already has internal pullup resistors, that you can activate via pinMode(pin, INPUT_PULLUP). That way you can save 1 extra component. Since it is a pullup resistor, which connects the pin with Vcc, you need to connect the button with ground.
That also gives you the inverted logic. In the end it is determined by you, what the digitalRead() value means. Think electrically about it.
Events: In Arduino programming there are not events. You are programming very much directly the hardware. There is no OS or GUI system, that would handle events for you. The program, that you write, runs command after command with a specific speed (determined by the Arduinos clock frequency; 16MHz for the Uno), pretty much linearly. Though there is one exception for that: interrupts. Microcontrollers have some peripherals build into them (ADC, communication interfaces, Timers, ...) and many of them work parallel to the main program (since their function does not need code, but is implemented in hardware). These peripherals can generate interrupts (for example to service the peripheral), which pauses the normal run of the program, runs an ISR (Interrupt Service Routine) and then returns to the main program. That is somewhat like an event, but very hardware specific and not nearly as generically usable as events on a PC.
Reading a button click: In your code you don't read the "button click", but only the state of the button. Thus you get multiple times 0 for one long enough button press. For the real click action you need to look for the transition from 1 to 0, which ideally only happens one time per button press. I write "ideally", because real life buttons bounce. In the moment of contact the value changes rapidly multiple times, until the button contacts have settled. So you need to debounce the button. You have already done basic debouncing by using delay(20) (because the button may need about that time to stabilize). You can see more sophisticated debouncing in the Bounce2 library, which is also easy to use for reading button clicks and presses.


text:
Wireless Bluetooth USB HUB using Arduino nano
I have the following problem/idea:
I have a electronics workbench and a separate PC desk. Now I have a USB HUB on the workbench, but it doesn't properly work, because the USB-cable to the pc is too long. My setup doesnt really allow me to put the PC somewhere else and the USB-hub is already mounted in the closest usable location.
A few days ago I remembered that I have a arduino nano with a hc-05 bluetooth module attached to its hardware serial port. And as both bluetooth and USB are serial connections I was wondering if I couldn't use the arduino sort of as a middle man and connect the arduino via bluetooth to the pc. Then have a software on the pc that registers the arduino as a USB hub with one port and run some code on the arduino that basically makes the arduino act as a USB host (I know that this is possible with the arduino nano) and have it just move data between the USB connection and the bluetooth module.
Im quite sure that all this should be possible. The atmega should even be capable of doing so at or close to maximum USB 2.0 data rates as that is only 12 Mbit/s and it can run at 16 MHz when powered with 5V. Im not quite sure about the maximum data rate for the bluetooth module though, but I can work with a little lower speeds...
The software for the pc could also be relatively straight forward. Something like a virtual USB-port and the software just shifting data from the com-port that is the bluetooth to this virtual USB-port.
So thats the idea. I have some experience in both programming microcontrollers and software for pc.
So what I need is a bit of help with this, as I am not quite sure how to accomplish this.
The parts that I will need the most help with are going to be the programming of the USB host on the arduino and the virtual USB-port on the pc.
The rest should be relatively easy as its basically just shifting data from one register into another.

as both bluetooth and USB are serial connections well, yes, they are both serial, but saying they are anything even remotely alike is like saying that an elephant and a bicycle are similar because they both move forwards and backwards.

You can't. As simple as that. The mere act of thinking about it belies a desperate lack of understanding about how USB works.
Yes, it's "serial" in that it sends one bit after another, as opposed to multiple bits all together ("parallel"), but it is completely unrelated in any way to the "serial" that the bluetooth module or the Arduino speak ("UART").

I agree with Majenko. The best way for you is to buy an active USB extension cable, so that you can handle the distance easily (the signal gets refreshed in the cable by active electronics, so that you can use USB over longer distances).
You consider this to be easy, because you haven't dug into the depth of these topics yet. Here are some important information on that:

Bluetooth and USB are fundamentally different. The term "serial" outside of the Arduino world is just a term for one bit after another. It doesn't describe any protocol or working principle. Interfaces as SPI and I2C are also serial interfaces, but that doesn't mean, that they work similarly, not even in their topology and also not in their protocol behavior. A bridge between these different interfaces is better described as a translator. And translation is always difficult.
Serial in the Arduino world means the UART interface. No similarity to USB or bluetooth.
The Bluetooth spec is rather big. There are many types of connection interfaces, that can be build with it. Examples are the UART (Arduino Serial), HID (like a mouse or keyboard on a PC) or audio (like headphones) interfaces. Each connection has it's specific function. The USB spec is even bigger, way bigger to be precise. You would need to understand how bluetooth and USB work at their core for implementing something like that.
The HC-05 is a chip for getting an UART interface over bluetooth. To change that, you would need to reprogram it with a new firmware. I doubt, that any firmware, that you can find in the web, would be sufficient for your case. Not generic enough. Also the chips hardware is limited, so you can only get limited resources out of it. Most likely you have the HC-05 on an adaptor board, which has a voltage regulator on it (since the HC-05 is a 3.3V device). You would need to ditch that board and solder the chip itself.
The Nano is a bad choice for everything involving USB. The Atmega328p on it, that you program when programming the Arduino, does not have an USB interface. For that the Nano has a second chip, the Atmega32u4, which acts as USB to UART adaptor. You would need to hack it to do anything different than that. Doing it is possible, but you would need to ask yourself, why you are trying to do something so complex with such an incapable board. Also the Nano cannot be an USB host, nor a hub. There is an USB Host shield for the Uno, but that also is limited.
Getting anything even remotely near to 12Mbit/s is illusionary. You won't be able to process nearly one bit every clock edge. You already need several clock edges to do very primitive processing (going into an ISR and then moving the data into a different register, as you put it). And the translation between the protocols will not be that easy. You will need much processing power and also quite some RAM and flash (you will certainly need to buffer some data and the program itself will also be very big to implement something like USB). "A little lower speeds" don't cut it there. Even if possible, that would be painstakingly slow in comparison to a real USB hub.
Most of the software, that you would need for such a project, is non-existent. Doing something that complex with such crappy hardware is an edge case. So you would need to write your own USB stack software. As mentioned, the USB interface is very complex and if you need to ask this question, you are currently not capable of doing this (and neither am I).

I don't say it is absolutely impossible to implement a bit USB functionality with the Nano. But you won't get a satisfying result, that you really can use, even if you were an absolute expert on microcontrollers and the USB and bluetooth stacks (which you really would need to be for it). That is at maximum a project, that an expert would do just for the grind, not for real results.
You have a real life problem, that you want to solve. Choose the easiest way and buy an active USB extension cable.


text:
Home made drum kit - How can I speed up the response time after my sensor gets triggered?
I am trying to make a psudo drum kit with my Arduino Due and a couple Force Sensitive Resistors (activated with my fingers, no drum sticks). So far in my testing I'm only using one FSR. I've attached an SD Card reader and put a WAV File on there (44100 Hz, 16-bit, stereo). In my 'Loop', I read in the resistance of the FSR to know if it's been triggered, then I play the WAV file accordingly. It works but its not that fast. If this project is going to work, the response time needs to be much faster.
Here's my code:
#include "SD.h" //Lib to read SD card
#include "SPI.h" //SPI lib for SD card
#include <Audio.h>

#define SD_ChipSelectPin 2

const int FSR_PIN = A0; // Pin connected to FSR/resistor divider

const float VCC = 4.875;
const float R_DIV = 10000.0;

void setup()
{
  Serial.println("Starting Drum Kit!");
  Serial.begin(9600);
  while (!Serial) {}

  pinMode(FSR_PIN, INPUT);
  pinMode(LED_PIN, OUTPUT);

  Serial.print("Initializing SD Card...");
  if (!SD.begin(SD_ChipSelectPin)) {
    Serial.println("FAILED!");
    while(true);
  }
  Serial.println("done");

  // 44100kHz stereo => 88200 sample rate
  // 100 mSec of prebuffering.
  Audio.begin(88200, 100);

  void loop()
{
  File snare_file;
  short snare_buffer[1024];
  int fsrADC = analogRead(FSR_PIN);
  if (fsrADC > 20) // If the analog reading is non-zero
  {
    Serial.println(String(fsrADC));

    snare_file = SD.open("606snare.wav");
    while (snare_file.available()) {
      snare_file.read(snare_buffer, 1024);
      Audio.prepare(snare_buffer, 1024, 1024);
      Audio.write(snare_buffer, 1024);
    }
    snare_file.close();
  }
}

If I hold down the sensor (constant triggering), the fastest that the file plays is about every half second. Here's the Serial output:
15:12:28.453 -> Initializing SD Card...done
15:12:28.487 -> 1023
15:12:28.930 -> 1023
15:12:29.510 -> 1023
15:12:30.050 -> 1023
15:12:30.628 -> 1023
15:12:31.136 -> 1023
15:12:31.744 -> 1023
15:12:32.328 -> 1023
15:12:32.834 -> 1023
15:12:33.411 -> 1023
15:12:33.955 -> 1023

I've tried playing around with loading the file and buffer in the setup section but I can't get it to work properly. There's not a whole lot of documentation on the Audio library either.
If you know of a better way to speed this up, or if I should be using a different library, please let me know.

You wrote, that you tried loading the file in setup(), but it didn't work properly. How did it not work?  I think moving the loading there is really time consuming. Though keeping the sound loaded permanently might get a problem, when you need to load several files for several drum pads.

I tried creating a global snare_buffer. Then in the setup I would open the file, read the file into the global snare_buffer, and close the file. Then in the loop I would call the two Audio commands: Audio.prepare and Audio.write. This resulted in no sound being produced. I'm not sure how the Audio library works. There wasn't a whole lot of documentation on it. Not sure if there's a better way or a better library.

I would try to also execute prepare in setup, then only call write in loop. Also not closing the file. If that still doesn't give you the required performance, you might need to use an external player, that just get's triggered by the Arduino.

This is not really a 'solution', but it might help you in finding out where the real problem is.
Check out which of the statements in the loop function uses up the most time, probably;

int fsrADC = analogRead(FSR_PIN);
Serial.println(String(fsrADC));
snare_file = SD.open("606snare.wav");
while (snare_file.available()) {
snare_file.read(snare_buffer, 1024);
Audio.prepare(snare_buffer, 1024, 1024);
Audio.write(snare_buffer, 1024);
snare_file.close()

Try improving the most time consuming item if possible.
Some possibilities you can try in the steps above:

Do not use AnalogRead but direct port commands
Remove this completely or at least remove the String instance.
Not much you can do here, except not using a file system but raw SD read (you might have problems getting the files on your SD) without a dedicated program on your PC
Not sure about improving this one
Read less bytes, although it might even worsen things. Or read the bytes BEFORE waiting on the trigger (if you know which sample will be played).
Execute the prepare as before the trigger as 5 if possible.
Not sure about this... High likely you cannot keep too many files open at the same time.

Afaik in my synthesizer (Korg Kronos), it reads from all samples the initial part, meaning it can startup the data from RAM, while the rest is read through SSD (in your case SD). However, you might not have enough memory in an Arduino for that.

I know that it's not the analogRead or the print statement. If I comment everything else out and just leave those two in the loop(), the response time is extremely fast. There must be a way to read in my file into the buffer in setup(). I think the main bottle neck is opening and closing the file each time. I'm not sure how to get around this.

With millis you can exactly time it (run each command 1000 times, print times AFTERWARDS and divide it by 1000). Than you have to check into the library what happens exactly. When opening/closing a file takes too long, concatten all files you need, and read manually from the part of the big single file what you need.


text:
Do I need a resistor to control a servo with a PWM signal?
I working with Arduino Nano Every that has several analog PWM pins. I want to use one to control a small servo.
Do I need to put a resistor between PWM pin and the servo signal?

It depends. In my case I had to add 1k resistor. https://arduino.stackexchange.com/questions/88609/long-servos-cable-causes-arduino-to-restart

No, you don't.
Resistors are used to limit and control current (amongst other things) and you don't need to do that when sending a signal from one digital device to another.


text:
Receive SMS using Arduino Nano and Quectel EC25
I'm trying to use an Arduino Nano to communicate with a Quectel EC25 module from this Raspberry Pi 4G HAT. I'm using Arduino's pins 8 and 7 to communicate with RX and TX from the Quectel module. I'm able to establish communication and send AT commands.
The problem is that when I start to listen for incoming SMS, the available method does not change status, even if an SMS is received. There is the code I using:
#include <SoftwareSerial.h>

#define DEBUG Serial
SoftwareSerial EC25(8,7); // RX, TX - 9600 baud rate

#define AT_RESPONSE_LEN 100
#define TIMEOUT 1000

void setup() {
  // put your setup code here, to run once:
  EC25.begin(9600);
  DEBUG.begin(9600);

  sendATComm("ATE1","OK\r\n");
  sendATComm("AT","OK\r\n");
  sendATComm("AT+IPR?","OK\r\n");
  sendATComm("AT+CGSN","OK\r\n");

  sendATComm("AT+CNMI=2,1","OK\r\n");
  DEBUG.println("listennig");

}

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

  if (EC25.available()){
    DEBUG.println("Available");
  }

}

// function for sending at command.
const char* sendATComm(const char *command, const char *desired_reponse)
{
  uint32_t timer;
  char response[AT_RESPONSE_LEN]; // module response for AT commands.

  memset(response, 0 , AT_RESPONSE_LEN);
  EC25.flush();

  sendATCommOnce(command);

  timer = millis();
   while(true){
    if(millis()-timer > TIMEOUT){
      sendATCommOnce(command);
      timer = millis();
    }
    char c;
    int i = 0;

    while(EC25.available()){
      c = EC25.read();
      DEBUG.write(c);
      response[i++]=c;
      delay(2);
      }
      if(strstr(response, desired_reponse)){
        return response;
        memset(response, 0 , strlen(response));
        break;
      }
  }
}

// send at comamand to module
void sendATCommOnce(const char *comm)
{
  EC25.print(comm);
  EC25.print("\r");
}

That gives the following output:
ATE1

OK
AT

OK
AT+IPR?

+IPR: 9600

OK
AT+CGSN

860548040717545

OK
AT+CNMI=2,1

OK
listennig

I also tried this example by changing the default RX and TX pins but does not work at all.


text:
How to program ATmega4809 from Raspbeery GPIO
From this tutorial  I'm able to nicely program an ATmega328 using SPI raspberry GPIO pins. However, when I try the same steps with  ATmega4809, avrdude seems not having instructions and outputs the following:
program enable instruction not defined for part "ATmega4809"

So, how do I program ATmega4809 chip from Raspberry?

The ATMega4809 uses UPDI (Unified Programming and Debugging Interface) for programming, not ICSP like the older ATMega328P. You need a UPDI programmer.
There is a project jtag2updi which you can run on an Uno that turns it into a JTAG to UPDI adaptor which is then compatible with avrdude -c jtag2updi ....

But in that case, why does it have MOSI, MISO and SCK pins?
Also, I'm doing some experiments with Arduino Nano Every, which does not have UPDI pin available.

Because MOSI, MISO and SCK are SPI, not ICSP. It just so happens that on the ATMega328P those pins perform two functions: SPI and ICSP. But the two are not related in any way whatsoever.


text:
Program Nano Every using UPDI port
I have and Arduino Nano and an Arduino Nano Every. I'm doing some experiments and trying to program the Nano Every from the Nano, using the UPDI port.
I'm using tutorials like this one that does the same thing but instead of Arduino Nano Every he wants to program an ATtiny.
What I did so far:
1. Transform Arduino Nano into a UPDI programer:
1.1 Clone jtag2updi and open jtag2updi.ino. Connect Arduino Nano through USB to my computer and compile and upload jtag2updi with Arduino IDE just like any other sketch.
1.2 Connect a capacitor of 10uF between RST and GND pins of Arduino Nano
1.3 Install MegaCoreX into Arduino IDE.
2. Program  Arduino Nano Every from a UPDI:
2.1 Connect UPDI pin from Arduino Nano Every to pin D6 of Arduino Nano with a 4.7k resistor. Connect 5V and GND of both boards.
2.2 In Arduino IDE open the Blink example and chose from the Tools menu the following configuration:

2.3 Compile and upload sketch.
Error:
And the problem is that it gives this error:
Arduino: 1.8.12 (Mac OS X), Board: "ATmega4809, Nano Every, Reset, BOD 2.6V, Internal 20 MHz, No bootloader"

/Applications/Arduino.app/Contents/Java/arduino-builder -dump-prefs -logger=machine -hardware /Applications/Arduino.app/Contents/Java/hardware -hardware /Users/miguelwon/Library/Arduino15/packages -tools /Applications/Arduino.app/Contents/Java/tools-builder -tools /Applications/Arduino.app/Contents/Java/hardware/tools/avr -tools /Users/miguelwon/Library/Arduino15/packages -built-in-libraries /Applications/Arduino.app/Contents/Java/libraries -libraries /Users/miguelwon/Documents/Arduino/libraries -fqbn=MegaCoreX:megaavr:4809:pinout=nano_every,resetpin=reset,BOD=2v6,clock=internal_20MHz,bootloader=no_bootloader -vid-pid=1A86_7523 -ide-version=10812 -build-path /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660 -warnings=none -build-cache /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_cache_974903 -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.avr-gcc.path=/Users/miguelwon/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7 -prefs=runtime.tools.avr-gcc-7.3.0-atmel3.6.1-arduino7.path=/Users/miguelwon/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7 -prefs=runtime.tools.avrdude.path=/Users/miguelwon/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17 -prefs=runtime.tools.avrdude-6.3.0-arduino17.path=/Users/miguelwon/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17 -prefs=runtime.tools.arduinoOTA.path=/Users/miguelwon/Library/Arduino15/packages/arduino/tools/arduinoOTA/1.3.0 -prefs=runtime.tools.arduinoOTA-1.3.0.path=/Users/miguelwon/Library/Arduino15/packages/arduino/tools/arduinoOTA/1.3.0 -verbose /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_modified_sketch_697862/Blink.ino
/Applications/Arduino.app/Contents/Java/arduino-builder -compile -logger=machine -hardware /Applications/Arduino.app/Contents/Java/hardware -hardware /Users/miguelwon/Library/Arduino15/packages -tools /Applications/Arduino.app/Contents/Java/tools-builder -tools /Applications/Arduino.app/Contents/Java/hardware/tools/avr -tools /Users/miguelwon/Library/Arduino15/packages -built-in-libraries /Applications/Arduino.app/Contents/Java/libraries -libraries /Users/miguelwon/Documents/Arduino/libraries -fqbn=MegaCoreX:megaavr:4809:pinout=nano_every,resetpin=reset,BOD=2v6,clock=internal_20MHz,bootloader=no_bootloader -vid-pid=1A86_7523 -ide-version=10812 -build-path /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660 -warnings=none -build-cache /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_cache_974903 -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.avr-gcc.path=/Users/miguelwon/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7 -prefs=runtime.tools.avr-gcc-7.3.0-atmel3.6.1-arduino7.path=/Users/miguelwon/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7 -prefs=runtime.tools.avrdude.path=/Users/miguelwon/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17 -prefs=runtime.tools.avrdude-6.3.0-arduino17.path=/Users/miguelwon/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17 -prefs=runtime.tools.arduinoOTA.path=/Users/miguelwon/Library/Arduino15/packages/arduino/tools/arduinoOTA/1.3.0 -prefs=runtime.tools.arduinoOTA-1.3.0.path=/Users/miguelwon/Library/Arduino15/packages/arduino/tools/arduinoOTA/1.3.0 -verbose /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_modified_sketch_697862/Blink.ino
Using board '4809' from platform in folder: /Users/miguelwon/Library/Arduino15/packages/MegaCoreX/hardware/megaavr/1.0.4
Using core 'coreX-corefiles' from platform in folder: /Users/miguelwon/Library/Arduino15/packages/MegaCoreX/hardware/megaavr/1.0.4
Detecting libraries used...
/Users/miguelwon/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-g++ -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega4809 -DF_CPU=20000000L -DARDUINO=10812 -DARDUINO_AVR_ATmega4809 -DARDUINO_ARCH_MEGAAVR -I/Users/miguelwon/Library/Arduino15/packages/MegaCoreX/hardware/megaavr/1.0.4/cores/coreX-corefiles/api/deprecated -I/Users/miguelwon/Library/Arduino15/packages/MegaCoreX/hardware/megaavr/1.0.4/cores/coreX-corefiles -I/Users/miguelwon/Library/Arduino15/packages/MegaCoreX/hardware/megaavr/1.0.4/variants/nano-every /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/sketch/Blink.ino.cpp -o /dev/null
Generating function prototypes...
/Users/miguelwon/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-g++ -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega4809 -DF_CPU=20000000L -DARDUINO=10812 -DARDUINO_AVR_ATmega4809 -DARDUINO_ARCH_MEGAAVR -I/Users/miguelwon/Library/Arduino15/packages/MegaCoreX/hardware/megaavr/1.0.4/cores/coreX-corefiles/api/deprecated -I/Users/miguelwon/Library/Arduino15/packages/MegaCoreX/hardware/megaavr/1.0.4/cores/coreX-corefiles -I/Users/miguelwon/Library/Arduino15/packages/MegaCoreX/hardware/megaavr/1.0.4/variants/nano-every /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/sketch/Blink.ino.cpp -o /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/preproc/ctags_target_for_gcc_minus_e.cpp
/Applications/Arduino.app/Contents/Java/tools-builder/ctags/5.8-arduino11/ctags -u --language-force=c++ -f - --c++-kinds=svpf --fields=KSTtzns --line-directives /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/preproc/ctags_target_for_gcc_minus_e.cpp
Compiling sketch...
/Users/miguelwon/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-g++ -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -MMD -flto -mmcu=atmega4809 -DF_CPU=20000000L -DARDUINO=10812 -DARDUINO_AVR_ATmega4809 -DARDUINO_ARCH_MEGAAVR -I/Users/miguelwon/Library/Arduino15/packages/MegaCoreX/hardware/megaavr/1.0.4/cores/coreX-corefiles/api/deprecated -I/Users/miguelwon/Library/Arduino15/packages/MegaCoreX/hardware/megaavr/1.0.4/cores/coreX-corefiles -I/Users/miguelwon/Library/Arduino15/packages/MegaCoreX/hardware/megaavr/1.0.4/variants/nano-every /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/sketch/Blink.ino.cpp -o /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/sketch/Blink.ino.cpp.o
Compiling libraries...
Compiling core...
Using precompiled core: /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_cache_974903/core/core_27f4eba04d8686aefe2683c90c98eae6.a
Linking everything together...
/Users/miguelwon/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-gcc -w -Os -g -flto -fuse-linker-plugin -Wl,--gc-sections -Wl,--section-start=.text=0x0 -mmcu=atmega4809 -o /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/Blink.ino.elf /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/sketch/Blink.ino.cpp.o /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/../arduino_cache_974903/core/core_27f4eba04d8686aefe2683c90c98eae6.a -L/var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660 -lm
/Users/miguelwon/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-objcopy -O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0 /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/Blink.ino.elf /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/Blink.ino.eep
/Users/miguelwon/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-objcopy -O ihex -R .eeprom /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/Blink.ino.elf /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/Blink.ino.hex
chmod +x /Users/miguelwon/Library/Arduino15/packages/MegaCoreX/hardware/megaavr/1.0.4/scripts/create_disassembler_listing.sh
/Users/miguelwon/Library/Arduino15/packages/MegaCoreX/hardware/megaavr/1.0.4/scripts/create_disassembler_listing.sh /Users/miguelwon/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-objdump "--disassemble --source --line-numbers --demangle --section=.text" /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/Blink.ino.elf /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/Blink.ino.lst
/Users/miguelwon/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-size -A /var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/Blink.ino.elf
Sketch uses 814 bytes (1%) of program storage space. Maximum is 49152 bytes.
Global variables use 4 bytes (0%) of dynamic memory, leaving 6140 bytes for local variables. Maximum is 6144 bytes.
Forcing reset using 1200bps open/close on port /dev/cu.usbserial-1440
/Users/miguelwon/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17/bin/avrdude -C/Users/miguelwon/Library/Arduino15/packages/MegaCoreX/hardware/megaavr/1.0.4/avrdude.conf -v -patmega4809 -cjtag2updi -P/dev/cu.usbserial-1440 -e -Uflash:w:/var/folders/vp/2f2lk6gj16v00znk4lc6yrkw0000gn/T/arduino_build_818660/Blink.ino.hex:i -Ufuse0:w:0x00:m -Ufuse1:w:0x54:m -Ufuse2:w:0x02:m -Ufuse4:w:0x00:m -Ufuse5:w:0xC9:m -Ufuse6:w:0x06:m -Ufuse7:w:0x00:m -Ufuse8:w:0x00:m -Ulock:w:0xC5:m

avrdude: Version 6.3-20190619
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2014 Joerg Wunsch

         System wide configuration file is "/Users/miguelwon/Library/Arduino15/packages/MegaCoreX/hardware/megaavr/1.0.4/avrdude.conf"
         User configuration file is "/Users/miguelwon/.avrduderc"
         User configuration file does not exist or is not a regular file, skipping

         Using Port                    : /dev/cu.usbserial-1440
         Using Programmer              : jtag2updi
JTAG ICE mkII sign-on message:
Communications protocol version: 1
M_MCU:
  boot-loader FW version:        1
  firmware version:              6.00
  hardware version:              1
S_MCU:
  boot-loader FW version:        1
  firmware version:              6.00
  hardware version:              1
Serial number:                   00:00:00:00:00:00
Device ID:                       JTAGICE mkII
         AVR Part                      : ATmega4809
         Chip Erase delay              : 0 us
         PAGEL                         : P00
         BS2                           : P00
         RESET disposition             : dedicated
         RETRY pulse                   : SCK
         serial program mode           : yes
         parallel program mode         : yes
         Timeout                       : 0
         StabDelay                     : 0
         CmdexeDelay                   : 0
         SyncLoops                     : 0
         ByteDelay                     : 0
         PollIndex                     : 0
         PollValue                     : 0x00
         Memory Detail                 :

                                  Block Poll               Page                       Polled
           Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00
           prodsig        0     0     0    0 no         61   61      0     0     0 0x00 0x00
           fuses          0     0     0    0 no          9    0      0     0     0 0x00 0x00
           fuse0          0     0     0    0 no          1    0      0     0     0 0x00 0x00
           fuse1          0     0     0    0 no          1    0      0     0     0 0x00 0x00
           fuse2          0     0     0    0 no          1    0      0     0     0 0x00 0x00
           fuse4          0     0     0    0 no          1    0      0     0     0 0x00 0x00
           fuse5          0     0     0    0 no          1    0      0     0     0 0x00 0x00
           fuse6          0     0     0    0 no          1    0      0     0     0 0x00 0x00
           fuse7          0     0     0    0 no          1    0      0     0     0 0x00 0x00
           fuse8          0     0     0    0 no          1    0      0     0     0 0x00 0x00
           lock           0     0     0    0 no          1    0      0     0     0 0x00 0x00
           data           0     0     0    0 no          0    0      0     0     0 0x00 0x00
           usersig        0     0     0    0 no         64   64      0     0     0 0x00 0x00
           flash          0     0     0    0 no      49152  128      0     0     0 0x00 0x00
           eeprom         0     0     0    0 no        256   64      0     0     0 0x00 0x00

         Programmer Type : JTAGMKII_PDI
         Description     : JTAGv2 to UPDI bridge
         M_MCU hardware version: 1
         M_MCU firmware version: 6.00
         S_MCU hardware version: 1
         S_MCU firmware version: 6.00
         Serial number:          00:00:00:00:00:00
         Vtarget         : 5.0 V

avrdude: jtagmkII_set_devdescr(): bad response to set device descriptor command: RSP_NO_TARGET_POWER
avrdude: jtagmkII_initialize(): Cannot locate "flash" and "boot" memories in description
avrdude: AVR device initialized and ready to accept instructions

Reading | avrdude: jtagmkII_program_enable(): bad response to enter progmode command: RSP_NO_TARGET_POWER
avrdude: jtagmkII_program_enable(): bad response to enter progmode command: RSP_NO_TARGET_POWER
avrdude: jtagmkII_read_byte(): bad response to read memory command: RSP_NO_TARGET_POWER
avr_read(): error reading address 0x0000
    read operation not supported for memory "signature"
avrdude: error reading signature data for part "ATmega4809", rc=-2
avrdude: error reading signature data, rc=-2
avrdude: jtagmkII_program_disable(): bad response to leave progmode command: RSP_NO_TARGET_POWER

avrdude done.  Thank you.

the selected serial port
 does not exist or your board is not connected

use "Upload using programmer" in Sketch menu

Thanks but same error.

I'm not sure if you ever solved this issue but for me this error was occurring because the ATmega4809 chip was not powered on. By adjusting the wiring I managed to get rid of the "RSP_NO_TARGET_POWER" error.
So I would suggest double checking wiring and then use the "Upload using programmer" (in "Sketch" tool-bar menu) to upload as suggested by Juraj.


text:
Define a custom baudrate in Serial Monitor
Is there a way to define a different baud rate from the ones we are shown in the dropdown menu of the Serial Monitor? I want to define a custom value.

There is no easy way to do so. The list of available baud rates is
hard-coded in the Java source of the Arduino IDE. To add a custom
rate, you would have to modify the source code and rebuild the
IDE.
I suggest you consider using a terminal emulator instead of the
serial monitor. On Linux, I like picocom: not a real terminal
emulator, but a minimal program that “connects” the terminal emulator
you are already using (gnome-terminal, rxvt...) to the serial port. It
supports custom baud rates, which it rounds to the nearest
rate the hardware can provide. Picocom works on Mac too.
For Windows, Adafruit recommends Putty or X-CTU. Sparkfun
recommends quite a few options for Windows, Mac and Linux.

If you are growing out of the Arduino IDE consider swaping to PlatformIO, baud-rate is just one of the many extra things you will get a chance to tweek.
If you are on X64 architecture, you can although use eclipse, but I find platformIO bit better for Arduino.
Arduino IDE is an OK starter, but to grow you will need to move further.
To add to Edgar Bonets answer, there are many other serial terminals including but not limited to: pyserial (multiplatform),screen (UNIXes), even good old Putty (runs on nearly everything that can blink I believe even on comodore)...


text:
Why is delay(1000) breaking my serial communication?
I have the following sketch...
void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
}

void loop() {
  if(Serial.available() > 0){
    Serial.println("Hello world from Ardunio!");
  }
}

This works great with my client code...
import SerialPort from 'serialport';
const port = new SerialPort('/dev/ttyACM0', {
  baudRate: 115200,
  autoOpen: false
})

port.open(function (err) {
  if (err) {
    return console.log('Error opening port: ', err.message)
  }

  // Because there's no callback to write, write errors will be emitted on the port:
  console.log("port opened");
  port.on('readable', function () {
    console.log('Data:', port.read())
  })
})

Now I want to slow it down so I change the sketch to...
void loop() {
  if(Serial.available() > 0){
    Serial.println("Hello world from Ardunio!");
  }
  delay(10000);
}

I would expect this to delay each message by 10 seconds, however, it seems to never rerun so I do not get any messages. What am I missing? Why would delay break the loop?

What if you double the line Serial.println("Hello world from Ardunio!");?

what happens if you remove the delay?

I thought it was working fine but now I am questioning that as I am having trouble again after going back from a couple of other things I was trying. I am not sure if when it was working I was still accidentally using while. I will try adding a few writes with delays and see if that helps at all. The ultimate goal is to write to the serial port every n seconds.

It just doesn't seem that loop is looping, If I remove the if and add multiple prints and delays it does seem to work. Why doesn't it work if I use the if statement?

Do you write anything to the arduino on the serial line?

because the if statement test does not evaluate to true

NEVER use delay() in a loop - its a bad habit you get used to and then you return later on with complex code asking why nothing is happening or your webserver is dead for 10 seconds every time you receive a request.
So instead of
void loop() {
  if(Serial.available() > 0){
    Serial.println("Hello world from Ardunio!");
  }
  delay(10000);
 }

you would do
unsigned long timerStart = 0;
unsigned long myTimer = 10000;

setup(){....}

 void loop() {
  if(Serial.available() > 0 ){
     if(millis() - timerStart > myTimer){      // non blocking
       Serial.println("Hello world from Ardunio!");
       timerStart = millis(); // reset timer
     }
   }
 }

What your code does at the moment is enter the IF clause if exactly in this millis the buffer is filled, then wait for ten seconds ignoring whatever you do. Next chance tohit and so on. Delay() is blocking processing => not a good thing todo in communication scenarios,

Sure makes sense thanks

Get rid of if(Serial.available() > 0). You only need that if statement if you're expecting information from Serial, but it doesn't seem to be the case for your project.
Also, only use delay() if you have a really good reason to.

So that is the next step. So that is triggered when you write?

Also that was probably why it worked the first time, I tried to simplify the code for SO and assumed removing the write would not be an issue. I was wrong

if(Serial.available() > 0) is triggered when something is received from the PC. If you have a problem with your code - post the entire code. You don't know where the bug is - it could be in the code that was left out


text:
Can ultrasonic distance sensor get good readings for a passing object?
I am working on a project where I laid 5 Ultrasonic distance sensors in a string on a rigid wood plank that lays on the ground and points all the sensors upward behind the guy with the bat.
When the pitcher pitches the ball and the ball goes over the sensors, the sensors have to detect the passing ball and compute their distance from the ground to have an idea whether the ball passed within the strike zone.
I ran into the following issues
Issue #1: The ultrasonic distance sensor was giving a lot of "noise", the pulse in was giving some 10-15 different values all the time even when it's just statically placed on the table while looking at the ceiling. Which was computing 15 different distances to the ceiling some of them were far off from the others.
I solved issue #1 by using a "initialization" routine where for first 10 seconds the sensor collects those noises and adds them to an array so it can ignore them later. All good.
Issue #2: The sensors failed to detect a fast moving ball, in fact I had to pass the ball super slow like 2 centimeters per seconds for it to detect it, otherwise there was no reading (may be something wrong with my code).
Here are my questions

Is ultrasonic distance sensor capable of detecting a fast moving object? My initial assessment with a simple pulseIn did show me something that sounded meaningful but that may have been just the noise throwing me off.
What other type of sensors can be good for this type of problems?

Here is my code. My apologies if this ridiculously long and rough sketch is not easy to read.
#include "stdio.h"

const int PIN_TRIG = 9;
const int PIN_ECHO = 10;
const int PIN_WARN = 11;

long distance;
int duration;
long oldDistance;

 int min = 1024;
unsigned int max = 0;
int totalUniques[100];

unsigned int cycles = 0;
bool warnOn = false;
unsigned int warnTime = 0;

bool uniqueCollected = false;

void setup() {
  // put your setup code here, to run once:
 pinMode(PIN_TRIG, OUTPUT);
 pinMode(PIN_ECHO, INPUT);
 pinMode(PIN_WARN, OUTPUT);
 InitializeUniques();

 Serial.begin(9600);

  digitalWrite(PIN_WARN, HIGH);
  warnOn = true;
}

void loop() {

  digitalWrite(PIN_TRIG, LOW);
  delayMicroseconds(2);

  digitalWrite(PIN_TRIG, HIGH);
  delayMicroseconds(15);
  digitalWrite(PIN_TRIG, LOW);

  duration = pulseIn(PIN_ECHO, HIGH);
  distance = duration*0.034/2;

  if (distance < min && distance != 0)
  {
    min = distance;
  }

  if (distance > max)
  {
    max = distance;
  }

 if (uniqueCollected == false)
 {
  int st = AddUnique(distance);

  printWithLabel("Adding unique", distance, "Total Unique Status", st);
  if (cycles > 1000)
  {
    PrintAllUniques();
    uniqueCollected = true;

    warnOn = false;
    digitalWrite(PIN_WARN, LOW);
    warnTime = millis();
  }
  else
  {
    cycles++;
  }
 }

  if (warnOn == true && uniqueCollected == true)
  {
    auto t = millis();
    if (abs(t - warnTime) > 10000)
    {
      digitalWrite(PIN_WARN, LOW);
      warnOn = false;
    }
  }

  if (distance > 150)
  {
    AddUnique(distance);
  }
  if (warnOn == false && uniqueCollected == true && FoundInUniques(distance) == false)
  {
    PrintAllUniques();
    printWithLabel("distance", distance);
    warnOn = false;
    digitalWrite(PIN_WARN, HIGH);
    delay(10000);

    digitalWrite(PIN_WARN, LOW);
   // warnTime = millis();
  }

  if (oldDistance < 0 && distance > 0 && distance < 150)
  {
   // printDistances(1);
  }
  else if (abs(oldDistance - distance) > 30)
  {
  //  printDistances(2);
  }

  oldDistance = distance;

 // Serial.print("Distance: ");
  //Serial.println(distance);

}

void printDistances(int caller)
{

    Serial.print("Something detected in the way");
    Serial.print(caller);
    Serial.print(" old : ");
    Serial.print(oldDistance);
    Serial.print(" new : ");
    Serial.println(distance);
}
void printWithLabel(char* label, int value)
{
   Serial.print(label);
   Serial.print(": ");
   Serial.println(value);
}
void printWithLabel(char* label1, int value1, char* label2, int value2)
{
   Serial.print(label1);
   Serial.print(": ");
   Serial.println(value1);
   Serial.print(", ");
   Serial.print(label2);
   Serial.print(": ");
   Serial.println(value2);
}
int AddUnique(int value)
{

  if (value == 0)
  {
    return -1;
  }
  int i=0;
  for (i=0;i<100;i++)
  {
    if (abs(totalUniques[i] - value) <= 3 || totalUniques[i] == 0)
    {
      break;
    }
  }

  if (i >= 100)
  {
    return -2;
  }
  else if (totalUniques[i] == 0)
  {
    totalUniques[i] = value;
    return i + 1;
  }
  return CountTotalUniques();
}

void InitializeUniques()
{
  for (int i=0;i<100;i++) totalUniques[i]=0;
}

int CountTotalUniques()
{
  for (int i=0;i<100;i++)
  {
    if (totalUniques[i] == 0)
    {
      return i;
    }
  }
}

void PrintAllUniques()
{
  Serial.print("Unique Values :");

  for (int i=0;i<100 && totalUniques[i] != 0;i++)
  {
    Serial.print(totalUniques[i]);
    if (i < 99)
    {
       Serial.print(", ");
    }
  }

  Serial.println(" ");
}

bool FoundInUniques(int value)
{
  if (value == 0)
  {
    return true;
  }

  for (int i=0;i<100 && totalUniques[i] != 0;i++)
  {
    if (abs(totalUniques[i] - value) <= 3)
    {
      return true;
    }
  }

  return false;
}

This doesn't sound very feasible.  In order for it to work you'd have to fire the ping sensor at exactly the right millisecond so that the sound meets the ball directly above the sensor.   Whatever means you use to detect the ball in order to fire the sensor would probably itself be a better option for locating the ball.

@Delta_G What's the harm in firing the sensor every few microseconds? It can't miss the ball unless Nolan Ryan is pitching. Correct?

Because the sensor can't fire that fast.  How high is the ball above the sensor?  How long does it take sound to go that far?  How fast is the ball moving?  How long will it be in the spot above the sensor?

Sound travels at around 1100 feet per second.  So that gets us about 1.1 feet per millisecond.  If the ball is shoulder high then we've got something on the order of 10ms for the round trip before we can safely say we didn't see the ball.  And that's assuming nothing misses high.  So once every ten or fifteen milliseconds you can fire the sensor.    If we're in the little league throwing 60mph then we're at 88 ft/s.  That's 11ms to cross a 1 foot section.   You see where we're going?  That's on the same order as your cycle time for the sensor.  You can't fire fast enough.

@Delta_G "So once every ten or fifteen milliseconds you can fire the sensor", did you mean Microseconds? I am firing every few microseconds.

@fahadash No, he ment milliseconds. It is irrelevant how fast you create a trigger pulse on the Arduino. It needs 10ms to receive the echo of trigger pulse. You need to wait for the echo to arrive, before firing the next pulse, or you will get false readings, because the echo of the first pulse is still to come (also most likely your sensor simply cannot trigger a new pulse before the current pulse is finished

you would be better off detecting the breaking of two planes a know distance apart, and measuring the time between breaks.

If you are firing the pulse every few microseconds and it takes 10ms for the pulse to travel to the ball and back, how will you know which pulse hit the ball?  How will you calculate distance if you don't know which pulse it was?


text:
Having trouble assigning colour to my neopixels
Hi I was wondering if someone is able to help me! I am currently trying to get a strip of 10 neopixels to change colour. I want to be able to code a random neopixel in the strip to change to either red, blue, green and yellow consecutively after 2 seconds. I am relatively new to Arduino so I'm still learning. I have been using the code below and it does everything that I want it to but I would like to set the colour so they're not as randomised. I found this code online.
#include <Adafruit_NeoPixel.h>

#define PIN 6
#define LED_COUNT 50
Adafruit_NeoPixel strip = Adafruit_NeoPixel(LED_COUNT, PIN, NEO_RGB + NEO_KHZ800);

void setup() {
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
}

void loop()
{
  randomPixelColor(100);

}

void randomPixelColor(int wait)
{
  int i= random(strip.numPixels());

  uint32_t c = random(2147483647); // I have no idea what this crazy number does.
  strip.setPixelColor(i, c);
  strip.show();
  delay(1000);

}    // end void randomPixelColor()

I don't even know if this is the right code to be using! Hopefully someone can help me cause I'm so confused.

What does "not as randomized" mean? The magic number is equal to 2^31 - 1, though that does not make much sense, since the color of an RGB strip only uses 24 bits, thus a random number covering all the RGB color space, that is available, would have 2^24 -1 as maximum value

I would like it to change from red, to blue, to green, to yellow every 2 seconds, but I would like it to be a random pixel that changes rather than a set one.

You already are choosing a random LED. Now you only need to define and use the colors, that you need. Define an array with the colors:
#define COLOR_N 4
uint32_t colors[COLOR_N] = {0x00FF0000, 0x000000FF, 0x0000FF00, 0x00FFFF00};

Also define a static or global variable to hold the current color:
uint8_t current_color = 0;

Then use this array in strip.setPixelColor() with the current_color variable as index:
strip.setPixelColor(i, colors[current_color]);

Now increment current_color for the next color. To go from yellow to red again, you can use the modulo operator %:
current_color = (current_color + 1) % COLOR_N;

You can easily extend to more colors, by writing the new colors into the colors array and setting COLOR_N to the corresponding value.

About the color values: The neopixels use an RGB color model with 8 bit depth. That means, that each component (red, green and blue) occupies exactly 1 byte. Thus there are 256 steps for each component. To describe a full color, you need all three components, thus 3 bytes or 24 bits. The data type, that fits this uint32_t (unsigned integer with 32 bit), though the most significant byte is unused here (if you use an RGBW strip, this byte is the component for the white LEDs).
We can write the number, that is representing a full color, as a hexadecimal value. Each component occupies 2 hexadecimal digits:
0x00RRGGBB

where 0x is the prefix, which marks a hexadecimal number, and RR, GG and BB are the components red, green and blue of the color. So a full red is 0x00FF0000, a full blue is 0x000000FF (the leading zeros are not mandatory, but I think they help readability and comparability).
The color mixing works additive here, just like light does. All components mixed together at the same ratio gives you white, all components to zero means black. Thus you get yellow from mixing red and green the same ratio. So a full yellow is 0x00FFFF00.

Good answer. However, you should explain where your color values come from.

Something like: "RGB can be expressed as 3 2-digit hex (hexadecimal) numbers plus 2 leading zeros. (Hex numbers range from 0 to F, so a 2 digit hex number ranges from 00 to FF, or 0 to 255 decimal.) Take an 8 character hex number. The digits would be 00RdGrBl, where "Rd" are the digits for red, "Gr" are the digits for green, and "Bl" are the digits for green. By convention, you write hex numbers with the prefix "0x", which tells the reader (and the compiler) that the number is in hex. So the color 0x00FF0000 has FF, or 255, for red, and 0 for green and blue. This color is bright red.

The color 0x00FFFF00 has FF (255) for red and green, and no blue. In additive colors, red + green = yellow. (LEDs and displays use additive colors. Paint and dies use the subtractive colors we learned in school, where blue + yellow = green)

@DuncanC I added a paragraph about this topic

Outstanding. You might want to add a bit about the difference between additive and subtractive colors, since this confuses the hell out of just about everybody since we learn in art class that blue+yellow=green.

@DuncanC I wouöd prefer not to boat the answer. Color mixing was not a part of the question and the OP did not ask a follow up on this. Also there are many resources that explain that very good


text:
What is the difference between delay() and delaymicroseconds()
Does delaymicroseconds() provide something more than the time accuracy

There is a more important difference between the two functions other than the unit of time the accept as parameters
the function delay() calculates time using the time interript of the arduino. However Delaymicroseconds() does not use the time interrupt
As you may know once an interrupt is called it stops all other interrupts
So the real difference is you can not use delay() in a program in which you are using an interrupt and instead, use delaymicroseconds() but be aware that it has a range where it is accurate and it is between 3 and 16383 micro seconds

That's not entirely true.  You can use delay in a program with an interrupt, you just can't use it in the ISR.

"delay() calculates time using the time interript" - that's not really of importance. As you can see in the source code ( https://github.com/arduino/ArduinoCore-avr/blob/master/cores/arduino/wiring.c), delay() uses the micros() function which itself requires timer interrupts to increment a counter. The respective interrupt gets fired even if you don't use delays. As long as you don't need interrupts from the involved timer, there are no complications using interrupts and delay(). You are right about delayMicroseconds(): it counts a defined number of CPU cycles (determined by F_CPU).


text:
Why can't I use 3V output of arduino pro mini?
I have an Arduino pro mini and I tested digital write of an pin and it is 3.2V and then I connected it to a 3V motor, but when I connected the motor to it, The voltage drops under 0.2 Volt, Can any one describe the science behind voltage drop ?
I know I've better use a transistor and separate the motor power but, what you should do when you have a single 3V power source? and I know there are some motor driver chips, but is it possible to keep it simple?

Science behind this? It's either some big motor or you forgot to make that pin an output, and pullup is even weaker than push-pull driver. Look for terms like Voltage source, ideal voltage source and loaded voltage source. (+ info from answers)

NEVER drive a motor directly from an Arduino IO pin.  You will kill the Arduino.
It's not a question of voltage, it's a question of current, and that is where the transistor comes in.  If you have a 3.3V Arduino (as it sounds like you have) then you may be able to drive the motor using the 3.3V output of the Arduino (VCC pin? Not sure with that model) and a transistor. That is the simplest arrangement.

simulate this circuit – Schematic created using CircuitLab

Using that circuit is a bad idea. (not the part about never trying to drive a motor directly from a GPIO pin. That part is true.) At the very least you'll need a flyback diode across the motor to prevent reverse EMF from damaging the transistor. Another problem is that the 3.3V output  from most Arduinos is VERY low current - and quite unlikely to be enough to drive a motor. It might overheat the voltage regulator, or cause the 3.3V line on the Arduino to droop

@DuncanC Good call on the flyback diode. I forgot that. But you are wrong about the 3.3V. On old Arduinos where the 3.3V was provided by the FT232 chip it was limited to 50mA. Now it's in the order of hundreds of mA - and on a 3.3V board it will be many more.  But I did qualify it with may be able to.

@DuncanC That's CircuitLab's symbol for a schottky. It wants to be a schottky, not a normal diode, so it switches into reverse faster.

@DuncanC By the way - for the 3.3V, ignore the specs on the Arduino website. Those haven't been updated since the R1, and it has gone through many revisions since then.

And anyway, for the Pro Micro 3.3V it uses the MIC6219 which can provide 500mA peak.

About the bipolar transistor - the voltage drop starts around 1.4V (depends on Ice current and also on base current/h21e), so it can be little bit too much for 3.3V (at least 3V motor won't run at full speed)

I would normally use a FET. But I doubt the OP could get his head around that. So confusing the poor little ardueenies with pedantry.

What is the current rating of your motor? What type of Arduino are you using, and how much current does it say it can provide from the 3.3V line? The bottom line is this: The voltage regulator will adjust it's output to keep the 3.3V line at 3.3V up to it's current limit. If you draw more current than that, the voltage will start to drop, and/or the voltage regulator will start to overheat.

He already said it was a pro mini. I have already given the specs of the regulator on there.

I can't find anything on the part number MIC6219. What is it's sustained current rating? And isn't that with a good heatsink attached? Arduino boards don't usually have any heatsinks on their  voltage regulators, which GREATLY reduces the sustained power you can draw from them without overheating them.

@DuncanC That was a typo - it should be the MIC5219... http://ww1.microchip.com/downloads/en/DeviceDoc/MIC5219-500mA-Peak-Output-LDO-Regulator-DS20006021A.pdf

You can drive the motor from the same 3v supply that powers your Arduino (assuming the supply can deliver enough current for both). What you can't do is power the motor through the Arduino, neither from a pin, nor from its on-board voltage-regulator. And especially don't try to use a 5v Arduino's 3v pin to drive it. Their 3v regulators provide only a limited amount of current.
If you try to drive a motor through the Arduino and it needs too much current, you risk frying the Arduino. If you supply the motor from the same power supply but not through the Arduino, and the motor takes too much current, the worst that will happen is the supply voltage will fall and Arduino will shut down.


text:
Powering 150 WS2812B LED strips
I just bought an Elegoo Uno R3 today and delved into programming Arduinos. For my first project I'd like to power a 5m LED strip (30 LED/m). I've learned that an individual neopixel needs around 60 mA, and i'm gonna assume this means that to power all 150, I need 9A. I'm extremely new to all this (and electrical stuff in general) and not exactly sure how to go on about giving 9A worth of power to the strips and the Arduino. Any help to get me on the right track would be appreciated.

Step one: buy a power supply that gives at least 9A. Step two: connect it.

The neopixel uberguide should give all info required to get started. https://www.google.com/url?sa=t&source=web&rct=j&url=https://cdn-learn.adafruit.com/downloads/pdf/adafruit-neopixel-uberguide.pdf&ved=2ahUKEwjQss2n6-bgAhUBIVAKHQtlAFUQFjAAegQIBBAB&usg=AOvVaw1-UNr6xUSFV5fscJPYqsFR

"Any help to get me on the right track would be appreciated." Is not really a question. Notable is that this only counts if you put R/G/B all on 100%, you're right, but you may settle for less

Your math looks right to me. You need a 9A power supply if you're going to drive all 150 LEDs at %100 brightness on all 3 channels.
I'd suggest using a separate 500mA 5V regulated power supply for the Arduino. Switching 9A of load on and off on the LED power supply is going to cause quite a bit of variation in the voltage on that 9A supply, and the simplest way to keep the power supply to the Arduino clean is to make the 2 power supplies completely different.

Connect the power supply in multiple places to the LED strip. The two ends and the middle at least. That will keep all the current from having to flow thru all of the strip.  If try to power it from just one end, the power traces in the strip might act as a fuse and blow open. Or it might survive, but act like a low-ohm resistor and the chips farther down the string will see less voltage (because voltage down the trace = current x resistance) and may appear dim, or act weirdly, or not turn on at all.

I would hope that an off-the-shelf LED strip is built with heavy-duty enough traces to handle it's maximum current load. If not is a pretty shoddy product, an would likely fail UL or CE test certification.

Do you see any UL or CE test certification marking on your strip?

Fair question, but even if they aren't UL/CE certified, they shouldn't melt if you turn everything on.

Yes, "shouldn't". But very hot is not melting, yet can still have lots of voltage loss down the length. Measure the voltage down the string if you see odd things.


text:
How to connect 3 MPU9250 to Node Mcu together?
I don't know how to connect 3 MPU9250 together on Node Mcu. There is not much information available. I am using bolder flight library for imu sensor - https://github.com/bolderflight/MPU9250
Can anyone post the image of connection on sensor and example of code? Thanks a lot.

it connects the same way as any other I2C device, so lookup an image of say, an oled or ads1115 adc or something like that.

but I want to do it 3 together?


text:
How to stabilize magnetic levitation system?
I followed everything from this project but still, the magnet is not levitating - https://www.hackster.io/jsirgado/magnet-levitation-with-arduino-eeeee4
The best I can do is to make the magnet jump up and down fast but it never levitates. Have tried changing PID setting from the project as aggressive and mild but still didn't achieve the final result.
I need advice from an expert to tell me what I am doing wrong here. All components are in good condition and 5v electromagnet is strong enough.
So what am I missing here? will implementing fast PWM mode be helpful?

I'd try to hold the magnet in your hand, and hold it at different positions, and feel if the system is trying to move the magnet, like you want it to. There't to many factors that could be different to the hackster project, like magnet strength, weight, coil strength, coil diameter, coil resitance(, your latitude on the planet).

I tried that and for me, it vibrates up-down and even sideways. How do I dampen this vibration to make it stable? Will the fast PWM mode help here?

That sounds like it's over-correcting. Not sure what to do about that. I'm not that familiar with PID.

@suu if it vibrates my guess is that your PID gains are to strong. What happens when you experiment with the gains while holding the magnet? Have you tried changing the position of the hall sensor? I don't think changing to fast pwm will make a change...

Maybe the magnet has an inductance too high to adjust the magnetic field fast enough. You would then loose resolution which is already very limited on an uno and which will worsen the quality of your control loop. The same applies to the analog measurement, you should try to use the 10 bits you get from the arduinos adcs as good as possible. For debugging you can monitor the dutycycle and the analog reading.

I tried lower PID gains and changed the position of the sensor below & above the permanent magnet also. I will check about resolution thing.

I'd look into the update time of the PID code versus the time constant of the physical system.  If your PID is sampling and adjusting much faster or slower than the physical system responds, then you could get oscillations.  The article recommends that "Heavy objects are more stable", so maybe the electromagnet is too strong for the control system.  Maybe try increasing the mass of the magnet or reducing the voltage/power to the electromagnet?

The answer to the solution was quite simple. I just had to comment out all serial port reading and Arduino processing became 60 times faster which helped to levitate the magnet. Thanks to everyone who helped me here :)


text:
Not able to split string into 2 char
I am trying to split an incoming string into 2 integer values since I have to control 2 dc motors with it. The processor is node MCU and I get following error:-
Com Port Reading:-
WiFi connected
Received: "84+62"
"84+62"

Soft WDT reset

>>>stack>>>

ctx: cont
sp: 3ffffd90 end: 3fffffc0 offset: 01b0
3fffff40:  2b343822 00223236 3ffee70c 40204148
3fffff50:  3ffe85ee 3ffee6d8 3ffee70c 402043c5
3fffff60:  3ffe85dc 3ffee70c 3ffee6d8 402043c5
3fffff70:  3ffe85f0 3ffee69c 00000000 00000001
3fffff80:  00000000 40200038 3ffefca4 0000000f
3fffff90:  00000007 00000000 00000001 402048f9
3fffffa0:  3fffdad0 00000000 3ffee744 40204984
3fffffb0:  feefeffe feefeffe 3ffe851c 401009a5
<<<stack<<<

 ets Jan  8 2013,rst cause:2, boot mode:(3,6)

load 0x4010f000, len 1384, room 16
tail 8
chksum 0x2d
csum 0x2d
v951aeffa
~ld

Code:-
if (msg.length() > 0) {
        Serial.print("Received: "); Serial.println(msg);
        char charBuf[50];
        msg.toCharArray(charBuf, 50);
        Serial.println(charBuf);

        char left[3] = {};
        char right[3] = {};
        int n = 0;

        while (charBuf != 0) {
          for (int i = 0; i < strlen(charBuf); i ++) {
            if (charBuf[i] != '+') {
              left[n] += charBuf[i];
              n++;
            }
            else {
              n = 0;
              break;
            }
            right[n] += charBuf[i];
            n++;
          }
        }
        Serial.println("Left Motor: "); Serial.print(left);
        Serial.println("Right Motor: "); Serial.print(right);

    }

My desired result is following:-
Left Motor: 84
Right Motor: 62

So what changes I need to make?

your code loops in while (charBuf != 0) { until watchdog resets the MCU

Use strtok() to split your string.

can you show an example using strtok()

Here's an example sketch that uses strtok().
char charBuf[] = "\"84+62\"";

// Set array size to maximum number of integers you will receive.
uint16_t myArray[2];

void setup(){

  Serial.begin(9600);

  int counter = 0;
  char* pch = strtok(charBuf, "\"+");

  while(pch != NULL){
    myArray[counter] = atoi(pch);
    pch = strtok(NULL, "\"+");
    counter += 1;
  }

  // Print out the contents of the integer array.
  for(int i = 0; i < counter; i++){
    Serial.println(myArray[i]);
  }
}

void loop(){}

myArray[0] contains 84 and myArray[1] contains 62.

"84+62"

The additional doublequote characters are part of your string and charBuf
    Serial.println(charBuf);  // Text with " and  +

    char* cpl = nullptr;
    char* cpr = nullptr;
    for (char* cp = charBuf; *cp != 0; cp++) {
        if (*cp != '"' && ! cpl )  cpl = cp;
        if (*cp == '"') *cp = 0;
        if (*cp == '+' ) {
          *cp = 0; // split
          cpr = cp+1;
        }
    }
    Serial.println("Left Motor: "); Serial.println(atoi(cpl));
    Serial.println("Right Motor: "); Serial.print(atoi(cpr));

You get this memory leak because you overflow the variable right. This does not happen in the for loop itself even though this could be implemented more straight forward. But it's the while loop that doesn't come to an end (charBuf doesn't change and will not become 0) and in the second iteration n will be 1 initially (due to n++ at the end of the for loop). That causes the overflow at right[n] += charBuf[i];.
So: remove the while loop (and use strtok()).


text:
Using a level converter to adjust the voltage levels
we are currently working on a device that needs us to connect an sd card reader to 2 Arduino’s ( Uno and zero) , however, we just found that it is not possible to do so without a level converter , may we have some help about how to do the proper connection from the sd ( that is already connected to arduino zero) to the level converter and then to the Uno. We want to make sure that both microcontrollers work at the same voltage of 3.3V. The Arduino Uno works at 5V whereas the Zero works at 3.3V which is why we need the level converter

You want to have two devices talking to the same SD card? At the same time? You can't.

Actually they have to talk to the sd card one after another, one should get the data first and then the other one should transfer it.

if one after another can be avoided with one device telling the other to write for it, it might simplify things.

Could you please explain your idea clearly..

A circuit diagram and a better description of the objective would help in providing answers. It sounds like you have one MCU with an SD card, and a second one without. You want to connect the second MCU and have them both access the SD card? I suggest splitting up all the work and designing a modular approach to who is doing what. In hardware I’ve found devices like Pololu 2595 Logic level shifters useful and easy to connect. I suggest avoiding attempting to have two devices sequentially writing directly to one SD card, rather having one MCU coordinate the SD I/O for all of them.

Two devices writing to one SD card like they have exclusive access, without very strict arbitration to control which device is writing or reading which part of the card, will corrupt the file system on the card very quickly. It’s much simpler and safer to have one “master” like @RowanP suggested.

Think of it like a network. You have one USB hard drive, but two computers. You plug the hard drive in to one computer and share the filesystem across the network to the other computer. You don't plug the hard drive into both computers. That is what you need to do with your SD card. You connect it to one MCU then "share" it with the other one through some other communication medium (network, serial, I2C, whatever is most suitable for your usage).

That’s what we exactly thinking about and what led us to the idea of using a level converter or shifter, the level converter has Tx and Rx pins , through these pins we’re planning to take data from the Arduino zero and send them to the Uno using the Rx, what do you think about the idea?

The level converter we currently planning to use is sparkfun 2 Channel 5V 3.3V I2C TTL Logic Level Converter Module

https://www.fruugo.eg/2-channel-5v-33v-i2c-ttl-logic-level-converter-module/p-52178967-105041923?language=en&ac=google&gclid=CjwKCAjwr56IBhAvEiwA1fuqGhTPCLet8h74pZrUWV_CKpYDl20vlOBIhPEua3GKtN1ljVWm-dfoZxoCtisQAvD_BwE


text:
Signal clipping in Arduino Serial Plotter
I would like to understand why did Arduino clipped the input signal as shown in the attached diagram? As far as I know, Arduinos are able to read analogue voltages up to 5v, that is 1023. But for some reason my signal got clipped at 390 which is about 1.90V. What may be the reason behind this? The schematic is also attached. The low voltage input signal (mV range) is passed through a Band pass filter with a gain of 143. The signal is then DC shifted by +3.3/2=1.65V by using a capacitor coupled voltage divider offset. The opamp LM358 (not LT1215 shown in the schematic) and everything else is powered from Arduino's built in 3.3V regulator. One reason might be that the opamp can't spit out anything more than its supply voltage, that is 3.3V, but even then the clipping should take place at 675 (1023*3.3/5), not 390. Am I missing something??
Thank you for reading my question. Any help is highly appreciated ^_^.
Serial Plotter:

Schematic:

LM358 is not rail-to-rail IO. You will never be able to get anything even close to 3.3V out of it.

So this is an opamp issue correct?? When 5V was supplied, clipping occurred at 600. Might have to change the opamp then, or decrease the gain of my signal??

Yep. Choose something that was designed sometime in the last 30 years.

The OPA342 or one of its derivatives might do what you want. You should read the data sheet to be sure it will do what you want.