text:
Serial connection between arduino and processing doesn't work; Port busy
I'm trying to connect arduino and processing via serial. Whenever I run the processing sketch I get the following error in Processing:
RuntimeException: Error opening serial port COM26: Port busy
Could not run the sketch (Target VM failed to initialize).

Below is the arduino sketch and processing code, which I "borrowed" from here, to try to programmatically find the correct serial port to connect to.
Arduino:
int var;

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

void loop() {
  if (Serial.available()) {
    var = Serial.read();
  }
  Serial.println(var);
  delay(100);
}

Processing:
import processing.serial.*;

Serial ser_port;                // for serial port
PFont fnt;                      // for font
int num_ports;
boolean device_detected = false;
String[] port_list;
String detected_port = "";

void setup() {
  size(400, 200);                         // size of application window
  background(0);                          // black background
  fnt = createFont("Arial", 16, true);    // font displayed in window

  println(Serial.list());

  // get the number of detected serial ports
  num_ports = Serial.list().length;
  // save the current list of serial ports
  port_list = new String[num_ports];
  for (int i = 0; i < num_ports; i++) {
    port_list[i] = Serial.list()[i];
  }
}

void draw()
{
  background(0);
  // display instructions to user
  textFont(fnt, 14);
  text("1. Arduino or serial device must be unplugged.", 20, 30);
  text("   (unplug device and restart this application if not)", 20, 50);
  text("2. Plug the Arduino or serial device into a USB port.", 20, 80);

  // see if Arduino or serial device was plugged in
  if ((Serial.list().length > num_ports) && !device_detected) {
    device_detected = true;
    // determine which port the device was plugged into
    boolean str_match = false;
    if (num_ports == 0) {
      detected_port = Serial.list()[0];
    } else {
      // go through the current port list
      for (int i = 0; i < Serial.list().length; i++) {
        // go through the saved port list
        for (int j = 0; j < num_ports; j++) {
          if (Serial.list()[i].equals(port_list[j])) {
            break;
          }
          if (j == (num_ports - 1)) {
            str_match = true;
            detected_port = Serial.list()[i];
          }
        }
      }
    }
  }
  // calculate and display serial port name
  if (device_detected) {
    text("Device detected:", 20, 110);
    textFont(fnt, 18);
    text(detected_port, 20, 150);
    ser_port = new Serial(this, detected_port, 9600);
  }
}

I am a newbie at this, so not sure what I'm doing wrong. Would appreciate any help :)

Have you checked manually if COM26 is actually the COM port of your Arduino? Does the communication work with the Serial Monitor?

You should probably set detected port when it's found rather than doing it after the loop if nothing else, and I'd recommend getting the serial list only once before the loop instead of three times. This might not solve the problem, but it's certainly more deterministic.

The port it's finding is the correct one. However, I haven't been able to make the communication work. It's saying the port is busy. I'm using an Arduino nano every. @DaveNewton You're saying I should set the serial port, directly after finding it, rather than wait to do it in the if device detected function? For the 2nd point, I'm not sure the code would work if I only check once, since I won't be able to programmatically find the com port the Arduino is on, if I only check once.

And can you connect with the Serial Monitor to that port? Is there some other program open that uses that port?

I tried a simple app, where I manually set the port. Processing is not giving me any errors and supposed to be writing to the Arduino. And if I try to open the serial monitor, while the app is running it's saying the port is busy. However, the variable in the Arduino sketch is not updating.

The question meant can you connect to the Arduino with anything else not while the program is running, e.g., does it work at all. My point about detection is that as soon as there’s a not-matching serial port in the loop you can stop checking—you know the index of the newly-plugged device’s serial port.

The IDE connects with it as normal. Processing does not work as expected. Not sure with what else to try? Re: detection - I see, I'll try to simplify the code.

I tried your Processing sketch, and it does detect and try to connect to the serial port, but fails for some reason.
Processing "code" can include a try catch block to help you diagnose the issue. Using this modified sketch, you can print the errors to the console window.
import processing.serial.*;

Serial ser_port;                // for serial port
PFont fnt;                      // for font
int num_ports;
boolean device_detected = false;
String[] port_list;
String detected_port = "";

void setup() {
  size(400, 200);                         // size of application window
  background(0);                          // black background
  fnt = createFont("Arial", 16, true);    // font displayed in window

  println(Serial.list());

  // get the number of detected serial ports
  num_ports = Serial.list().length;
  // save the current list of serial ports
  port_list = new String[num_ports];
  for (int i = 0; i < num_ports; i++) {
    port_list[i] = Serial.list()[i];
  }
}

void draw()
{
  background(0);
  // display instructions to user
  textFont(fnt, 14);
  text("1. Arduino or serial device must be unplugged.", 20, 30);
  text("   (unplug device and restart this application if not)", 20, 50);
  text("2. Plug the Arduino or serial device into a USB port.", 20, 80);

  // see if Arduino or serial device was plugged in
  if ((Serial.list().length > num_ports) && !device_detected) {
    device_detected = true;
    // determine which port the device was plugged into
    boolean str_match = false;
    if (num_ports == 0) {
      detected_port = Serial.list()[0];
    } else {
      // go through the current port list
      for (int i = 0; i < Serial.list().length; i++) {
        // go through the saved port list
        for (int j = 0; j < num_ports; j++) {
          if (Serial.list()[i].equals(port_list[j])) {
            break;
          }
          if (j == (num_ports - 1)) {
            str_match = true;
            detected_port = Serial.list()[i];
          }
        }
      }
    }
  }
  else{
    text("else", 20, 110);
  }
  // calculate and display serial port name
  if (device_detected) {
    text("Device detected:", 20, 110);
    textFont(fnt, 18);
    text(detected_port, 20, 150);
    try{
      ser_port = new Serial(this, detected_port, 9600);
    }
    catch(Exception e){
      // Print detailed error information to the console.
      System.err.println(e);
      e.printStackTrace();
    }
  }
  else{
    text("Device NOT detected:", 20, 140);
  }
}

These are the errors I get on my computer using a Arduino Uno.
    at processing.serial.Serial.<init>(Unknown Source)
    at processing.serial.Serial.<init>(Unknown Source)
    at sketch_211210a.draw(sketch_211210a.java:85)
    at processing.core.PApplet.handleDraw(PApplet.java:2475)
    at processing.awt.PSurfaceAWT$12.callDraw(PSurfaceAWT.java:1547)
    at processing.core.PSurfaceNone$AnimationThread.run(PSurfaceNone.java:313)
java.lang.RuntimeException: Error opening serial port /dev/tty.wchusbserial620: Port busy
java.lang.RuntimeException: Error opening serial port /dev/tty.wchusbserial620: Port busy

Another issue is with this part of the code: if (device_detected). The draw() function is like the Arduino loop() function in that it keeps looping through the code. It is repeatedly trying to make a new serial connection to the same port, which MAY explain why the Port busy error message is repeated in the console error messages.
Using Processing IDE 3.5.3, there is a errors tab at the bottom of the console window. I am getting 2 errors there which don't seem to be involved with the port connection issue.
If you install the controlP5 library in the Processing IDE, you can use this port testing sketch to see the Port ID change every time you create a new connection with it. I suspect your sketch may connect to the Arduino the first time through the draw() function, then it keeps trying to connect to the same port which is busy.
// Serial port(s) connection tester. Processing version 3.5.3.
// For a list of all the ScrollableList Controller methods available,
// use: "ControlP5.printPublicMethodsFor(ScrollableList.class);"
// to print the entire list of the 165 functions to the console.
import controlP5.*;
import java.util.*;
import processing.serial.*;

ControlP5 cp5;
Serial myPort;
Textlabel outputWindowLine1, outputWindowLine2;
String portName;

void setup(){

  size(500, 431);

  // Use a font larger than the default "6px".
  ControlFont font = new ControlFont(createFont("Verdana", 14));

  // ALL CAPS is the default font for the control. Why?
  Label.setUpperCaseDefault(false);

  // Configure a controlP5 ScrollableList.
  cp5 = new ControlP5(this);
  cp5.addScrollableList("dropdown")
    .setPosition(0, 50)
    .setSize(500, 400)
    .setBarHeight(50)
    .setItemHeight(30)
    .setFont(font)
    .addItems(GetSerialPortList())
    .setType(ScrollableList.LIST)
    .setLabel("--- Click on a port name to try and connect to it ---")
    ;

  outputWindowLine1 = cp5.addTextlabel("outputWindowLine1Label")
    .setText("The list of port names is \"scrollable\".")
    .setPosition(0, 0)
    .setColorValue(0)
    .setFont(font)
    ;

  outputWindowLine2 = cp5.addTextlabel("outputWindowLine2Label")
    .setText("Press any character on the keyboard to reload the list.")
    .setPosition(0, 25)
    .setColorValue(0)
    .setFont(font)
    ;
}

void draw(){
  background(255);
}

// User selects a drop down item. Works like a JavaScript onChange()
// event, except you can click on the same item multiple times, this
// code will execute again on each mouse "click" of the same item.
void dropdown(int n){

  // Create a serial connection and send some
  // chars to the "USB to Serial Converter".
  try{

    // Get the port name.
    portName = Serial.list()[n];

    // If you don't do this, you can't re-connect to the same port again.
    // Re-connecting to the same port gives you a new "myPort ID" and may
    // take a few seconds.
    if(myPort != null){
      myPort.clear();
      myPort.stop();
    }

    // Create a Serial Port connection.
    myPort = new Serial(this, portName, 9600);

    // User message.
    outputWindowLine1.setText("Connected to portName: " + portName);
    outputWindowLine2.setText("myPort = " + myPort);

  }
  catch(Exception e){

    // User message.
    outputWindowLine1.setText("Error connecting to portName: " + portName);
    outputWindowLine2.setText("");

    // Print detailed error information to the console.
    System.err.println(e);
    e.printStackTrace();
  }
}

// Refresh the dropdown list of serial port names.
void keyPressed(){
  cp5.get(ScrollableList.class, "dropdown").setItems(GetSerialPortList());
  outputWindowLine1.setText("Serial port list refreshed!");
  outputWindowLine2.setText("");
}

// Get a List of the serial port names.
List GetSerialPortList(){
  List serialPortList = Arrays.asList(Serial.list());
  return serialPortList;
}

thank you very much for your detailed response. I'll take the time tomorrow to go through it, and digest. And I will post on here again. Have a good evening.

I've decided to make a new post, since the error seems to be more basic/something else, and it feels like it would be more harm than good to try to edit this post.


text:
Code to display binary value from 1 hall sensor A3144 connected with shift register 74HC165 when magnet is brought near to it or taken away?

I have checked my connections and when I bring a magnet close to the hall sensors the voltage on them which is apprx. 4.5V becomes 0V and when I remove the magnet the sensor turns back to 4.5V. This means that all the hall sensors are responding to the magnets which makes my connections alright. I want to get 0 when magnet is brought closer to the sensor and 1 when taken away.
The below code shows 11111111 continuously and does not get affected even if magnet is brought close or taken away. I expected the code to show 00000000 until magnet is brought closer to any sensor. If magnet is brought closer to 1st sensor, it should have shown 10000000 and so forth.
int load = 7;
int clockEnablePin = 4;
int dataIn = 5;
int clockIn = 6;

void setup() {
Serial.begin(9600);
pinMode(load, OUTPUT);
pinMode(clockEnablePin, OUTPUT);
pinMode(clockIn, OUTPUT);
pinMode(dataIn, INPUT);
digitalWrite(clockEnablePin, LOW);
digitalWrite(clockIn, LOW);
}

void loop() {

//Write pulse to load pin
digitalWrite(load, LOW);
digitalWrite(load, HIGH);

//Get data from 74HC165
byte incoming = shiftIn(dataIn, clockIn, LSBFIRST);

// Print to serial monitor
Serial.print("Pin States: \r\n");
Serial.println(incoming, BIN);
delay(200);
}

uint8_t shiftIn(uint8_t dataIn, uint8_t clockIn, uint8_t bitOrder) {
uint8_t value = 0;
uint8_t i;
for (i = 0; i < 8; ++i)
{
 digitalWrite(clockIn, HIGH);
 if (bitOrder == LSBFIRST)
 {
  value |= digitalRead(dataIn) << i;
 }
 else
 {
  value |= digitalRead(dataIn) << (7 - i);
 }
 digitalWrite(clockIn, LOW);
}
return value;
}

The code as well as the schematic is correct. The problem was with shift register. Thank you everyone for your suggestions.

The wiring seems good to me. The code seems to be from here, which I used before myself (though I have the clock inhibit pin hardwired). Does it work when you test the shift register without the sensors but with buttons or wires?

The connections are correct in the above diagram. I have had a terrible experience with non working shift register. Some 74HC165 don't work properly(might be duplicate). So, try buying from a verified store.
Use this code to get HIGH or LOW value as output. You can change them to 1 or 0 as per your requirement.
I used this code and it works perfect with 8 Hall switches connected to one shift register 74HC165. Don't forget to connect your pins with your Arduino Uno as depicted in the code or you can update your code as per your connections of shift register with Arduino Uno. You can increase the number of inputs by adding more shift register 74HC165 to the circuit & also you just need to update the value of number of shift chips in the below code.
/* How many shift register chips are daisy-chained.
*/
#define NUMBER_OF_SHIFT_CHIPS   1

/* Width of data (how many ext lines).
*/
#define DATA_WIDTH   NUMBER_OF_SHIFT_CHIPS * 8

/* Width of pulse to trigger the shift register to read and latch.
*/
#define PULSE_WIDTH_USEC   5

/* Optional delay between shift register reads.
*/
#define POLL_DELAY_MSEC   1

/* You will need to change the "int" to "long" If the
 * NUMBER_OF_SHIFT_CHIPS is higher than 2.
*/
#define BYTES_VAL_T unsigned int

int ploadPin        = 7;  // Connects to Parallel load pin the 165
int clockEnablePin  = 4;  // Connects to Clock Enable pin the 165
int dataPin         = 5; // Connects to the Q7 pin the 165
int clockPin        = 6; // Connects to the Clock pin the 165

BYTES_VAL_T pinValues;
BYTES_VAL_T oldPinValues;

/* This function is essentially a "shift-in" routine reading the
 * serial Data from the shift register chips and representing
 * the state of those pins in an unsigned integer (or long).
*/
BYTES_VAL_T read_shift_regs()
{
    long bitVal;
    BYTES_VAL_T bytesVal = 0;

    /* Trigger a parallel Load to latch the state of the data lines,
    */
    digitalWrite(clockEnablePin, HIGH);
    digitalWrite(ploadPin, LOW);
    delayMicroseconds(PULSE_WIDTH_USEC);
    digitalWrite(ploadPin, HIGH);
    digitalWrite(clockEnablePin, LOW);

    /* Loop to read each bit value from the serial out line
     * of the SN74HC165N.
    */
    for(int i = 0; i < DATA_WIDTH; i++)
    {
        bitVal = digitalRead(dataPin);

        /* Set the corresponding bit in bytesVal.
        */
        bytesVal |= (bitVal << ((DATA_WIDTH-1) - i));

        /* Pulse the Clock (rising edge shifts the next bit).
        */
        digitalWrite(clockPin, HIGH);
        delayMicroseconds(PULSE_WIDTH_USEC);
        digitalWrite(clockPin, LOW);
    }

    return(bytesVal);
}

/* Dump the list of zones along with their current status.
*/
void display_pin_values()
{
    Serial.print("Pin States:\r\n");

    for(int i = 0; i < DATA_WIDTH; i++)
    {
        Serial.print("  Pin-");
        Serial.print(i);
        Serial.print(": ");

        if((pinValues >> i) & 1)
            Serial.print("HIGH");
        else
            Serial.print("LOW");

        Serial.print("\r\n");
    }

    Serial.print("\r\n");
}

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

    /* Initialize our digital pins...
    */
    pinMode(ploadPin, OUTPUT);
    pinMode(clockEnablePin, OUTPUT);
    pinMode(clockPin, OUTPUT);
    pinMode(dataPin, INPUT);

    digitalWrite(clockPin, LOW);
    digitalWrite(ploadPin, HIGH);

    /* Read in and display the pin states at startup.
    */
    pinValues = read_shift_regs();
    display_pin_values();
    oldPinValues = pinValues;
}

void loop()
{
    /* Read the state of all zones.
    */
    pinValues = read_shift_regs();

    /* If there was a chage in state, display which ones changed.
    */
    if(pinValues != oldPinValues)
    {
        Serial.print("*Pin value change detected*\r\n");
        display_pin_values();
        oldPinValues = pinValues;
    }

    delay(POLL_DELAY_MSEC);
}

Preset your clockIn and clockEnablePin pins to LOW in the setup function. Do not manipulate them in the loop function. You do not need to use the delayMicroseconds() functions because the 74HC165 is a great deal faster than Arduino read/write functions.

You might want to write your own shiftin() function since the QH needs to be sampled before the first clock pulse.

source: Stack Exchange

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

sort: votes


text:
Serial communication with 2 Arduinos and one optocoupler
I just started working with Arduinos on Tinkercad in a school assignment and have non preexisting electrical knowledge. Tried to read up on the subject and I think I've gotten some of the facts straight but i still can't get them to communicate when using the optocoupler. It works fine with the code if i connect them to each other directly with the tx/rx pins.
//Sender code
char string[5] = {'h', 'e', 'l', 'l', 'o'};
void setup()
{
  Serial.begin(9600);
}
void loop()
{
  Serial.write(string,5);
  delay(1000);
}

//Reciving arduino code

char text[10];

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

void loop()
{
  Serial.readBytes(text,5);
  Serial.println(text);
  delay(1000);
}

My guess is I've done something wrong connecting the receiving Arduino but i can't find whats wrong. Any feedback is immensely appreciated!

How about the schematic? You could invert the signal, or it's connected in a way that even 9600 bauds/s are too fast for it

Try this as you have a logic inversion. If the Arduino is connected to the cathode, connect it to the anode or visa versa. This will cause a double logic inversion and get the signals back to working.

Here is a diagram that I would suggest you to to try it out. The transmitting Arduino pin will turn the internal infrared LED on or off depend on the whether the pin is at LOW or HIGH. When the infrared LED is on, it will turn on the phototransistor, and produce a LOW at the receiving arduino pin.
The LED is optional but it gives you a visual clue on whether you are receiving the data or not.

simulate this circuit – Schematic created using CircuitLab

EDIT: Even though the OP may be long gone, I wanted to finish what I started with my response.

This circuit works fine for me using two UNOs (and one UNO and a serial board for a PC). It is, essentially, the same as in the first response by @hcheung. I used 4.7K and 10K for R2/R4 and they worked fine. I tested it using this program running on both UNOs.
    #include <SoftwareSerial.h>

SoftwareSerial SSerial(4,5); // RX, TX

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

}

void loop() {
  // display whatever comes in through software serial on the Arduino monitor
  if(SSerial.available()) {
    Serial.write(SSerial.read());
  }
  // send whatever comes in on serial to software serial
  if(Serial.available()) {
    SSerial.write(Serial.read());
  }
}

Note that the programs use software serial and both Tx and Rx are isolated.
If you use this for the hardware serial port on two UNOs, take care. First, don't hang things on 0/1 until after the program loads and how much you can get away with is unclear to me.
Second, if you use a simple program like this, on both UNOs, you will quickly see that the first bytes sent will ping-pong and causes problems.
    void setup() {
  Serial.begin(9600);
}

void loop() {
  if(Serial.available()){
    Serial.write(Serial.read());
  }
}

I note that the OP was only using one end.
Personally, I found several junk box 4N25s that would not work - that took me a bit of time to figure out. Finally, I don't see the point of optically isolating two UNOs as I did for example, but that is another story.
______ older msg is below _______________________________
A typical way of doing this is illustrated here .

// *** I am leaving my original text below, but I want to back off of this a bit. I spent a few hours on this today and I am not happy with the results or my understanding. If I come to any worthwhile conclusions, I will post them. I do like getting to the bottom of things, but I was premature. It is simply not working the way I would expect when I get into 9600 speed and I need to investigate further. Yes, I am accounting for the UNO 0&1 involvement with USB.
// ***
The advantage is that you will not be inverting the line on the receiving end. The choice of R1 and R2 is important. I used R1=330 and R2=1K and transmission was fine at 9600 using a junk box 4N25. My testing was with a single UNO and after uploading a simple program.
See https://github.com/pepaslabs/Electronics/wiki/Designing-a-TTL-Serial-Opto-isolator for a good discussion on exactly this topic.
PS: As mentioned you should have submitted a schematic and you could have used a meter to see what voltages you were getting - those are good steps to understanding things.

You connected Uno2 RX connecting to GND in your diagram.

@hcheung Yes, thanks - very sloppy of me - corrected

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


text:
Question about ElapsedMillis() library and state machines
I'm making a sort of state machine with 3 states, and I'm actually doing some tests by configuring at the start of my code state=3. I've wired on each pin 2 leds, for a total of 12 leds. I'm using elapsedMillis library (https://github.com/pfeerick/elapsedMillis)  to make things a bit more easy and I'm stuck at 3rd state. At the 3rd state I would like that each couple of leds will stay on for 90ms, than goes of for 1ms. elapsedMillis library allows one to do something like that:
elapsedMillis timeElapsed; //declare global if you don't want it reset every time loop runs
#include "elapsedMillis.h"

const int pin0 = 12;
const int pin1 = 11;
const int pin2 = 10;
const int pin3 = 9;
const int pin4 = 8;
const int pin5 = 7;

unsigned long t1 = 500;
unsigned long waiting = 1000;
unsigned long t2 = 100;
unsigned long t3 = 50;
unsigned long t4 = 1;
unsigned long t5 = 90;
unsigned long startTime = 0;

int ledArray[] = {pin0, pin1, pin2, pin3, pin4, pin5};
int j, k, a, c = 0;
int state = 3;

elapsedMillis elapsedTime;
elapsedMillis timer1;
elapsedMillis timer2;
elapsedMillis timer3;
elapsedMillis timer4;
elapsedMillis timer5;

void setup() {
  pinMode(pin0, OUTPUT);
  pinMode(pin1, OUTPUT);
  pinMode(pin2, OUTPUT);
  pinMode(pin3, OUTPUT);
  pinMode(pin4, OUTPUT);
  pinMode(pin5, OUTPUT);
  Serial.begin(9600);

}

void loop() {

  switch (state) {

    case 0:
      // led accesi in modo scalare allo stato 0
      while (k <= 5)
      {

        if (timer1 >= t1)
        {
          if (j <= 5)
          {
            digitalWrite(ledArray[j], HIGH);
            j++;
            timer1 = 0;

          }
          k++;
          elapsedTime = 0;
        }

      }
      // attendo 1s poi vado allo stato 1

      if (elapsedTime >= waiting) {
        state = 1;
        elapsedTime = 0;
      }

      break;

    case 1:

      // led spenti rapidamente in modo scalare

      while (k >= 0) {
        if (timer2 >= t2)
        {
          if (j >= 0)
          {
            digitalWrite(ledArray[j], LOW);
            j--;
            timer2 = 0;
          }
          k--;
          elapsedTime = 0;
        }
      }
      // attendo 0.1s
      if (elapsedTime >= t2) {
        state = 2;

      }
      break;

    case 2:

      // led fade per 3 volte
      if (c <= 3)
      {
        while (a <= 255)
        {
          if (timer3 >= t3) {
            analogWrite(ledArray[3], a);
            timer3 = 0;
            a += 10;

          }

        }
        while (a >= 0)
        {
          if (timer3 >= t3) {
            analogWrite(ledArray[3], a);
            timer3 = 0;
            a -= 10;
          }
        }
        c++;
      }
      else {
        state = 3;
      }

      break;

    case 3:

      if (timer4 >= t5) {
        if (j <= 5) {
          digitalWrite(ledArray[j], HIGH);
          j++;
          timer4 = 0;
          if (timer5 >= t4) {
              digitalWrite(ledArray[j], LOW);
              timer5 = 0;
            }
          }
        }
      break;
  }
}

case 3:

  for (int ii = 0; ii <= 5; ii++)
  {
    digitalWrite(ledArray[ii], ( (ii == j) && (timer4 < 90)));
  }

  if (timer4 > 91) {
    j += backwardScan ? -1 : 1 ;
    if (j > 5) {
      backwardScan = 1;
      j = 5;
    }
    if (j < 0) {
      backwardScan = 0;
      j = 0;
    }
    timer4 = 0;
  }
  break;

For the state3 I would like an effect like the "KITT" knight rider car in 80s TV show. Each couple of 2 leds should move back and forth... in shortly: first 2 leds stays on 90ms and 1ms off, then second 2 leds on 90ms and 1ms off.. etc...
It seems like the leds in the array goes on all together.

And what exactly is the actual problem? Please give a detailed description. Also: How are you seeing if it works? 1ms is too short of a pause to see with the human eye

For the state3 I would like an effect like the "KITT" knight rider car in 80s TV show. Each couple of 2 leds should move back and forth... in shortly: first 2 leds stays on 90ms and 1ms off, then second 2 leds on 90ms and 1ms off.. etc...

And what is the problem with your code? What exactly does it do different than expected? Please don't let us guess

seems like the leds in the array goes on all together

Guessing about case 3-- State variable j is which pair of leds to light, and.....Not sure... No state for back and forth, timing state is the diff between timer4 and timer5?  I'd guess you need another state variable to remember whether you are moving "back" or "forth".  In general with state machine logic, you should be able to identify exactly which state you are in, set the outputs accordingly, and then transition or not to the next state.  For instance, your code should be able to recognize how to set the KITT leds for the "middle pair, scanning forth-wards, on, 33ms to go" state.

Yes in state 3, variable j is to keep track of which pair of leds are you in, but my actual problem is how to have a led on for 90ms and 1ms off by using the timer4 and timer5 if needed. I have t4 that is variable for 90ms led ON and t5 that is led off for 1ms

... You could handle the on & Xms to go state with the state of a timer, with for(int ii=0,ii<=5,ii++){digitalWrite(edArray[ii],( (ii==j) && (timer4 <90) }} and then whenever if(timer4>91), update  backwards, jandtimer4` to the appropriate next state.

mmmh sorry I can't read this well...

You need to maintain more state information to have 'case 3' work like a KITT-style back and forth LED scanner. I think you can do it with three state variables, j for which pair of LEDs is active, backwardsScan to say which way to go, and timer4 to remember where in the 91ms cycle we are with the active pair of LEDs.
Try something like this:
...
int backwardsScan = 0;
...

case 3: // KITT-like scanning back and forth 90us/1us
  // j remembers which LED pair is active
  // backwardsScan remembers which direction to scan
  // timer4 handles the 90ms/1ms on-off cycle.
  //
  // reset output leds appropriately for (j,timer4):
  for(int ii=0;ii<=5;ii++){
    digitalWrite(ledArray[ii],( (ii==j) && (timer4 <90)));
  }
  // update KITT state based on (j,backwardsScan,timer4)
  if(timer4 > 91){
     j += backwardsScan? -1 : 1 ;
     if (j > 5){
        backwardsScan = 1;
        j = 5;
        }
     if (j < 0) {
        backwardsScan = 0;
        j = 0;
        }
     timer4 = 0;
     }

  break;

The main trick with state machines is being able to fully determine the complete state from what you are keeping track of--It should be memoryless, in that the state variable(s) fully specify the state, and you don't need to remember the prior state.  If you find you need to know more than one thing, you might need a vector or set of state variables.  One could map the whole led-backwardsScan-timer4 state vector into a single state variable (timer4, modulo 182ms for example,) but that would be unnecessarily complicated. Recognizing all the variables required to fully specify the state is important.

I noticed you write: "backwardsScan?" and the digitalWrite is not clear for me...

The  ( backwardsScan ? -1 : 1 ) is the ternary operator https://en.wikipedia.org/wiki/%3F:  If  backwardsScan is true, it delivers the first value, -1  or if false, it delivers the second value +1.

I had to change this: for(int ii=0,ii<=5,ii++) with ";" not ,

The logic in the digitalWrite only writes HIGH to the active LED in the sub 90ms timer4  time, and LOW to all the other LEDs and to the active LED after 90ms.

I have lot of errors, trying now to fix the code...


text:
Serial connection between Processing and Arduino doesn't work
I'm trying to connect an Arduino Nano Every and Processing via serial. I'm getting no errors on either side, and the arduino serial functionality works otherwise on the arduino IDE.
I'm connecting on the right port, and the port is busy while the processing code is running (as you would expect), however, the variable inside the arduino is not updating. In fact, the whole if serial.available statement is not executing.
Arduino:
int var;

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

void loop() {
  if (Serial.available()) {
    var = Serial.read();
  }
  Serial.println(var);
  delay(100);
}

Processing:
import processing.serial.*;

// The serial port
Serial myPort;

void setup() {
  // List all the available serial ports:
  printArray(Serial.list());
  // open port
  myPort = new Serial(this, Serial.list()[2], 9600);
}

void draw() {
  try {
    myPort.write(1);
  }
  catch(Exception e) {
    // Print detailed error information to the console.
    System.err.println(e);
    e.printStackTrace();
  }
  delay(50);
}

PS. Asked moderator to close previous post on topic.

How do you know that it doesn't work? I don't see you reading anything from the serial interface in the processing sketch. What are you actually seeing?

I read the variable in the arduino IDE serial monitor, after waiting a few seconds and stopping the processing app. If the processing app successfully writes to the arduino, then var = 1, however, it's = 0.

how would you ever know the value of var?

I print it on the serial monitor in arduino IDE. Am I missing sth fundamental?

I'm not sure how it is with the Nano Every, but other Arduinos reset every time that you reopen the serial port. And that happens when you close the processing program and open the Serial Monitor. If that is also the case with the Nano Every, then you cannot every get anything other than zero, because the value send by the processing sketch is already forgotten due to the reset of the Arduino. You would need to read and print from serial inside your processing sketch

Thanks for the comment Chris. But wouldn't the variable be updated and stay updated? So it gets set to a value, and even if there is no serial open it should stay at the value it was set? My understanding is, I'm sending a value with my processing code to the arduino, and storing that value in a variable. Then, I close down serial connection with processing and try to read the value of the variable. However, the variable has not been updated as I would expect it to.

Most Arduinos (and the Nano Every is one of them) will reset when the serial connection is reopened (You close it by closing the processing sketch and open it again with the Serial Monitor). Variables are stored in RAM, which gets wiped and reinitialized after a reset or power loss.
So this basically happens: You send the data from processing over serial to the Arduino. The Arduino puts the received value into the variable in its RAM. Then you close the processing sketch, effectively closing the serial connection. Then you open the Serial Monitor, which opens the serial connection again. This triggers the reset of the Arduino and wipes the previous variable value from the RAM. You will only ever see the initial variable value (zero) this way.
You can prevent a reset over serial if you connect a capacitor between the Reset pin and ground.
Though I would say this is probably not what you really should do. Instead just read the data from serial inside your processing sketch. After you have read it you can print it.

As a side note: The reset-on-serial-reconnect functionality is used for programming the Arduino over serial (through the USB cable). The new program is written into the program memory (flash) by the bootloader. The bootloader runs directly after a reset/power-on. So to upload a new program to the Arduino the Arduino IDE has to first reset the Arduino to talk to the bootloader.

Well this is something I would have never thought to consider. Thank you so much, Chris. I was completely stuck here!

I suppose this reset only happens if you open/close the serial connection from the PC. Since repeatedly opening and closing the serial monitor from the IDE doesn't cause the same reset?

If you open your Processing sketch and send the data to the Arduino without opening the serial monitor in the Arduino IDE, the data gets through. Here is your Arduino sketch which is slightly modified. Disclaimer - tested on an Uno.
There are other options for serial monitors which may work (varies by OS), as well as other options to interface between Processing and Arduino, such as Firmata
int var;

void setup() {
  Serial.begin(9600);
  pinMode(2, OUTPUT);
  digitalWrite(2, LOW);
}

void loop() {
  if (Serial.available()) {
    var = Serial.read();
    digitalWrite(2, HIGH);
    delay(50);
    digitalWrite(2, LOW);
  }
  Serial.println(var);
  delay(100);
}

EDIT
Arduino IDE version 1.0.6.2 with Processing 2.2-ish would let you open the serial monitor in the Arduino IDE and "monitor" the data. Since you can't do this anymore, what about making your Processing app open 2 windows. One window could be a home brewed serial monitor, and the other the sketch you are working on. Using Processing version 3.5.3, it is only 15 lines of code to open up 2 windows. I'm sure the actual implementation of such a system would be a good challenge.

@Zhelyazko Grudov - Another way to open 2 windows: https://gist.github.com/atduskgreg/666e46c8408e2a33b09a Just copy and paste both sketches into ONE sketch and try it :)

Thanks @ve7JRO for the answer. I think the issue was what Chris mentioned below with the reset. However, this is very useful information for debugging, so thank you for sharing.


text:
RFM69 Sending Failure
Hi I'm trying to get the RFM69 rf module to work on an arduino uno.
Here is my code:
#include <SPI.h>
// Addresses for this node. CHANGE THESE FOR EACH NODE!
#define NETWORKID     0   // Must be the same for all nodes (0 to 255)
#define MYNODEID      2   // My node ID (0 to 255)
#define TONODEID      1   // Destination node ID (0 to 254, 255 = broadcast)
// RFM69 frequency, uncomment the frequency of your module:
//#define FREQUENCY   RF69_433MHZ
#define FREQUENCY     RF69_915MHZ

// Create a library object for our RFM69HCW module:
RFM69 radio;

void setup()
{
  // Open a serial port so we can send keystrokes to the module:
  Serial.begin(9600);
  Serial.print("Node ");
  Serial.print(MYNODEID,DEC);
  Serial.println(" ready");

   if(radio.initialize(FREQUENCY, MYNODEID, NETWORKID))
     Serial.println("Initialized Successful");

  radio.setHighPower(); // Always use this for RFM69HCW
}

void loop()
{
     bool test = radio.sendWithRetry(TONODEID, "Hi", 2);
    Serial.println(test);
}

which outputs
Node 2 Ready
Initialization Successful
Node 2 Ready
Initialization Successful

which means that the sendWithRetry function is not returning a bool as expected, but I can't figure out why.
I am using the code given in the github
https://github.com/sparkfun/RFM69HCW_Breakout/blob/master/Libraries/Arduino/RFM69/RFM69.cpp which shows the nitty gritty of the RF69 Module and its arduino code.
I hooked up the hardware according to
https://learn.sparkfun.com/tutorials/rfm69hcw-hookup-guide/all
and checked all the wiring, so the I concluded that the problem was software based.
Any ideas why this isn't working?


text:
Issues with the TX pins for recieving data from the HM19 and HC05
I bought a hm19 (link 2), 2 hc05s, an Arduino micro, and an Arduino due. I'm trying to turn an led on and off using my phone over Bluetooth. I verified that all modules work by themselves. So here's my issue.
First is that the Hc05 (link 1 below) modules simply do not respond to any AT command at all but work for serial communication. I have tried shorting a pin to send it into AT mode but that just made it impossible for me to communicate with it since I cannot get any input on my desktop using an USB cable from the Bluetooth module which brings me to the second issue.
Second is that I can send inputs from the serial monitor from my desktop to my phone but i cannot send data from my phone to my desktop. I have tracked this issue down to being in between the Bluetooth module and the Arduino. I have strong reasons to believe that DSD tech (hm19) have mislabled their bluetooth module because plugging rx into rx, tx to tx, gnd to gnd, and vcc to 5v works while flipping the rx and tx pins gives me a weird format.
Is there anyway I can fix the second issue preferably so i can diagnose the first one myself?
Link 1: https://www.amazon.com/gp/product/B07C1PXM44/ref=ppx_yo_dt_b_asin_title_o01_s00?ie=UTF8&psc=1
Link 2: https://www.amazon.com/gp/product/B07MBLVHH8/ref=ppx_yo_dt_b_asin_title_o04_s00?ie=UTF8&psc=1
Connecting RX to TX and TX to RX

Connecting RX to RX and TX to TX

All inputs were "1" and were sent from my desktop to my phone
here's the code run using an Arduino DUE with the TX0 and RX0 pins
char inputByte;
void setup() {
 Serial.begin(9600);
 pinMode(13,OUTPUT);

}

void loop() {
while(Serial.available()>0){
  inputByte= Serial.read();
  Serial.println(inputByte);
  if (inputByte=='Z'){
  digitalWrite(13,HIGH);
  }
  else if (inputByte=='z'){
  digitalWrite(13,LOW);
  }
  }
}

Have you read this HC-05 "how-to" or an equivalent? When I last used an HC-05, this is what I needed to get it going.


text:
Stepper motor with microstep driver
In my project I have to control a stepper motor using arduino and microstep driver, can I control the motor so that it can move 90 degrees then stop for like a second and then move again and repeat that sequence.
Can I do that please help I'm stuck in the code and I couldn't figure it out.

In what code are you stuck? You didn't provide any in your question. If you already have a code, then include it in the question. If not: Have you tried the examples with one of the Arduino stepper libraries (like Stepper or Accelstepper)? Have you tried to understand how they work? If you have problems understanding them: What exactly gives you problems here? We need more information to provide good answers.

Yes I tried with a bunch of code this one work the best for my stepper: https://drive.google.com/file/d/12Esu1wzS0HfXB_lRHbog6yM09OSJ5SSu/view

Of course you can! There are some excellent libraries to control steppers, e.g. Stepper or AccelStepper.
What you describe sounds like basic task that is covered in examples of these libraries. For example, this one: https://github.com/arduino-libraries/Stepper/blob/master/examples/stepper_oneRevolution/stepper_oneRevolution.ino. You only need to set correct pins and tweak delays and rotation angles (if your stepper has 200 steps per revolution, then 90 degrees is 50 steps).

This code is working well for me what could I change to get the motion needed https://drive.google.com/file/d/12Esu1wzS0HfXB_lRHbog6yM09OSJ5SSu/view

What to do with that particular code is a whole different question to what was initially asked. That said, your code looks fine, it probably does 2 revolutions continuously (depends on motor). To change that to 90 deg with pause, change 400 to 50 and add delay(1000); to loop. Also, as others noted, you need to understand your code to make it work, there is no other way.

Thanks I understand it now and It's working. I'm a beginner when it comes to programming, I tried a lot of codes from AccelStepper and other libraries none has worked for me so, I was frustrated and I wrote the question in a hurry. sorry for that and thank you again for the help.


text:
ESP32: spi_master: check_trans_valid(801) when using SPI
I use the following code to communicate with a display:
void Display_HandleDC(spi_transaction_t* p_Transaction)
{
    gpio_set_level((gpio_num_t)LCD_DC, (uint32_t)p_Transaction->user);
}

static void Display_SendCommand(const uint8_t Command)
{
    spi_transaction_t t;

    memset(&t, 0, sizeof(t));

    t.length = 8;
    t.tx_buffer = &Command;
    t.user=(void*)0;

    assert(spi_device_polling_transmit(_SPI, &t) == ESP_OK);
}

static void Display_SendData(const uint8_t* p_Data, uint32_t Length)
{
    spi_transaction_t t;

    if(Length == 0)
    {
        return;
    }

    memset(&t, 0, sizeof(t));

    t.length = Length * 8;
    t.tx_buffer = p_Data;
    t.user=(void*)1;

    assert(spi_device_polling_transmit(_SPI, &t) == ESP_OK);
}

static uint32_t Display_ReadID(void)
{
    spi_transaction_t t;

    Display_SendCommand(0x04);

    memset(&t, 0, sizeof(t));
    t.length = 4 * 8;
    t.flags = SPI_TRANS_USE_RXDATA;
    t.user = (void*)1;

    assert(spi_device_polling_transmit(_SPI, &t) == ESP_OK);

    return *(uint32_t*)t.rx_data;
}

static void Display_Write(int ypos, uint16_t *linedata)
{
    static spi_transaction_t trans[6];

    for(uint8_t x=0; x<6; x++)
    {
        memset(&trans[x], 0, sizeof(spi_transaction_t));
        if ((x&1)==0) {
            //Even transfers are commands
            trans[x].length=8;
            trans[x].user=(void*)0;
        } else {
            //Odd transfers are data
            trans[x].length=8*4;
            trans[x].user=(void*)1;
        }

        trans[x].flags = SPI_TRANS_USE_TXDATA;
    }

    trans[0].tx_data[0] = 0x2A;
    trans[1].tx_data[0] = 0;
    trans[1].tx_data[1] = 0;
    trans[1].tx_data[2] = 320 >> 8;
    trans[1].tx_data[3] = 320 & 0xFF;

    trans[2].tx_data[0] = 0x2B;
    trans[3].tx_data[0] = ypos >> 8;
    trans[3].tx_data[1] = ypos & 0xFF;
    trans[3].tx_data[2] = (ypos + 1) >> 8;
    trans[3].tx_data[3] = (ypos + 1) & 0xFF;

    // Write the data to memory
    trans[4].tx_data[0] = 0x2C;
    trans[5].tx_buffer = linedata;
    trans[5].length = 320 * sizeof(uint16_t) * 8;
    trans[5].flags = 0x00;

    for(uint8_t x = 0; x<6; x++)
    {
        assert(spi_device_queue_trans(_SPI, &trans[x], portMAX_DELAY) == ESP_OK);
    }
}

static void Display_Busy(void)
{
    spi_transaction_t* rtrans;
    for(uint8_t x=0; x<6; x++)
    {
        assert(spi_device_get_trans_result(_SPI, &rtrans, portMAX_DELAY) == ESP_OK);
    }
}

esp_err_t Display_Init(void)
{
    static uint16_t* Line;

    gpio_set_direction((gpio_num_t)LCD_DC, GPIO_MODE_OUTPUT);
    gpio_set_direction((gpio_num_t)LDC_RESET, GPIO_MODE_OUTPUT);
    gpio_set_direction((gpio_num_t)LCD_BACKLIGHT, GPIO_MODE_OUTPUT);

    if((spi_bus_initialize(HSPI_HOST, &_BusCfg, 0) != ESP_OK) || (spi_bus_add_device(HSPI_HOST, &_DevDcfg, &_SPI) != ESP_OK))
    {
        return ESP_FAIL;
    }

    Display_Reset();
    ESP_LOGI(TAG, "ID: %08X", Display_ReadID());

    uint32_t Commands = sizeof(_Init_Cmd_List) / sizeof(_Init_Cmd_List[0]);
    ESP_LOGI(TAG, "Loading initialization commands: %u", Commands);

    for(uint32_t i = 0x00; i < Commands; i++)
    {
        ESP_LOGI(TAG, "     Command %u / %u", i + 1, Commands);
        Display_SendCommand(_Init_Cmd_List[i].Command);
        Display_SendData(_Init_Cmd_List[i].Data, _Init_Cmd_List[i].Length & 0x1F);
        if(_Init_Cmd_List[i].Length & 0x80)
        {
            vTaskDelay(100 / portTICK_RATE_MS);
        }
    }

    Line = (uint16_t*)heap_caps_malloc(320 * sizeof(uint16_t), MALLOC_CAP_DMA);
    if(Line == NULL)
    {
        return ESP_FAIL;
    }

    for(uint32_t i = 0x00; i < 320; i++)
    {
        Line[i] = 0xF8;
    }

    Display_Write(0, Line);
    Display_Busy();
    free(Line);

    return ESP_OK;
}

And this code results in the following error message:
E (1833) spi_master: check_trans_valid(801): txdata transfer > host maximum
assertion "spi_device_queue_trans(_SPI, &trans[x], portMAX_DELAY) == ESP_OK" failed: file "src/Peripherals/Display/display.cpp", line 225, function: void Display_Write(int, uint16_t*)
abort() was called at PC 0x400e47a4 on core 1

ELF file SHA256: bc86d952445723b2

Backtrace: 0x4008e8c0:0x3ffb4b30 0x4008ecb9:0x3ffb4b50 0x400e47a4:0x3ffb4b70 0x400d170d:0x3ffb4ba0 0x400d1873:0x3ffb4bc0 0x400d13ea:0x3ffb4bf0 0x400d194b:0x3ffb4c20 0x40088601:0x3ffb4c40
  #0  0x4008e8c0:0x3ffb4b30 in invoke_abort at .platformio\packages\framework-espidf@3.40001.200521\components\esp32/panic.c:155
  #1  0x4008ecb9:0x3ffb4b50 in abort at .platformio\packages\framework-espidf@3.40001.200521\components\esp32/panic.c:172
  #2  0x400e47a4:0x3ffb4b70 in __assert_func at /builds/idf/crosstool-NG/.build/HOST-i686-w64-mingw32/xtensa-esp32-elf/src/newlib/newlib/libc/stdlib/assert.c:62 (discriminator 8)
  #3  0x400d170d:0x3ffb4ba0 in Display_Write(int, unsigned short*) at src/Peripherals/Display/display.cpp:225 (discriminator 1)
  #4  0x400d1873:0x3ffb4bc0 in Display_Init() at src/Peripherals/Display/display.cpp:288
  #5  0x400d13ea:0x3ffb4bf0 in setup() at src/Application/application.cpp:21
  #6  0x400d194b:0x3ffb4c20 in applicationTask(void*) at src/main.cpp:41
  #7  0x40088601:0x3ffb4c40 in vPortTaskWrapper at .platformio\packages\framework-espidf@3.40001.200521\components\freertos/port.c:143

But the error doesn´t occur when I change the DMA channel from 0 to 1:
if((spi_bus_initialize(HSPI_HOST, &_BusCfg, 1) != ESP_OK) || (spi_bus_add_device(HSPI_HOST, &_DevDcfg, &_SPI) != ESP_OK))
{
    return ESP_FAIL;
}

What´s the difference between both channels and why is only channel 1 working?

Your code initializes the SPI bus by calling the spi_bus_initialize(HSPI_HOST, &_BusCfg, 0) function. The last argument of this function (int dma_chan) defines the DMA channel to use, which can be 0, 1 or 2.
Selecting DMA channel "0" will actually not select a DMA channel at all (which is explained in the Espressif documentation):

dma_chan: Either channel 1 or 2, or 0 in the case when no DMA is required. Selecting a DMA channel for a SPI bus allows transfers on the bus to have sizes only limited by the amount of internal memory. Selecting no DMA channel (by passing the value 0) limits the amount of bytes transfered to a maximum of 32.

The reason you get an error when your ESP32 tries to do an SPI transfer when no DMA channel is selected (option 0), is that the transfer apparently is larger than 32 bytes.
The error produced is "E (1833) spi_master: check_trans_valid(801): txdata transfer > host maximum", which reflects that.
The reason DMA channel 1 works correctly, is because that is an actual DMA channel and it has no limit on the amount of bytes transferred (only limited by the amount of internal memory).


text:
I am trying to add a countdown to my Arduino code but it does 0 days, 04:09:36 instead of starting at 7 days
The code I use probably has a math problem since an Arduino can only count a 16 bit integer. This problem is with the WeekDelay() function.
The project is for an Aerogarden. It pumps water into the garden every week from information based on my collected data. It writes on the LCD information like if it is pumping, waiting (it should have the timer here and display on the LCD), and it can show when it is going to pump with a beep warning. After beeping, pumping, and waiting for a few times I run out of information and do a loop and show a warning message, blinking the LCD and pumping a set amount.
More specifically WeekDelay() should be a delay for a week. It clears the LCD, Sets the cursor to 0,0 and prints "Waiting one week". It should then have a countdown of 24 hours on the screen and then just how many days it is waiting. It does that through clearing the LCD, Setting the cursor, printing days and waiting.
Because of the glitch it does not display any days even though it should show 7. It displays 04:09:36. Somebody was helping me out and said this:
Ah, it is the integer math interacting with the size of days. 04:09:36 = 43600+960+36 = 14976 which happens to be equal to 7243600 % 32768. See gammon.com.au/forum/?id=12146 and https://wiki.sei.cmu.edu/confluence/display/c/INT35-C.+Use+correct+integer+precisions for what's happening.
This is some cut-down version of my code:
int beeper_pin      = 2; //Naming buzzer pin
int resetGarden_pin = 3; //Naming the warning led pin
int pump_pin        = 6; //Naming the pump pin

#include <LiquidCrystal_I2C.h> // Driver Library for the LCD Module

LiquidCrystal_I2C lcd(0x27, A4, A5);

void clearLCDLine(int line)
{
  lcd.setCursor(0, line);
  for (int n = 0; n < 20; n++) // 20 indicates symbols in line. For 2x16 LCD write - 16
  {
    lcd.print(" ");
  }
}

void beepWarning() {            //Makes beeping a subroutine

  lcd.setCursor(0, 0);
  lcd.print("WARNING");
  delay(100);
  lcd.setCursor(0, 1);
  for (int x = 0; x < 3; x++) {

    lcd.setCursor(0, 1);
    lcd.print("WATER PUMP ACTIVE");
    delay(100);
    clearLCDLine(1);
    lcd.setCursor(0, 1);
    lcd.print("WATER PUMP ACTIVE.");
    delay(100);
    clearLCDLine(1);
    lcd.setCursor(0, 1);
    lcd.print("WATER PUMP ACTIVE..");
    delay(100);
    clearLCDLine(1);
    lcd.setCursor(0, 1);
    lcd.print("WATER PUMP ACTIVE...");
    delay(100);
    clearLCDLine(1);
  }

  lcd.setCursor(0, 1);
  lcd.print("WATER PUMP ACTIVE...");

  for (int x = 0; x < 3; x++) {   //Repeats 3 times

    digitalWrite(beeper_pin, HIGH); //Turn on buzzer
    delay(100);                     //Delay of 400 milliseconds
    digitalWrite(beeper_pin, LOW);  //Turns off buzzer
    delay(100);                     //Delay of 400 milliseconds

  }
}

void SOSWarning() {            //Makes SOS a subroutine

  clearLCDLine(1);
  lcd.setCursor(0, 0);
  lcd.print("WPA Reset Aerogarden");

  for (int x = 0; x < 3; x++) {   //Repeats 3 times

    for (int d = 0; d < 3; d++) {   //Repeats 3 times
      digitalWrite(beeper_pin, HIGH); //Turn on buzzer
      delay(200);                     //Delay of 400 milliseconds
      digitalWrite(beeper_pin, LOW);  //Turns off buzzer
      delay(200);                     //Delay of 400 milliseconds
    }

    for (int a = 0; a < 3; a++) {   //Repeats 3 times
      digitalWrite(beeper_pin, HIGH); //Turn on buzzer
      delay(400);                     //Delay of 400 milliseconds
      digitalWrite(beeper_pin, LOW);  //Turns off buzzer
      delay(400);                     //Delay of 400 milliseconds
    }

    for (int d = 0; d < 3; d++) {   //Repeats 3 times
      digitalWrite(beeper_pin, HIGH); //Turn on buzzer
      delay(200);                     //Delay of 400 milliseconds
      digitalWrite(beeper_pin, LOW);  //Turns off buzzer
      delay(200);                     //Delay of 400 milliseconds
    }

    delay(500);                     //Delay of 500 milliseconds
  }
}

void weekDelay() { //Makes waiting for a week a subroutine
  clearLCDLine(1);
  clearLCDLine(0);
  lcd.setCursor(0, 0);
  lcd.print("Waiting One Week");

  unsigned long start = millis();
  unsigned long week_secs = 7 * 24 * 3600;
  unsigned long countdowntime_seconds;

  while (countdowntime_seconds = week_secs - (millis() - start)/1000){
     char buff[80];
     int countdown_day = countdowntime_seconds / 3600 / 24;
     int countdown_hour = (countdowntime_seconds / 3600) % 24;
     int countdown_minute = ((countdowntime_seconds / 60) % 60);
     int countdown_sec = countdowntime_seconds % 60;
     sprintf(buff,"%1d days, %02d:%02d:%02d",
            countdown_day,
            countdown_hour,
            countdown_minute,
            countdown_sec
            );
     Serial.print(buff);
     clearLCDLine(1);
     lcd.setCursor(2, 1);
     lcd.print(buff);
     delay(1000);
     }
}

void pumpOn() {               //Makes turning on the pump a subroutine
  clearLCDLine(1);
  lcd.setCursor(0, 1);
  lcd.print("PUMPING");
  delay(100);
  digitalWrite(pump_pin, HIGH); //Turning on the pump
}

void pumpOff() {              //Makes turning off the pump a subroutine
  digitalWrite(pump_pin, LOW);  //Turning off the pump
  clearLCDLine(1);
  lcd.setCursor(0, 1);
  lcd.print("WATER PUMP OFF");
  delay(1000);
}

void setup() {
  //run once:
  lcd.backlight();
  lcd.init();

  lcd.setCursor(4, 0);//////////////////////////////////////////////////////
  lcd.print("HH:MM:SS"); //////////////////////////////////////////////////

  lcd.clear(); // Clear the screen
  lcd.setCursor(0, 0);
  lcd.print("Aero_Pump V3");
  delay(1000);
  lcd.setCursor(0, 1);
  lcd.print("By Alex");
  delay(1000);
  pinMode (beeper_pin,      OUTPUT); //Setting outputs
  pinMode (resetGarden_pin, OUTPUT); //Setting outputs
  pinMode (pump_pin,       OUTPUT); //Setting outputs
  lcd.clear(); // Clear the screen

  digitalWrite(resetGarden_pin, LOW); //Turning off the reset garden light

  beepWarning(); //Beeps a warning
  pumpOn();      //Turns on the pump
  delay(3000);  //Adds a delay of 24000 milliseconds
  pumpOff();     //Turns off the pump
  weekDelay();   //Waits a week

  beepWarning(); //Beeps a warning
  pumpOn();      //Turns on the pump
  delay(12000);  //Adds a delay of 24000 milliseconds
  pumpOff();     //Turns off the pump
  weekDelay();   //Waits a week
}

void loop() {

  SOSWarning(); //Beeps an SOS warning
  pumpOn();      //Turns on the pump
  delay(48000);  //Adds a delay of 48000 milliseconds
  pumpOff();     //Turns off the pump

  for (int x = 0; x < 3024000; x++) {
    lcd.backlight(); // turn on backlight.
    delay(100);
    lcd.noBacklight(); // turn off backlight
    delay(100);
  }
  lcd.backlight(); // turn on backlight.
}

This is the function that needs to be fixed:
void weekDelay() { //Makes waiting for a week a subroutine
  clearLCDLine(1);
  clearLCDLine(0);
  lcd.setCursor(0, 0);
  lcd.print("Waiting One Week");

  unsigned long start = millis();
  unsigned long week_secs = 7 * 24 * 3600;
  unsigned long countdowntime_seconds;

  while (countdowntime_seconds = week_secs - (millis() - start)/1000){
     char buff[80];
     int countdown_day = countdowntime_seconds / 3600 / 24;
     int countdown_hour = (countdowntime_seconds / 3600) % 24;
     int countdown_minute = ((countdowntime_seconds / 60) % 60);
     int countdown_sec = countdowntime_seconds % 60;
     sprintf(buff,"%1d days, %02d:%02d:%02d",
            countdown_day,
            countdown_hour,
            countdown_minute,
            countdown_sec
            );
     Serial.print(buff);
     clearLCDLine(1);
     lcd.setCursor(2, 1);
     lcd.print(buff);
     delay(1000);
     }
}

tip: do lcd.print("WATER PUMP ACTIVE"); ... delay(100); ... lcd.print("."); ... there is no need to clear LCD and print same line over and over

As the comment already tells, you are trying to calculate a constant with int literals that overflows:
unsigned long week_secs = 7 * 24 * 3600;
This is 604800 (0x93A80), but since ints are just signed 16 bits numbers (with your compiler system), only the lower 16 bits are taken into account. Fortunately these lower 16 bits are positive in two's complement, and so you get 14976 (hex 0x3A80).
The correct statement uses at least one unsigned long value, and the integer promotion rules make sure that all values are converted to that type, too.
unsigned long week_secs = 7UL * 24 * 3600;

I hope I see you in heaven. Thank you so much. This has taken so long to figure out.


text:
Random access to SD card using SD.h or another library (ESP32)
I'm trying to use a SD card with my ESP32 in order to save some variables in a txt file. Each variable uses 1 byte, so they can be represented by an 8 bit extended ASCII character.
The issue is it seems that the SD.h library has only 3 open modes (Read only, FILE_WRITE, FILE_APPEND), and I cannot figure out how to use random access for writing a specific byte of the file.
Imagine the situation: I have a file called myFile.txt which initially has a size of 5 bytes, and its content is:
abcde
The code I'm using is the following:
#include <SPI.h>
#include <SD.h>

#define SD_CS_PIN 5

File myFile;

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(115200);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

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

  if (!SD.begin(SD_CS_PIN)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");

  myFile = SD.open("/myFile.txt", FILE_WRITE);
  myFile.seek(3);
  myFile.write('a');
  myFile.close();

}

void loop() {}

But after running the code, the file has an unexpected behaviour, its size changes from 5 bytes to 4 bytes, and its content is:
abca
instead of the expected
abcae
I know it happens because when writing into the file I'm using the open mode FILE_WRITE which uses the FILE_APPEND mode internally, so when doing myFile.seek(3);, I'm truncating the file to 4 bytes since the FILE_APPEND mode needs to point to the end of the file.
So, my question is, how can I open a file in random access mode with SD.h, or another library?
Thanks in advance!

I would try to seek() to the end before close(). note: the SD library in ESP32 boards support package is different than the standard Arduino SD library.

@Juraj I tried it out but I got the same result, the first myFile.seek(3); truncates the file before.

Solved!
The solution was to migrate from the SD library to mySD, which seems to be a SdFat wrapper for ESP32.
You can see in the file mySD.h that the FILE_WRITE mode is defined as:
#define FILE_WRITE (F_READ | F_WRITE | F_CREAT)

Which means that it allows random access to the file for writing (F_WRITE instead of FILE_APPEND).
PS: I want to remark @Juraj comment since the forum is mainly for Arduino board questions

the SD library in ESP32 boards support package is different than the standard Arduino SD library


text:
220v lightbulb gradual dimmer
I am trying to turn my incandescent bulb gradually,say its brightness should  go from zero to 100% in 10 mins. In doing so I found the following code and it works well but it's not as gradual as I want so  I hope to achieve my goal by modifying it. I thought I could change the delay in void loop() and that's it! but doing so makes no significant result.
volatile int i=0;               // Variable to use as a counter volatile as it is in an interrupt
volatile boolean zero_cross=0;  // Boolean to store a "switch" to tell us if we have crossed zero
int AC_pin = 9;                // Output to Opto Triac
int dim_level = 0;                    // Dimming level (0-128)  0 = on, 128 = 0ff
int inc=1;                      // counting up or down, 1=up, -1=down

int freqStep =75;    // This is the delay-per-brightness step in microseconds.
                      // For 60 Hz it should be 65
// It is calculated based on the frequency of your voltage supply (50Hz or 60Hz)
// and the number of brightness steps you want.
//
// Realize that there are 2 zerocrossing per cycle. This means
// zero crossing happens at 120Hz for a 60Hz supply or 100Hz for a 50Hz supply.

// To calculate freqStep divide the length of one full half-wave of the power
// cycle (in microseconds) by the number of brightness steps.
//
// (120 Hz=8333uS) / 128 brightness steps = 65 uS / brightness step
// (100Hz=10000uS) / 128 steps = 75uS/step

void setup() {                                      // Begin setup
  pinMode(AC_pin, OUTPUT);                          // Set the Triac pin as output
  attachInterrupt(0, zero_cross_detect, RISING);    // Attach an Interupt to Pin 2 (interupt 0) for Zero Cross Detection
  Timer1.initialize(freqStep);                      // Initialize TimerOne library for the freq we need
  Timer1.attachInterrupt(dim_check, freqStep);
  // Use the TimerOne Library to attach an interrupt
  // to the function we use to check to see if it is
  // the right time to fire the triac.  This function
  // will now run every freqStep in microseconds.
}

void zero_cross_detect() {
  zero_cross = true;               // set the boolean to true to tell our dimming function that a zero cross has occured
  i=0;
  digitalWrite(AC_pin, LOW);       // turn off TRIAC (and AC)
}

// Turn on the TRIAC at the appropriate time
void dim_check() {
  if(zero_cross == true) {
    if(i>=dim_level) {
      digitalWrite(AC_pin, HIGH); // turn on light
      i=0;  // reset time step counter
      zero_cross = false; //reset zero cross detection
    }
    else {
      i++; // increment time step counter
    }
  }
}

void loop() {
  dim_level+=inc;
  if((dim_level>=128) || (dim_level<=0))
    inc*=-1;
  delay(600);
}

Edit 1: Working on  the first sketch suggested by Juraj, I put a light bulb as its load and because the period was initialized by FADE_MIN I expect the light should instantly glow in full brightness first and then gradually lose its brightness and so on, but it's not what happens and instead it takes some time to achieve its full brightness.

try my sketch https://arduino.stackexchange.com/questions/63631/fan-regulator-control-from-arduino/63674#63674

Right! I've just run it on Proteus , but it's not that clear to me. what is "FADE_MAX/MIN" for example? arbitrary chosen? what is happening in the void loop? and how to obtain the gradual fading in say 10 mins?

What delays did you try?  The vold loop(){...} code  makes 128 steps * 600ms = 76.8 sec, which is not close to the desired 10*60=600sec.  You probably want a delay(10*60 * 1000 / 128) (that's 4687ms per step) to make it 10 minutes one-way.   Also, how do you get 10000uS / 128 steps = 75uS/step?  I get 10000/128 = 78.

... and thirdly, the n/128 steps on an incandescent lamp probably don't map linearly to perceived brightness for a couple reasons: The power per unit time under the sine curve isn't uniform, and secondly the perceived brightness per incremental watt will change with temperature and wattage.  You might add an array mapping equal-sized perceptual steps to microseconds, using Juraj's 3rd example..

addressing Edit 1: try lower FADE_MIN value

I tried different amounts for delay and FADE_MIN and it still gradually goes high.


text:
HC-05 Bluetooth module; two serial ports, COM4 and COM5
I'm learning how to use the Arduino HC-05 Bluetooth module. After pairing to it with my laptop I saw that I was getting two serial links, COM4 and COM5, as can be seen from the picture below.
On COM4 everything is working fine, but on COM5 nothing is happening. Can somebody explain why this is so?
NOTE: I only have one Bluetooth device (the HC-05).

You didn't include a picture in your question

your question is not arduino specific ... it belongs at https://stackoverflow.com/questions

@chrisl sorry i forgot

@jsotola i chose that because its what am working with but all in all thank you.

do both serial ports appear when the module is paired? ... this is really a windows question, that is why I suggested SO

@jsotola they do, I have tried to uninstall both of them but once I just pair to the module they both appear. Am preparing to try on Ubuntu 20.04LTS and see what happens

this seems like a distraction from your arduino learning ... maybe accept it as a quirk of windows and maybe, some day, you will stumble across an answer

I found this answer in Microsoft Technet helpful:

when connecting your terminal program to the first you are actually instructing Windows to attempt to establish the Bluetooth connection to the remote paired device, and if the connection is established the RFCOMM channel will be opened for the exchange of data
when connecting your terminal program to the second you are actually instructing Windows to load the SPP SDP record and to remain waiting for incoming connections from the remote paired device.


text:
When using the IRremote library- why does it say 64 bits when after converting the hex to binary it comes out to be less?
I get this code output on my Serial when the IR receiver gets a signal:
Protocol  : GREE
Code      : 0x01C02350000000E0 (64 Bits)
Mesg Desc.: Model: 1 (YAW1F), Power: Off, Mode: 1 (Cool), Temp: 16C, Fan: 0 (Auto), Turbo: Off, Econo: Off, IFeel: Off, WiFi: Off, XFan: Off, Light: On, Sleep: Off, Swing(V) Mode: Manual, Swing(V): 0 (Last), Swing(H): 0 (Off), Timer: 23:00, Display Temp: 0 (Off)
uint16_t rawData[279] = {...

When I convert 0x01C02350000000E0 to binary, however, it usually comes out to less than 64 bits. I'm assuming it has to do with the parameters of my IR receiver and not normal.

sixteen hexadecimal digits equals 64 binary digits ... that is what fits into eight bytes of data ....... what binary number do you get from 0x01C02350000000E0?

I don't really understand the question. 0x01C02350000000E0 is a 16-digit hexadecimal number and so directly translates to 16x4 = 64 bits. What do you mean that it "usually" comes out as less than that? Do you not count the leading zeroes? They are bits as well.

When I convert 0x01C02350000000E0 to binary, however, it usually comes out to less than 64 bits is like saying when I add 2 plus 2, it usually comes out to 4 .... it either does, or it does not, there is no "usually"

You are confusing the data size and the value size.
Yes, your value can be represented using fewer than 64 bits, but the data size that is used to contain that value is 64 bits in size.
It's like saying that "4" is stored in a 6 digit storage space.  It only needs 1 storage slot, but the allocated space is 6 digits. So what is actually stored would be "000004".
As humans we tend to throw away the leading zeroes because they are meaningless. That's because we are able to use flexible storage sizes in our brains. The computer, though, works on fixed sizes - 8 bit, 16 bit, 32 bit, 64 bit, etc.
You can't store that value in a 32 bit variable, but you can in a 64 bit one. It may be wasteful for that specific value, but it's the smallest size that is available that is big enough.


text:
Digital Pins Question
I am new to the world of Arduino and need a little bit of help. I have an Arduino Uno and I am trying to supply 5V to an actuator using the digital pins. It is my understanding that the board I have is capable of doing that. But I can't seem to get 5V from my digital pins.
I would really prefer to not have to use the 5V power pin because I need to supply multiple sources with 5V in an alternating pattern, which I know I can do with the digital pins.
Could I use the analog pins to help with this? Could I supply more power using a battery? Etc.
Thank you in advance.

How much current?

Hi Edgar, I am not sure of the exact current. It is a shape memory alloy wire that I would like to actuate. It normally operates on 5V at 0.24 to 0.38 Amps. Thank you!

I can't seem to get 5V ... what does that mean? ... are you unsure if you get 5 V?

The digital pins of the Arduino are rated to reliably deliver up to
20 mA. Their absolute maximum rating is 40 mA. Anything
above that risks destroying the microcontroller.
If your device is supposed to pull from 0.24 to 0.38 A, that is too
much for your Arduino pins. With such a high current, you are seeing a
significant voltage drop caused by the internal resistance of the output
transistors. Or it could be that you already fried those transistors.

The most common solution is to use the digital output to turn on a MOSFET that supplies separate power to a high-current device that needs more current than the 20 mA that an ATmega328 microcontroller can safely supply.
The MOSFET is chosen based on the desired current and with the need for a logic-level input.
A typical circuit:

simulate this circuit – Schematic created using CircuitLab
D1 is needed for an inductive load like a motor. It protects other components.
You might get away without using the resistors (connecting D1 directly to the MOSFET's gate) but the 10 K "pull-down" resistor R1 ensures that the load is off when the Arduino is powering up. Resistor R2 is probably mainly useful for noisy or high-frequency applications..

Why an IRF530 instead of an IRL530?  Per Figures 1 of https://www.vishay.com/docs/91299/sihl530.pdf and https://www.vishay.com/docs/91019/irf530.pdf the IRL530 is more fully on at V_GS=5V and would do 10x the amps of the IRF530.

@DaveX: No reason other than that's what the diagram editor came up with and I forgot to remove :-)


text:
How to input delay and increase volume measurements with hall sensor detection
I'm writing code so that, every time a hall monitor senses, my code additively measures 5 liters of volume as it prints each detection. Then, this data is sent via Bluetooth to a phone. (This is for a tipping bucket device that distributes 5 liters of water every time it tips). However, my code keeps the volume measurement at 0.00 no matter how many times the hall effect is sensed, and I also can't figure out where to insert my delay statement so it does not double count the tips. Any suggestions?
int hall_pin = 2;

// set number of hall trips for RPM reading (higher improves accuracy)
float hall_thresh = 1000000000.0;

// BLE Battery Service
BLEService Vol_valServ("180F");

// BLE Battery Level Characteristic
BLEUnsignedCharCharacteristic VolumeChar("2A19",  // standard 16-bit characteristic UUID
        BLERead | BLENotify); // remote clients will be able to get notifications if this characteristic changes

long previousMillis = 0;  // last time the volume level was checked, in ms

void setup() {
    // initialize serial communication at 9600 bits per second:
    Serial.begin(9600);

    while (!Serial);

    pinMode(LED_BUILTIN, OUTPUT); // initialize the built-in LED pin to indicate when a central is connected

    // begin initialization
    if (!BLE.begin()) {
        Serial.println("starting BLE failed!");
        while (1);
    }

    /* Set a local name for the BLE device
       This name will appear in advertising packets
       and can be used by remote devices to identify this BLE device
       The name can be changed but maybe be truncated based on space left in advertisement packet
    */
    BLE.setLocalName("VolumeMonitor");
    BLE.setAdvertisedService(Vol_valServ); // add the service UUID
    Vol_valServ.addCharacteristic(VolumeChar); // add the battery level characteristic
    BLE.addService(Vol_valServ); // Add the battery service

    /* Start advertising BLE.  It will start continuously transmitting BLE
       advertising packets and will be visible to remote BLE central devices
       until it receives a new connection */

    // start advertising
    BLE.advertise();

    Serial.println("Bluetooth device active, waiting for connections...");
}

// the loop routine runs over and over again forever:
void loop() {
    // preallocate values for tach
    float hall_count = 1.0;
    float start = micros();
    bool on_state = false;

    // counting number of times the hall sensor is tripped
    // but without double counting during the same trip
    while (true) {
        if (digitalRead(hall_pin) == 0) {
            if (on_state == false) {
                on_state = true;
                hall_count += 1.0;
            }
        } else {
            on_state = false;
            float Volume = (hall_count - 1) * 5.0; // this is the liters per tip
            Serial.print(Volume);
            Serial.println(" Volume");

            // wait for a BLE central
            BLEDevice central = BLE.central();

            // if a central is connected to the peripheral:
            if (central) {
                Serial.print("Connected to central: ");
                // print the central's BT address:
                Serial.println(central.address());
                // turn on the LED to indicate the connection:
                digitalWrite(LED_BUILTIN, HIGH);

                while (central.connected()) {
                    long currentMillis = millis();
                    if (currentMillis - previousMillis >= 200) {
                        previousMillis = currentMillis;
                        Serial.print("Volume is now: ");
                        Serial.println(Volume);;
                    }
                }
                digitalWrite(LED_BUILTIN, LOW);
                Serial.print("Disconnected from central: ");
                Serial.println(central.address());
            }
            if (hall_count >= hall_thresh) {
                break;
            }

            // print information about Time and RPM
            float end_time = micros();
            float time_passed = ((end_time - start) / 1000000.0);
            Serial.print("Time Passed: ");
            Serial.print(time_passed);
            Serial.println("s");

            delay(10000);
            // delay in between reads for stability
        }
    }
}

The float hall_count = 1.0; is a local variable within the loop(){..} function.  To persist state between calls loop(), it needs to be either a global variable declared outside of loop(), or to be static inside the loop, as in static float hall_count = 1.0;


text:
LightBlue to Arduino connection log does not display serial monitor printed data
I'm writing code so that, every time a hall monitor senses, my code additively measures 5 liters of volume as it prints each detection. Then, this data is sent via Bluetooth to a phone. (This is for a tipping bucket device that distributes 5 liters of water every time it tips). I am using the LightBlue app for the bluetooth connection. My code connects to the bluetooth app, but the LightBlue log does not show what's being printed on my serial monitor. Does anyone have any suggestions?
    // https://makersportal.com/blog/2018/10/3/arduino-tachometer-using-a-hall-effect-sensor-to-measure-rotations-from-a-fan
#include <ArduinoBLE.h>
// digital pin 2 is the hall pin

int hall_pin = 2;

// set number of hall trips for RPM reading (higher improves accuracy)

float hall_thresh = 1000000000.0;

// BLE Battery Service
        BLEService Vol_valServ("180F");

        // BLE Battery Level Characteristic
        BLEUnsignedCharCharacteristic VolumeChar("2A19",  // standard 16-bit characteristic UUID
            BLERead | BLENotify); // remote clients will be able to get notifications if this characteristic changes

        long previousMillis = 0;  // last time the volume level was checked, in ms
void setup() {

  // initialize serial communication at 9600 bits per second:

  Serial.begin(9600);

   while (!Serial);

          pinMode(LED_BUILTIN, OUTPUT); // initialize the built-in LED pin to indicate when a central is connected

          // begin initialization
          if (!BLE.begin()) {
            Serial.println("starting BLE failed!");

            while (1);
          }

          /* Set a local name for the BLE device
             This name will appear in advertising packets
             and can be used by remote devices to identify this BLE device
             The name can be changed but maybe be truncated based on space left in advertisement packet
          */
          BLE.setLocalName("VolumeMonitor");
          BLE.setAdvertisedService(Vol_valServ); // add the service UUID
          Vol_valServ.addCharacteristic(VolumeChar); // add the battery level characteristic
          BLE.addService(Vol_valServ); // Add the battery service

          /* Start advertising BLE.  It will start continuously transmitting BLE
             advertising packets and will be visible to remote BLE central devices
             until it receives a new connection */

          // start advertising
          BLE.advertise();

          Serial.println("Bluetooth device active, waiting for connections...");

}

// the loop routine runs over and over again forever:

void loop() {

  // preallocate values for tach

  float hall_count = 0.0;

  float start = micros();

  bool on_state = false;

  // counting number of times the hall sensor is tripped

  // but without double counting during the same trip

  while (true) {

    if (digitalRead(hall_pin) == 0) {

      if (on_state == false) {

        on_state = true;

        hall_count += 1.0;

      }

    } else {

      on_state = false;
      float Volume = (hall_count) * 5.0; // this is the liters per tip

      Serial.print( "hall_count");
      Serial.print( hall_count);
      Serial.println(" Volume");
      Serial.print(Volume);

        // wait for a BLE central
        BLEDevice central = BLE.central();

        // if a central is connected to the peripheral:
        if (central) {
          Serial.print("Connected to central: ");
          // print the central's BT address:
          Serial.println(central.address());
          // turn on the LED to indicate the connection:
          digitalWrite(LED_BUILTIN, HIGH);

          while (central.connected()) {

if (digitalRead(hall_pin)==0){

if (on_state==false){

on_state = true;

hall_count+=1.0;

}

} else{

on_state = false;
float Volume = (hall_count)*5.0; // this is the liters per tip

Serial.println( Volume);

Serial.println("Volume");
VolumeChar.writeValue(Volume);

delay(2000);
        // delay in between reads for stability

            }
          }

          digitalWrite(LED_BUILTIN, LOW);
          Serial.print("Disconnected from central: ");
          Serial.println(central.address());

          }

          if (hall_count >= hall_thresh) {

            break;

          }

        // print information about Time and RPM

        float end_time = micros();

        float time_passed = ((end_time - start) / 1000000.0);

        Serial.print("Time Passed: ");

        Serial.print(time_passed);

        Serial.println("s");

delay(2000);
        // delay in between reads for stability
      }
    }
  }


text:
Arduino Nano 33 BLE Sense starts in bootloader mode on power up
I'm facing a lot of issues with Arduino Nano BLE Sense.
I'm aware about the port switching between bootloader (when the yellow LED pulses) and application.
First issue
Sometime when I power up the board (i.e. pluggin in the USB cable or turn on the PC) it starts in bootloader mode, even if there's a working sketch inside.
This is very bad, because I didn't find a way to recover from this situation without pressing the reset button, and of course this is not doable in a real environment.
Second issue
Even when it starts the application and I can successfully open the serial port, it does not receive or send any data. To recover, again, I need to press the reset button. The sketch is very simple and I also tried with default examples. Anyway, here how I open the serial port i Arduino:
void setup()
{
  Serial.begin(115200);
  while (!Serial);
  Serial.setTimeout(10);
  Serial.flush();
}

Please note, that once it starts in the correct way it works without any problem!
Questions:

is there a way to software reset the board to force the application to start when in bootloader mode? I tried with ard-reset-arduino.py --caterina /dev/ttyACM1 with no luck (i.e. it remains in bootloader mode).

do you have any suggestion how to avoid the serial issues I'm facing? I tried with several Arduino boards (I have 10 on my desk) and 3 different PCs.

Are you sure it's in bootloader mode and not just waiting for that while(!Serial) to become true? That will never happen until you open the serial port from the PC.

@PMF, even if I don't open the port on PC side usually the yellow LED is off (application mode). Sometimes instead it pulses on power up. Resetting the board leads to turn off the LED. Furthermore, when the LED pulses I can upload the firmware but I cannot exchange serial data with my application. When the LED is off I can (unless issue #2).

So, yes, I'm pretty sure it's in bootloader mode for issue #1.


text:
Is an ESP32 HTTP web server limited to a certain number of Base64 images?
This sketch only displays about nine images (when there are more). Does this mean the ESP32 is limited amount of Base64 images able to be displayed?
#include <WiFi.h>
#include <WebServer.h>

const char* ssid = "ESP32";
const char* password = "12345678";

IPAddress local_ip(192,168,1,1);
IPAddress gateway(192,168,1,1);
IPAddress subnet(255,255,255,0);

WebServer server(80);

// Used for determining the selected pattern and HTML to display:
int pattern = 0;
int selectedPattern = 0;

String circleString = "<img src=\"data:image/png;base64,[encoded data, 6912 characters]\" alt=\"NAME\" style=\"width:100%\">\n";

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

  WiFi.softAP(ssid, password);
  WiFi.softAPConfig(local_ip, gateway, subnet);
  delay(100);

  server.on("/", handle_OnConnect);
  server.onNotFound(handle_NotFound);

  server.begin();
  Serial.println("HTTP server started");
}
void loop()
{
  server.handleClient();

}

void handle_OnConnect() {

  server.send(200, "text/html", SendHTML(selectedPattern));
}

void handle_NotFound(){
  server.send(404, "text/plain", "Not found");
}

String SendHTML(int pattern)
{
    String ptr = "<!DOCTYPE html> \n";
    // Instance of class String (not a pointer)

    ptr += "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n";
    // <meta> viewport element makes the web page responsive in any web browser
    // https://www.w3schools.com/css/css_rwd_viewport.asp

    ptr += "\n";

    ptr +="\n";
    ptr +="\n";

      /*  */
      ptr += "
\n"; // 1
        ptr += circleString;
      ptr += "
\n";

      ptr +="1\n";

      ptr += "
\n"; // 2
        ptr += circleString;
      ptr += "
\n";

      ptr +="2\n";

      ptr += "
\n"; // 3
        ptr += circleString;
      ptr += "
\n";

      ptr +="3\n";

      ptr += "
\n"; // 4
        ptr += circleString;
      ptr += "
\n";

      ptr +="4\n";

      ptr += "
\n"; // 5
        ptr += circleString;
      ptr += "
\n";

      ptr +="5\n";

      ptr += "
\n"; // 6
        ptr += circleString;
      ptr += "
\n";

      ptr +="6\n";

      ptr += "
\n"; // 7
        ptr += circleString;
      ptr += "
\n";

      ptr +="7\n";

      ptr += "
\n"; // 8
        ptr += circleString;
      ptr += "
\n";

      ptr +="8\n";

      ptr += "
\n"; // 9
        ptr += circleString;
      ptr += "
\n";

      ptr +="9\n";

      ptr += "
\n"; // 10
        ptr += circleString;
      ptr += "
\n";

      ptr += "
\n"; // 11
        ptr += circleString;
      ptr += "
\n";

      ptr += "
\n"; // 12
        ptr += circleString;
      ptr += "
\n";

      ptr += "
\n"; // 13
        ptr += circleString;
      ptr += "
\n";

    ptr +="\n";
    ptr +="\n";

    return ptr;

}

Sketch uses 726230 bytes (55%) of program storage space. Maximum is 1310720 bytes.
Global variables use 39384 bytes (12%) of dynamic memory, leaving 288296 bytes for local variables. Maximum is 327680 bytes.

You are including the image raw data several times in the returned string. That could blow up the memory indeed. Why don't you just include a reference to the image in the html and supply the image separately?

Because I do not know how to do that. Also, I am not sure if it matters, but this minimal program uses one image, but the actual program uses all different images.

I would need to read the docs, too. You would need to convert the image back to binary and serve it directly. And then do something like server.on("/myimage.png", ServeImage(myimage.png)).

did you check the html source in the browser? I guess it is cut, because the esp fails to allocate more memory for the large String

You build up the HTML website by concatting strings together by hand in the code. I know this is done in many code throughout the internet, but this is only really practical, if you need to change the website content with every request. Normally it is better to use SPIFFS (or now LittleFS) to store the files and let a fitting webserver library serve them as static files. Additionally you are making Swiss cheese out of your heap memory when you concat String variables this often and you might run out of RAM.
I'm not used to LittleFS, so I will write this answer using SPIFFS. But I'm sure you can use LittleFS in a very similar way. I will leave it to you to determine how it fits in with code for SPIFFS.
Have a look at the ESPAsyncWebServer library and its simple server example. I've used this library for my projects. Try the examples, read the documentation and get an idea how this library is working.
Then have a look at the documentation where it says "Serving static files". I think you want to serve your static files from a directory. That way the library will look for requested files in that complete directory inside of the SPIFFS. Inside that directory you will have your HTML website (named as index.html) and all the images as binary data in a format, that a webbrowser can read (like jpg, png, ...). In your HTML website you reference the images with their path. Since in this scenario they all lie in the root directory the path is only the filename (+ the files extension).
When the webbrowser requests the index.html from the ESP, the library will serve it from SPIFFS. The webbrowser interprets the site and sees the references to the images. It than tries to load these images, meaning it sends requests to the ESP with the path of the images. The library will search for these files in SPIFFS, will find them and serve them to the webbrowser, who will then display them on the website.
Something like this:
#include "ESPAsyncWebServer.h"
#include "SPIFFS.h"

AsyncWebServer server(80);

void setup(){
  Serial.begin(115200);
  while(!SPIFFS.begin()){
    Serial.println("Could not mount SPIFFS");
    delay(500);
  }
  server.serveStatic("/", SPIFFS, "/").setDefaultFile("index.html");
  server.begin();
}

void loop(){
}

Note:

I've left out all Wifi related stuff. You need to add that yourself.
I've not tested this code, just put it together from one of my working bigger programs.
You still need to upload the actual files to the ESP SPIFFS. There are many tutorials on how to do that. Just place your files in the root directory of SPIFFS.

LittleFS vs SPIFFS docs are at https://github.com/esp8266/Arduino/blob/master/doc/filesystem.rst


text:
How to send non char variables over serial
I'm trying to build a GUI that sends the data from processing to arduino via serial. With the help of a couple of guys on here, I have come up with a basic framework that sends a variable ID, variable value and termination character (\n). So far so good!
However, the [arduino reference][1] advises to only use char for storing characters. How would I send a byte or int over serial, while still being able to use a termination character to ensure everything is working as expected?
edit:
Using the arduino code from Edgar's answer below and the following processing code, I get the "could not parse value" error.
import processing.serial.*;

SerialConnection serialConnection;

boolean data_processed = false;
char[] var_array = new char[31];
char var_id;
char var_val;
char space = ' ';
char termchar = '\n';

void setup() {
  serialConnection = new SerialConnection(this, 9600);
}

void draw() {
  serialConnection.startSerialCommunication();

  if (serialConnection.isReady) {
    var_id = 'a';
    var_val = 127;
    serialConnection.serialPort.write(var_id);
    serialConnection.serialPort.write(space);
    serialConnection.serialPort.write(var_val);
    serialConnection.serialPort.write(termchar);

    delay(50);
    while (serialConnection.serialPort.available() > 0) {
      for (int i = 0; i < 30; i++) {
        char inchar = serialConnection.serialPort.readChar();
        var_array[i] = inchar;
        print(var_array[i]);
      }
    }
  }
}

https://www.arduino.cc/reference/en/language/variables/data-types/char/

If you want to send numeric values to your Arduino, the simplest option
is to send them formatted as ASCII text. Thus you end up simply sending
characters.
Let's assume for example a simple text-based protocol of the form
foo 42
bar 5678
baz -12

Each message is made of a variable name followed by its numeric value.
The name and the value a separated by a space. Each message is
terminated by a line feed ('\n').
In order to parse a message, you first have to split it at the space
character. The strsep() function comes handy for this. Then,
you have to parse the second part of the message (the value) as an
integer. I would use strtol() for this job. Putting all
together:
void process(char *message) {
    char *name = strsep(&message, " ");  // split at the space
    if (!message) {
        Serial.println("Error: no value given");
        return;
    }
    char *endp;  // end of the numeric value
    long value = strtol(message, &endp, 0);
    if (endp == message) {
        Serial.println("Error: could not parse value");
        return;
    }
    /* Successfully parsed. */
    Serial.print(name);
    Serial.print(" received value ");
    Serial.println(value);
}

Note there are some sanity checks in order to make sure the message does
match the expected format. Obviously, you have to replace the last three
lines by something more meaningful to your application.
Example sketch using this:
void setup() {
    Serial.begin(9600);
}

void loop() {
    static char buffer[40];
    static size_t buffer_pos = 0;
    while (Serial.available()) {
        char c = Serial.read();
        if (c == '\n') {  // end of message
            buffer[buffer_pos] = '\0';  // terminate the string
            process(buffer);
            buffer_pos = 0;  // reset for next message
        } else if (buffer_pos < sizeof buffer - 1) {
            buffer[buffer_pos++] = c;  // buffer the character
        }
    }
}

Thank you for the answer, Edgar! Sorry for the delay in responding, wanted to go through everything. I really appreciate the code example. Also, didn't even know these functions existed. If I understand what's happening correctly, you're passing by address the buffer array to the process function, which dereferences it, and is then fed into the str functions? What confuses me is, it looks like the process function takes a single char as argument, but it actually processes the whole buffer array. Is that normal C behavior when using pointers to arrays, or is specific to the str.. functions?

Also these functions have double pointers. That's crazy.

Finally, I love how elegant this code is, lots to learn here!

@ZhelyazkoGrudov: Re “If I understand what's happening correctly, you're passing by address the buffer array”: Exactly. Whenever you pass an array to a function in C or C++, it “decays” to a pointer to its first element. This “decay to pointer” behavior is generic: it affects all arrays whenever you do mostly anything with them. The str*() functions all expect a pointer to the first element of a NUL-terminated array of char. What is specific about them is that they interpret the first null char they find as the end of the string.

Great to know! Thank you for the explanation.

Sorry to bother you again Edgar, I run into the "could not parse value" error, even though from what I understand I'm sending the data in the correct format. I edited the question to include the processing code I'm using.

@ZhelyazkoGrudov: Your Processing code is sending an escape character (ASCII code 127) instead of "127". The Arduino expects an ASCII string: try sending '1', then '2', then '7'. I don't know Processing, but it is more than likely that it has a method similar to Arduino's print() that would format a number in ASCII for you. You may then write something like serialConnection.serialPort.print(127);. I don't know the exact name of the method. If you have to ask, look for some forum relevant to Processing (not here).

Thank you very much for taking the time to respond again Edgar. I really, really appreciate it.


text:
Why does oscilloscope trigger look shaky when using delayMicroseconds?
I'm new to electronics but I have a Rigol DS1054Z oscilloscope and I'm experimenting to help learn.  I've created an incredibly simple sketch using an ESP32 and Arduino IDE:
void setup() {
  pinMode(32, OUTPUT);
}

void loop() {
  delayMicroseconds(10);
  digitalWrite(32, LOW);
  delayMicroseconds(10);
  digitalWrite(32, HIGH);
}

However, the square wave is incredibly "shaky" or unstable looking.  Why is that?

is it jitter? the code is not the right way to create a perfect wave.. try a PWM signal

@ArduinoFan: Yes, this is jitter.

Have you tried no interrupts to see if that fixes the problem? https://www.arduino.cc/reference/en/language/functions/interrupts/nointerrupts/  DSO "Trigger Mode" set to "Normal"?

See https://arduino.stackexchange.com/a/37393/6628

The display moving is what we call jitter. It is normal with the Arduino  and expected. The pulses are not even because of the background tasks such as the interrupt service routine (that does the millies etc whether you use them or not). When an interrupt occurs it causes the processor to stop, save its state, do a new task, then restore its state and continue. During the interrupt service routine (ISR) the processor uses time to execute instructions, this delay causes the jittering. Trust your scope, as usual it is correct. If you use one of the timer outputs the jitter will go away because they are not normally adjusted the just keep going. PWM is one of the more common modes of doing this but there are many others you can also use.

This isn't an answer, but you could compare it to hardware PWM to test the limits of the rest of the system.
Simple ESP32 PWM per https://www.electronicshub.org/esp32-pwm-tutorial/
int freq = 48000;
int ledChannel = 0;
int resolution = 8;  // 48000*2^8 < 80Mhz on channel 0 per https://www.electronicshub.org/esp32-pwm-tutorial/

void setup() {

  ledcSetup(ledChannel, freq, resolution);
  ledcAttachPin(32, ledChannel);
  ledcWrite(ledChannel, 127);
}

void loop() {
}

Jitter like that is usually caused by the different amount of time it takes to go through loop(). Remember that the tick timer takes time away from loop() at an interval that is not synchronized to the loop() time.


text:
Why do we add delay when using ultrasonic sensors?
I'm a beginner in Arduino and recently i got myself an Ultrasonic sensor (HC-SR04).
I looked up tutorials on how to measure distance with the sensor and the code I'm using is:
const int trigPin = 8;
const int echoPin = 7;

long duration;
int distance;

void setup() {
  // put your setup code here, to run once:
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2); //why do we delay 2 microseconds

  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10); //why do we delay 10 microseconds
  digitalWrite(trigPin, LOW);

  duration = pulseIn(echoPin, HIGH);
  distance = duration*0.034/2;
  Serial.print("Distance: ");
  Serial.println(distance);
}

I would like to know why do we add delays in the loop function? Appreciate if anyone could explain it.

please read the HC-SR04 datasheet ... https://cdn.sparkfun.com/datasheets/Sensors/Proximity/HCSR04.pdf

We need to provide the HC-SR04 with a fitting trigger signal. When you read the datasheet of the HC-SR04 you will see that it needs a 10us trigger pulse.
The first delay of 2us is to make sure we are at an established LOW level on the trigger pin, since the pin might have been HIGH before that. We are delaying here to make sure, that the HC-SR04 actually registered the level as LOW, even if it was HIGH before. If we would change from HIGH to LOW and back to HIGH as fast as we can, then the HC-SR04 might not have enough time to actually see the pin going low. Its mostly a measure to ensure the code working correctly here.
The second delay is for the actual trigger pulse. The datasheet specifies it as 10us length, so that is what we delay here. After that we go back to LOW to end the trigger pulse and wait for the echo pulse to come.
You might have read that it is bad to use delays in your code, since they are blocking. That is correct in principle, but normally really short delays in the microsecond range don't really matter for the program flow. Just be away to keep the total delay time in your code low enough to not miss any important events (like button presses).

The microsecond delays make sense but my library also has a 25 ms delay before returning. All the computation is done by this point, so it seems to be just a delay and 25 ms is a long time for a robot.

@user88094 You didn't specify what library you mean. Yes, without seeing the code and context I would also say, that a 25ms delay is not needed.