text:
Adding an Interrupt to ATtiny45 with Arduino
I recently wrote a simple script to...we'll say, "flash some LED's" and uploaded it to an attiny45. In short, the script cycles through 3 LED's and turns them on for a specified frequency, in a specified direction. With a button, I can cycle through different modes. There are 7 modes (default (LED's OFF), then 3 different speeds forwards and 3 different speeds backwards).
The script works fine-ish, however I've noticed that in order to read from the button input properly, the function that turns the LED's ON and OFF must be completed, meaning that for the longer cycles, the user may have to hold the button until the function completes. This is further complicated during the shorter cycles, where the input may detect multiple button-presses (despite adding a delay following the digital read.
NOTE: I could just make the delay longer, but this doesn't fix the issue during lower frequencies, when the function may take multiple seconds to complete.
I feel the best way to sort this (though I'd be open to other ideas) is to use the attachInterrupt() function; however, it doesn't work. The button no longer works and I'm not sure why.
// Pin Variables
int led1 = 2;
int led2 = 3;
int led3 = 4;
int leds[] = {led1, led2, led3};
int modePin = 0; // (physical pin 5 on the IC)

// Mode Speeds and setting
int fastTime = 100;
int mediumTime = 300;
int slowTime = 1000;
int offTime = 100;
int mode = 0;

void setup() {
  for (int i=0; i<3; i++){
    pinMode(leds[i], OUTPUT);
    digitalWrite(leds[i], LOW);
  }
  attachInterrupt(modePin, callMode, RISING);
}

void loop() {
  // If we get here, reset and go back to default (all LED's OFF)
  if (mode >= 7) {
    mode = 0;
  }
}

void callMode(){
  ++mode;
  //TIME: 1000, 300, 100 (milliseconds)
   switch (mode) {
     case 0:
       // Default, OFF
       for (int i=0; i<3; i++){
         digitalWrite(leds[i], LOW);
       }
       break;
     case 1:
       // Forward, Fast
       ledMode(fastTime, offTime, true);
       break;
     case 2:
       // Forward, Medium
       ledMode(mediumTime, offTime, true);
       break;
     case 3:
       // Forward, Slow
       ledMode(slowTime, offTime, true);
       break;
     case 4:
       // Backwards, Fast
       ledMode(fastTime, offTime, false);
       break;
     case 5:
       // Backwards, Medium
       ledMode(mediumTime, offTime, false);
       break;
     case 6:
       // Backwards, Slow
       ledMode(slowTime, offTime, false);
       break;
     case 7:
       // Return to Zero
       for (int i=0; i<3; i++){
          digitalWrite(leds[i], LOW);
       }
       mode = 0;
       break;
   }
}

void ledMode(int onTime, int offTime, bool forward){
  if (forward) {
    for (int i = 0; i <= 2; i++) {
      digitalWrite(leds[i], HIGH);
      delay(onTime);
      digitalWrite(leds[i], LOW);
      delay(offTime);
    }
  }
  else {
    for (int i = 2; i >= 0; i--) {
      digitalWrite(leds[i], HIGH);
      delay(onTime);
      digitalWrite(leds[i], LOW);
      delay(offTime);
    }
  }
}

NOTE: callMode() and ledMode() are only split up into different functions because I know that the function passed to attachInterrupt() cannot contain any delays(). So each time the button is pressed, the mode variable should increment and then the switch-statement should cause the next mode to run. When we reach 7, let's reset to zero and enter the default/OFF mode.
I've been racking my head for a few days on this and not sure what the problem is. Perhaps I can only use the attachInterrupt() function to some other pin? Perhaps I'm not using that function correctly?
Thank you in advance for any and all help you can provide.
-Joe

Re “I know that the function passed to attachInterrupt() cannot contain any delays()”: you should not call delay() from interrupt context. Whether delay() is called directly by the interrupt handler or indirectly through another function makes no difference. 2. Did you try the Blink Without Delay approach?

use callMode() to set a flag, such as nextSeq = true; ... in ledMode(), check for flag ... if (nextSeq)

@EdgarBonet I think that would be doable with a single LED, but not when I'm cycling through 3 of them. I'm attempting to adopt it now, but it's definitely proving to be tricky, to say the least

Interrupts are overkill for this kind of ultra-slow problems, and they
can introduce some extra complexity. Here the best solution seems (to me
at least) to lie in the approach of the Blink Without Delay
Arduino tutorial. Obviously, it must be adapted. In that tutorial, the
system switches between only two states (LED off or on). Here the
cycling of the LEDs goes through six phases:

all LEDs are off
LED[0] is on
all LEDs are off
LED[1] is on
all LEDs are off
LED[2] is on

The basic algorithm is the same: when millis() tells us it is time to
move to the next phase, we do so and update the state of the LEDs.
Note that I numbered the phases in such a way that the last bit
(phase&1) tells us whether an LED is on, and in that case the
remaining bits (phase>>1) hold the index of the LED that is on.
Here is how to cycle the LEDs at a fixed speed:
if (millis() - last_change >= phase_time) {
    last_change += phase_time;

    /* If an LED is on, turn it off. */
    if (phase & 1)
        digitalWrite(leds[phase >> 1], LOW);

    /* Move to the next phase. */
    if (++phase >= 6) phase = 0;

    /* Turn on the LED if needed. */
    if (phase & 1)
        digitalWrite(leds[phase >> 1], HIGH);
}

On top of this you need a finite state machine that cycles
between the different modes (speeds and directions). In order to avoid
code repetition, I would split this mode into a “state” that can OFF,
FORWARD or BACKWARDS, and an index into an array of delay times (with 0,
1, 2 meaning fast, medium and slow, respectively).
Putting it all together (warning: not tested):
const uint8_t leds[] = { 2, 3, 4 };
const uint32_t times[] = { 100, 300, 1000 };

void setup() {
    for (int i = 0; i < 3; i++)
        pinMode(leds[i], OUTPUT);
}

enum { OFF, FORWARD, BACKWARDS } state = OFF;  // global state
uint8_t time_idx;      // index in times[] (0 = fast)
int8_t phase;          // 0 = all off, 1 = led[0] on, 2 = all off...
uint32_t last_change;  // last time the phase changed

void loop() {

    /* Change mode on button press. */
    if (button_pressed()) {
        if (state == OFF) {
            state = FORWARD;
            time_idx = 0;  // start fast
        } else {
            time_idx++;    // slow down
            if (time_idx >= 3) {  // change direction or stop
                time_idx = 0;
                if (state == FORWARD)
                    state = BACKWARDS;
                else              // state is BACKWARDS
                    state = OFF;
            }
        }
    }

    /* Cycle the LEDs. */
    if (state != OFF && millis() - last_change >= times[time_idx]) {
        last_change += times[time_idx];

        /* If an LED is on, turn it off. */
        if (phase & 1)
            digitalWrite(leds[phase >> 1], LOW);

        /* Move to the next phase. */
        if (state == FORWARD) {
            if (++phase >= 6) phase = 0;
        } else {  // BACKWARDS
            if (--phase < 0) phase = 5;
        }

        /* Turn on the LED if needed. */
        if (phase & 1)
            digitalWrite(leds[phase >> 1], HIGH);
    }
}

I did not write the button_pressed() function, which is meant to
debounce the button and detect the “just pressed” transition. It is left
as an exercise to the reader (or you can just use a debouncing
library).

Thank you so much for your feedback! Just to close the loop here, I was about to implement this on my project, but then I had another idea. I reverted back to an older pre-interrupt version of the firmware and following a button-press, I simply added a 4-second delay. This requires the user to press-&-hold the button until a press is detected (never more than the length of the current cycle), but works fairly well for this purpose. In all cases, the user presses until the LED's stop and then releases. Works like a charm. Talk about a simple solution.


text:
Using ICSP pins as SPI in Arduino Due
I am using two RFID sensors operating on SPI with arduino Due. They will not be operating at the same time.
Is it favorable to use the ICSP pins as SPI pins for one of them, or use them in a one master two slaves configuration with the SPI header?

on Due there is no ICSP programming. those pins are only for SPI

The Due's SPI is odd, to say the least. From what I recall, it doesn't have multiple SPI ports. Instead it uses multiple hardware SS pins to look like multiple ports in hardware. Just stick to one channel with multiple slaves. The Due is just a mess. It's no wonder it got retired in short order...

@Majenko, Due is not retired

@Juraj They resurrected it?! Morons! The Due is the second worst Arduino of all time, only beaten by the Intel Galileo abortion.

source: Stack Exchange

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

sort: votes


text:
Loop one specific case inside of a switch
I want to loop one specific case inside of my switch, until the button gets pressed a second time. How can i make this work?
Code:
const int ledrood = 9;
const int ledgroen = 10;
const int ledblauw = 11;
const int buttonPreset = 2;
const int buttonMix = 4;
float sensorWaarde = 0;
int switchtel = 1;

int roodval;
int groenval;
int blauwval;
int buttonState = LOW;

void setup() {
Serial.begin(9600);
pinMode(ledrood, OUTPUT);
pinMode(ledgroen, OUTPUT);
pinMode(ledrood, OUTPUT);
pinMode(sensorWaarde, INPUT);
pinMode(buttonPreset, INPUT);
pinMode(buttonMix, INPUT);

}

void loop() {
int sensorWaarde = analogRead(A0);
buttonState = digitalRead(buttonMix);
if (buttonState == HIGH) {

delay(200);
switch (switchtel) {
  case 1:
  roodval = 255;
  roodval = sensorWaarde / 4;

    groenval = 0;
    blauwval = 0;
    analogWrite( ledgroen, groenval );
    analogWrite( ledrood, roodval );
    analogWrite( ledblauw, blauwval);
    Serial.println(roodval);
    switchtel = switchtel + 1;
    break;

  case 2:

    roodval = 0; // cyaan
    groenval = 255;
    blauwval = 255;
    analogWrite( ledgroen, groenval );
    analogWrite( ledrood, roodval );
    analogWrite( ledblauw, blauwval);
    Serial.println("2");
    switchtel = switchtel + 1;
    break;

  case 3:

    roodval = 255; // magenta
    groenval = 0;
    blauwval = 255;
    analogWrite( ledgroen, groenval );
    analogWrite( ledrood, roodval );
    analogWrite( ledblauw, blauwval);
    Serial.println("3");
    switchtel = switchtel + 1;
    break;
    switch (switchtel) {

    }
   }
 }
}

Start with the state change detection: https://www.arduino.cc/en/Tutorial/StateChangeDetection . Should there be a timeout for the second press of the button?

You need to split your cases into multiple parts.
For example, you have a case which sets up a mode, and a case that runs a mode, and if needed a case that finishes a mode.
For example:
switch (mode) {
    case 0: // Idle
        break;
    case 1: // Start - do whatever to set up the mode here
        redValue = 100;
        greenvalue = 200;
        mode = 2; // Switch to the next case
        break;
    case 2: // Run - this is the bit that repeats
        if (digitalRead(3) == HIGH) {
            mode = 3; // Finish it
        }
        // Do whatever for each loop here.
        break;
    case 3: // It is finished.
        redValue = 0;
        greenValue = 0;
        // etc.
        mode = 0; // Or whatever you want to do next
        break;
}

The key thing here is that case 1 is equivalent to a mini setup() and case 2 is equivalent to a mini loop(). You switch to case 1, which does the setup, and that case then switches to case 2, which it stays at until you tell it otherwise. That case will keep getting executed until you tell it to move to another case.

I want to loop one specific case inside of my switch, until the button gets pressed a second time. How can i make this work?

not sure why it needs to be anything more complicated than this:
  if (isPressed2x(btn)) do_something(); //if button is pressed twich, execute do_someting()

there are lots of ways to implement isPressed2x(). the simplest would be to use a static variable to keep track of it:
char isPressed2x(uint8_t btn) {
  static char cnt=0; //button press counter
  if (isPressed(btn)) {  //button is pressed
    cnt+=1; //increment counter
    if ((cnt&0x01) == 0) return 1; //button has been pressed twich
  }
  return 0; //button not pressed, or not pressed twice
}

similarly, isPressed(btn) can be implemented, with or without debouncing.
the key is to break down any task into small, simple and well defined blocks so when re-assembled together, those small, simple and well defined blocks can perform tasks as complicated as you wish them to be.
the alternative is to jumbo all of them into one routine, making it hard to understand, hard to debug and hard to port.

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


text:
How to loop a specific tone?
I am building a security system, and found the following code
#define NOOT_B0  31
#define NOOT_C1  33
#define NOOT_D1  37
#define NOOT_E1  41
#define NOOT_F1  44
#define NOOT_G1  49
#define NOOT_A1  55
#define NOOT_B1  62
#define NOOT_C2  65
#define NOOT_D2  73
#define NOOT_E2  82
#define NOOT_F2  87
#define NOOT_G2  98
#define NOOT_A2  110
#define NOOT_B2  123
#define NOOT_C3  131
#define NOOT_D3  147
#define NOOT_E3  165
#define NOOT_F3  175
#define NOOT_G3  196
#define NOOT_A3  220
#define NOOT_B3  247
#define NOOT_C4  262
#define NOOT_D4  294
#define NOOT_E4  330
#define NOOT_F4  349
#define NOOT_G4  392
#define NOOT_A4  440
#define NOOT_B4  494
#define NOOT_C5  523
#define NOOT_D5  587
#define NOOT_E5  659
#define NOOT_F5  698
#define NOOT_G5  784
#define NOOT_A5  880
#define NOOT_B5  988
#define NOOT_C6  1047
#define NOOT_D6  1175
#define NOOT_E6  1319
#define NOOT_F6  1397
#define NOOT_G6  1568
#define NOOT_A6  1760
#define NOOT_B6  1976
#define NOOT_C7  2093
#define NOOT_D7  2349
#define NOOT_E7  2637
#define NOOT_F7  2794
#define NOOT_G7  3136
#define NOOT_A7  3520
#define NOOT_B7  3951
#define NOOT_C8  4186
#define NOOT_D8  4699

 int melody[] = {
// NOOT_C4, NOOT_G3, NOOT_G3, NOOT_A3, NOOT_G3, 0, NOOT_B3, NOOT_C4
NOOT_D8, NOOT_D8, NOOT_D8, NOOT_D8, NOOT_D8, NOOT_D8
};
int NOOTDurations[] = {
 4, 4, 4, 4, 4, 4, 4, 4
 };
 void setup() {
    // iterate over the NOOTs of the melody:
  for (int thisNOOT = 0; thisNOOT < 8; thisNOOT++) {

// to calculate the NOOT duration, take one second divided by the NOOT type.
//e.g. quarter NOOT = 1000 / 4, eighth NOOT = 1000/8, etc.
int NOOTDuration = 1000 / NOOTDurations[thisNOOT];
tone(8, melody[thisNOOT], NOOTDuration);

// to distinguish the NOOTs, set a minimum time between them.
// the NOOT's duration + 30% seems to work well:
int pauseBetweenNOOTs = NOOTDuration * 1.50;
delay(pauseBetweenNOOTs);
// stop the tone playing:
noTone(8);
  }
 }

void loop() {
int melody[] = {
 // NOOT_C4, NOOT_G3, NOOT_G3, NOOT_A3, NOOT_G3, 0, NOOT_B3, NOOT_C4
 NOOT_D8, NOOT_D8, NOOT_D8, NOOT_D8, NOOT_D8, NOOT_D8
  };
 int NOOTDurations[] = {
  4, 4, 4, 4, 4, 4, 4, 4
  };

  }

How can i let the specific tone loop? Right now it's not within the loop and i am struggling to make it work in the loop. Thanks in advance!

So put the parts you think you need in the loop() and see what happens. If it doesn't work, post a specific question.

#include "Arduino.h"

const byte TONE_PIN = 4;
const int ALARM_BEEP_1 = 4186;
const int ALARM_BEEP_2 = 4699;

const int ALARM_TONE_LENGTH = 200;
const int ALARM_TONE_PAUSE = 800;
const int ALARM_TONE_REPEAT = 6;

boolean alarm = false;

void setup()
{
  alarm = true;
}

void loop()
{
  if (alarm) {
    alarmSound();
  }
}

void alarmSound() {
  static unsigned long next = millis();
  static byte count = 0;
  if (millis() > next) {
    next += ALARM_TONE_LENGTH;
    count++;
    if (count == ALARM_TONE_REPEAT) {
      next += ALARM_TONE_PAUSE;
      count = 0;
    }
    tone(TONE_PIN, (count % 2) ? ALARM_BEEP_1 : ALARM_BEEP_2, ALARM_TONE_LENGTH);
  }
}

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


text:
How do i make my DC motors run simultaneously?
Im coding an adafruit motor shield for  3 DC motors to go forward & backwards, and so my concern is why only my motor3 is running the whole time and motors 1 & 2 are switching off meaning 1 goes than 2 goes and on and on? My code is below if you see where my mistake is in the code can you just tell me what it is and what to do to make them run simultaneously?
#include <AFMotor.h>
AF_DCMotor motor1(1);
AF_DCMotor motor2(2);
AF_DCMotor motor(3);

void setup() {
  Serial.begin(9600);           // set up Serial library at 9600 bps
  Serial.println("Motor test!");
  // turn on motor
  motor1.setSpeed(300);
  motor2.setSpeed(200);
  motor.setSpeed(500);
  motor.run(RELEASE);
}

void loop() {
  uint8_t i;

  //third motor
  Serial.print("tick");
  motor.run(FORWARD);
  for (i=0; i<255; i++) {
    motor2.setSpeed(i);
    delay(10);
  }
  for (i=255; i!=0; i--) {
    motor2.setSpeed(i);
    delay(10);
  }

  //second motor
  Serial.print("tick");
  motor2.run(FORWARD);
  for (i=0; i<255; i++) {
    motor2.setSpeed(i);
    delay(10);
  }
  for (i=255; i!=0; i--) {
    motor2.setSpeed(i);
    delay(10);
  }
  Serial.print("tack");
  motor2.run(BACKWARD);
  for (i=0; i<255; i++) {
    motor2.setSpeed(i);
    delay(10);
  }
  for (i=255; i!=0; i--) {
    motor2.setSpeed(i);
    delay(10);
  }

  Serial.print("tick");
  motor1.run(FORWARD);
  for (i=0; i<255; i++) {
    motor1.setSpeed(i);
    delay(10);
  }
  for (i=255; i!=0; i--) {
    motor1.setSpeed(i);
    delay(10);
  }
  Serial.print("tack");
  motor1.run(BACKWARD);
  for (i=0; i<255; i++) {
    motor1.setSpeed(i);
    delay(10);
  }
  for (i=255; i!=0; i--) {
    motor1.setSpeed(i);
    delay(10);
  }
}

well I haven't ran it yet because I don't know what to put in my code to make the motors run for a certain amount of time!

My question is how would I make my motors run a certain way for a certain amount of time? For an example, motor moves  Forward for 2 seconds!!!

@jstola I did what you said to do and start off with one motor going one direction, than I finished that motor and then I did the two other motors. And everything is working great except the exception that only motor 3 is running the whole time, and  for motor 1 and 2, they switch off meaning like 1 does its runs s than 2 does its runs, how do I make it so they all run simultaneously?

referring to the sketch above ... do the motors move the way you want them to? .... right now, they take 2 1/2 seconds to ramp up in speed and 2 1/2 seconds to ramp down to stop ... have you tried larger increments between steps?

The simplest approach to include a delay in your sketch is to call the Arduino delay() function.  Pass this function a delay value in milliseconds.  For example, a 1 second delay is 1000 milliseconds.
As simple as this method is, it is not recommended if your sketch is required to accomplish tasks during the delay.  This is a common requirement and frustrates many new programmers.
In order to accomplish tasks while waiting for an arbitrary period of time, do not use the Arduino delay() function.  Instead use the Arudino millis() function.  The millis() function will return the number of milliseconds passed since the Arduino board began running the current program.  Record this number, execute the desired action then enter an infinite loop until millis() return a number which indicates the desired number of seconds have passed.  While in the infinite loop the program can execute other tasks as long as they take small amounts of time relative to the desired delay.  Such as testing for a switch closure and turning on an LED.
Essentially, this new program is now a simple finite state machine.

Start with the BlinkWithoutDelay example code and make modifications to suit your needs.
This is the original code.
    /*
  Blink without Delay

  Turns on and off a light emitting diode (LED) connected to a digital pin,
  without using the delay() function. This means that other code can run at the
  same time without being interrupted by the LED code.

  The circuit:
  - Use the onboard LED.
  - Note: Most Arduinos have an on-board LED you can control. On the UNO, MEGA
    and ZERO it is attached to digital pin 13, on MKR1000 on pin 6. LED_BUILTIN
    is set to the correct LED pin independent of which board is used.
    If you want to know what pin the on-board LED is connected to on your
    Arduino model, check the Technical Specs of your board at:
    https://www.arduino.cc/en/Main/Products

  created 2005
  by David A. Mellis
  modified 8 Feb 2010
  by Paul Stoffregen
  modified 11 Nov 2013
  by Scott Fitzgerald
  modified 9 Jan 2017
  by Arturo Guadalupi

  This example code is in the public domain.

  http://www.arduino.cc/en/Tutorial/BlinkWithoutDelay
*/

// constants won't change. Used here to set a pin number:
const int ledPin =  LED_BUILTIN;// the number of the LED pin

// Variables will change:
int ledState = LOW;             // ledState used to set the LED

// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long previousMillis = 0;        // will store last time LED was updated

// constants won't change:
const long interval = 1000;           // interval at which to blink (milliseconds)

void setup() {
  // set the digital pin as output:
  pinMode(ledPin, OUTPUT);
}

void loop() {
  // here is where you'd put code that needs to be running all the time.

  // check to see if it's time to blink the LED; that is, if the difference
  // between the current time and last time you blinked the LED is bigger than
  // the interval at which you want to blink the LED.
  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;

    // if the LED is off turn it on and vice-versa:
    if (ledState == LOW) {
      ledState = HIGH;
    } else {
      ledState = LOW;
    }

    // set the LED with the ledState of the variable:
    digitalWrite(ledPin, ledState);
  }
}

Here are the changes that cause the LED to light up for 500 ms, then go dark for 5000 ms.
The changes are marked by // *************.
Hopefully, this will get you the idea about how to use millis() to control a device at desired intervals.
        /*
          Blink without Delay
          http://www.arduino.cc/en/Tutorial/BlinkWithoutDelay
        */

        const int ledPin =  LED_BUILTIN;                        // the number of the LED pin

    //  int ledState = LOW;                    // ************* // change this assignment as follows

        int ledState = 0;                      // ************* // ledState used as a state counter

        unsigned long previousMillis = 0;

    //  const long interval = 1000;            // ************* // change the interval as follows

        const long interval =  500;            // ************* // use a 500 ms interval

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

        void loop() {
          unsigned long currentMillis = millis();

          if (currentMillis - previousMillis >= interval) {

            previousMillis = currentMillis;    // ************* // program arrives here every 500 ms

    //      if (ledState == LOW) {             // ************* // this code is not needed
    //        ledState = HIGH;                 // *************
    //      } else {                           // *************
    //        ledState = LOW;                  // *************
    //      }                                  // *************

    //      digitalWrite(ledPin, ledState);    // *************

            if (ledState == 0 ) {              // *************
                digitalWrite(ledPin, HIGH);    // ************* // turn on LED at start of cycle
            }                                  // *************
            else if (ledState == 1 ) {         // *************
                digitalWrite(ledPin, LOW);     // ************* // turn off LED at end of 500 ms
            }                                  // *************

            ledState++;                        // ************* // increment state counter
            if (ledState > 10 )  ledState = 0; // ************* // reset ledState when it has reached end of cycle

          }                                                     // end of if
        }                                                       // end of loop

What you're searching for is called "non-blocking programming", a technique in which you frequently test or evaluate whether something needs to be done, and either do it or not, but move on immediately. For one motor, you could block successfully (do nothing else while you wait for something to happen): start/wait/stop/reverse/wait/stop/... etc.
But for two more more motors that need to run independently, your code must not block but decide quickly whether to do a particular thing now or not (start or stop a motor, f/ex), and move on to the next decision.
This article describes how to do that in more detail
(full disclosure: it's one of mine).

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


text:
Controlling 2 DC motors with L293D and 6 V battery pack?
I'm just starting to delve into robotics and electronics, and my first project was building a small Arduino collision-avoidance robot with a ultrasonic range finder, one servo and two DC motors.
Right now I'm using a 6 V battery pack to power both DC motors, another 6 V just for the servo, and a 9 V battery for the Arduino.
But I'm in doubt if the power supply for the DC motors is enough. I'm using an L293D IC to control both motors, but the robot can barely move under load (and the total weight of the robot is not that much. I already reduced all the weight I could). So, how much power, typically, I should supply for the L293D to control those motors?

As has been covered many times here and on electronics.stackexchnge, the L293/L298 are antiquated devices with high internal losses, meaning you essentially loose one cell in your battery pack just to heating up the chip.  Ideally you would replace this with an FET driver, otherwise you will need to add at least another cell to the battery pack.

Is a FET a IC, like the L293D?

The L293 is bipolar IC, not an FET IC.  TB6612FNG is a small FET dual H bridge used with more success on some newer motor shield type offerings.  There are other choices discussed on electronics.stackexchange as well.

Do you know how much power drains your motors? Because we can't help you if you don't give enough infos.

I do not know which Arduino you are using but the 9V smoke alarm battery is about the worst choice you can make. You do not have much current available nor a lot of capacity.

Posting links to "Technical" information on all the hardware devices would be a big help. Also do you have access to a voltmeter. Measure the voltage across the motor terminals when it is running, I expect it to be about 3.5V with good batteries.

The L293D can handle two motors at a time and as per the data sheet the maximum voltage that you can give to the motor as a supply (on pin 8) is 36 volts.

This is not a valid answer to the original question. The OP knows that he can handle 2 motors with this IC, he does not worry about voltage supported by the IC either. He wants to know what power (or current, if we consider the 6V voltage fixed) he needs to properly make both motors move.


text:
Creating a sine wave with a DAC and feeding it back
I want to produce a digital sine wave, send it to DAC0, and then receive it back as input on A0 and plot the graph. I am using an Arduino Due. I wrote the following code:
#define maxSamplesNum 120
#define Sample 50000000/maxSamplesNum  // sample for the 50Hz signal expressed in microseconds

static int Table[maxSamplesNum] =                        // lookup table  for sine wave table
  {
    0x7ff, 0x86a, 0x8d5, 0x93f, 0x9a9, 0xa11, 0xa78, 0xadd, 0xb40, 0xba1,
    0xbff, 0xc5a, 0xcb2, 0xd08, 0xd59, 0xda7, 0xdf1, 0xe36, 0xe77, 0xeb4,
    0xeec, 0xf1f, 0xf4d, 0xf77, 0xf9a, 0xfb9, 0xfd2, 0xfe5, 0xff3, 0xffc,
    0xfff, 0xffc, 0xff3, 0xfe5, 0xfd2, 0xfb9, 0xf9a, 0xf77, 0xf4d, 0xf1f,
    0xeec, 0xeb4, 0xe77, 0xe36, 0xdf1, 0xda7, 0xd59, 0xd08, 0xcb2, 0xc5a,
    0xbff, 0xba1, 0xb40, 0xadd, 0xa78, 0xa11, 0x9a9, 0x93f, 0x8d5, 0x86a,
    0x7ff, 0x794, 0x729, 0x6bf, 0x655, 0x5ed, 0x586, 0x521, 0x4be, 0x45d,
    0x3ff, 0x3a4, 0x34c, 0x2f6, 0x2a5, 0x257, 0x20d, 0x1c8, 0x187, 0x14a,
    0x112, 0xdf, 0xb1, 0x87, 0x64, 0x45, 0x2c, 0x19, 0xb, 0x2,
    0x0, 0x2, 0xb, 0x19, 0x2c, 0x45, 0x64, 0x87, 0xb1, 0xdf,
    0x112, 0x14a, 0x187, 0x1c8, 0x20d, 0x257, 0x2a5, 0x2f6, 0x34c, 0x3a4,
    0x3ff, 0x45d, 0x4be, 0x521, 0x586, 0x5ed, 0x655, 0x6bf, 0x729, 0x794
  };

int i = 0;
int sample;
int sensorPin = A0;
int sensorValue = 0;

void setup() {
  Serial.begin(9600);
  analogWriteResolution(12); // set the analog output resolution to 12 bit (4096 levels)
  analogReadResolution(12); // set the analog input resolution to 12 bit
}

void loop() {
  sample = 50;

  analogWrite(DAC0, Table[i]); // write the selected waveform on DAC0

  i++;
  if (i == maxSamplesNum)  // Reset the counter to repeat the wave
    i = 0;
  delayMicroseconds(sample); // Hold the sample value for the sample time
  sensorValue = analogRead(sensorPin);
}

I want to create a 3.3 V (P-P) sine wave but I don't how to set the amplitude in this wave.
Also I would like to redirect the sine wave output from DAC0 to the A0 Pin and plot the graph to check if generating the sine wave was successful.
How do I plot the graph ?
I uploaded the program but there was no result. I tried to read data from A0, but there wasn't any output. What am I doing wrong?

You just have to Serial.print() the ADC reading, either immediately (which will slow your signal generation), or after the fact (buffer the values, then print them all).

Possible duplicate of No Voltage output on DAC0

I ran your code unmodified and plugged in an oscilloscope to look at DAC0 (looks an OK sine wave) and A0 (looks flatline). Hope this helps.

Further to @Edgar's suggestion there is more information about the Arduino IDE [Serial Plotter] [https://arduinogetstarted.com/tutorials/arduino-serial-plotter#:~:text=Serial%20Plotter%20is%20one%20of,and%20visualizes%20data%20as%20waveforms]. Which I think resolves the "How do I plot the graph" part of your question. The oscilloscope test shows that your wave generation is working OK. If you would like further help about a loopback on A0, I suggest you show your wiring. Regards.


text:
How to do a software reset on MAX7456?
I messed around with the MAX7456 chip for a while, even the character set updating sketch seemed to work after a few modifications. But now it is not displaying anything with the Hello World sketch that worked before. No signal seems to pass through it, the screen is just black.
The datasheet says that one must write Video Mode 0 Register (VM0) at address 00H bit 1 to 1 via SPI to reset it, how would I do it? Also, how would one verify that the chip indeed did reset itself and responds to the commands given to it afterwards? (The board looks like this)

Can you clarify: The board used to work, and now -- using the same code -- it doesn't? Or it works for a while, and then not? Or it works with some code but not other code?

@NickGammon Yes, using the same code the board does not work any more.

Well, after powering the chip off it should reset. I don't think sending a software reset would achieve anything more than a power off. It is possible you damaged it, however without more information it is impossible to say.

Your answer seemed to fix the issue. It now works.

The datasheet says:

The SPI commands are 16 bits long with the 8 most significant bits (MSBs) representing the register address and the 8 least significant bits (LSBs) representing the data ...

Thus, you need to write address / data after selecting the chip.
digitalWrite (SS, LOW);  // select the chip
SPI.transfer (0x00);     // select address 0x00 (Video Mode 0)
SPI.transfer (bit (1));  // write bit 1 (Software Reset Bit)
digitalWrite (SS, HIGH); // done

According to the datasheet you need to wait around 20 µs for the operation to complete. You could, of course, just wait 20 µs but it might be nice to see if the bit gets cleared.
  byte result;

  do
    {
    digitalWrite (SS, LOW);      // select the chip
    SPI.transfer (0x80);         // select address 0x00 (Video Mode 0) - read mode
    result = SPI.transfer (0);   // read it
    digitalWrite (SS, HIGH);     // done
    } while (result & bit (1));  // loop while not reset yet

Also, how would one verify that the chip indeed did reset itself and responds to the commands given to it afterwards?

I'm not sure, without the chip in hand, what other tests you can make, but if you added a counter into the above loop, you could probably verify that it was doing something. eg.
  // reset chip
  digitalWrite (SS, LOW);  // select the chip
  SPI.transfer (0x00);     // select address 0x00 (Video Mode 0) - write mode
  SPI.transfer (bit (1));  // write bit 1 (Software Reset Bit)
  digitalWrite (SS, HIGH); // done

  byte result;
  unsigned int counter = 0;

  // wait for it to become ready, or time-out
  do
    {
    digitalWrite (SS, LOW);      // select the chip
    SPI.transfer (0x80);         // select address 0x00 (Video Mode 0) - read mode
    result = SPI.transfer (0);   // read it
    digitalWrite (SS, HIGH);     // done
    if ((result & bit (1)) == 0)
      counter++;     // count times not ready
    } while ((result & bit (1)) && (counter < 1000) );  // loop while not reset yet

  if (counter == 0 || counter >= 1000)
    {
    // chip does not seem to be responding
    }
  else
    {
    // all OK!
    }

This sketch seemed to do the job. The hello world sketch started working (but for obvious reasons the character set is wrong).


text:
Why does Arduino Due appear to halt after single call to ADC_Handler?
In the simple example below I just software trigger an ADC acquisition and then set the builtin LED's digital out in the interrupt handler. I don't know why the program appears to halt however.

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

  pinMode(13,OUTPUT);
  digitalWrite(13,LOW);

  adc_enable_channel(ADC, ADC_CHANNEL_6);
  adc_enable_interrupt(ADC, ADC_IER_EOC6);
  pmc_enable_periph_clk(ID_ADC);
  NVIC_EnableIRQ(ADC_IRQn);

  Serial.println("GO");
}

void loop()
{
  Serial.println("RUNNING");
  adc_start(ADC);
}

void ADC_Handler(void)
{
  digitalWrite(13,HIGH);
  adc_get_status(ADC);
}

I know the handler gets called because the LED lights.  The main loops appears to stop running after this as it lo longer prints out anything.  If I don't trigger an acquision in the main loop it runs forever. Likewise if I don't enable the interrupt or the NVIC.
I can't explain this behavior.

There's no reference to ADC_Handler in your setup code, so I doubt this is really called.

Possible duplicate: https://arduino.stackexchange.com/questions/19924/arduino-due-interrupt-based-adc-hangs-processing?rq=1

@PMF As with other ISRs, it overrides a weak reference in Arduino15\packages\arduino\hardware\sam\1.6.12\cores\arduino\coretex_handlers.c It is definitely called because the LED lights up only if that digitalWrite is there.

The freeze will occur unless unless ADC_ISR bits 0-15 are 0 at the end of the interrupt handler.  In this case, ISR returns bit 6 set for the enabled channel (6).  For many interrupts, the bit can be reset to 0 by simply reading ADC_ISR. However for end-of-conversion interrupts the converted data register for that channel must be read for the ISR bit to be set to 0.
Therefore this code will not halt. (I included some extra printouts to make clear the register values at each point in time.)
volatile uint32_t LAST = 0;
volatile uint32_t CHAN6 = 0;
volatile uint32_t ISR1 = 0;
volatile uint32_t ISR2 = 0;

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

  adc_enable_channel(ADC, ADC_CHANNEL_6);

  adc_enable_interrupt(ADC, ADC_IER_EOC6);

  pmc_enable_periph_clk(ID_ADC);

  NVIC_ClearPendingIRQ(ADC_IRQn);
  NVIC_EnableIRQ(ADC_IRQn);

  Serial.println("GO");
  adc_configure_trigger(ADC, ADC_TRIG_SW,0);
}

void loop()
{
  Serial.println(ISR1,BIN);
  Serial.println(ISR2,BIN);

  adc_start(ADC);
  delay(1000);
}

void ADC_Handler(void)
{
  ISR1 = adc_get_status(ADC); // chan 6 bit =1
  LAST = adc_get_latest_value(ADC);
  ISR1 = adc_get_status(ADC); // chan 6 bit =1 (still)

  CHAN6 = adc_get_channel_value(ADC, ADC_CHANNEL_6);
  ISR2 = adc_get_status(ADC); // chan 6 bit = 0
}

However, I will note that the datasheet for the chip says on page 1322 Reading one of the ADC_CDR registers clears the corresponding EOC bit. Reading ADC_LCDR clears the DRDY bit and EOC bit corresponding to the last converted channel.
This appears to be false. Reading ADC_LCDR does not clear the status bit and will cause a hang.  ADC_CDR6 must be read specifically to avoid a hang.


text:
servos act strangely instead of stopping/starting
I am trying to make it so that my robot rolls straight when pin 8 is high and stop when pin 8 is low, the 2 servos is constant rotation servos. instead the servos spin when the wire touches it pin even without power to the wire, and they don't stop when the wire is pulled, but sometimes they don't start and sometimes they stop.
I'm new to coding and I really need this help.

#include <Servo.h>

Servo h1;
Servo h2;

#define servoPin 13
#define servoPin 3

int angle = 0;
const int buttonPin = 8;
int buttonState = 0;
void setup() {

  h2.attach(13); //left servo
  h1.attach(3); //right servo
  pinMode(8, INPUT);
}

void loop() {

  if (digitalRead(8) == LOW)  {
  h1.write(90); //no movement
  h2.write(90);//no movement

  } else  {
    h1.write(180); //go straight
    h2.write(0); //go straight
  }
}

What happens if you change INPUT to INPUT_PULLUP?

reduce your code to repeatedly print the state of pin 8 ... what do you observe?

As VE7JRO suggested, this really sounds like a floating pin. I guess you have a button on that pin, which connects the pin to ground when pressed, but you don't have an external pullup resistor. Using pinMode(pin, INPUT_PULLUP) will activate the internal pullup resistor for that pin.

Are you aware that there are at least two very different types of servos? Are you sure that the library you use matches the type of servo you attached?


text:
How to fix this problem of invalid conversion from 'const char*' to 'char' [-fpermissive]
Im working with node mcu ESP 8266 and trying to make it a webserver but keep encountering this problem.
   #include<ESP8266WiFi.h>
    WiFiClient client;
    WiFiServer server(80);
    void setup()
    {
    Serial.begin(9600);
    WiFi.begin("network","password");
    while(WiFi.status()!= WL_CONNECTED)
    {
      delay(200);
      Serial.print("...");
    }
    Serial.println("NodeMCu is connected");
    server.begin();
    }
    void loop()
    {
    client = server.available();
    if(client==1)
    {
       String request= client.readStringUntil("\n");
      Serial.println(request);
    }
    }
    ```

I'm getting this error :error: invalid conversion from 'const char*' to 'char' [-fpermissive]
   24 |    String request= client.readStringUntil("\n");
      |                                           ^~~~
      |                                           |
      |                                           const char*

Please copy the exact error message, including the line where the compiler finds the error. Also put your code in a code block (" {}  " when editing).

BTW, the problem is in the client.readStringUntil("\n"). The double quotes make the \n into a c-string (const char *), but it expects a single character (char). You can correct this by changing "\n" into (single quoted) '\n', which makes it into a single character.

I assume this is "off-topic" because the bug is not specifically about the Arduino. Given OP's level of experience, they had no way to know that.  I expect many other Arduino novices will encounter this same error and come here looking for an explanation.  Is this really so off-topic?


text:
Can you charge and use a Li-po battery at the same time?
I have a system that uses an Arduino Uno board as a "brain". All the elements in the system are powered by a single Li-po battery (3-cell, 11.1 V, 1800 mAh).
I made a circuit so the Arduino can check the battery voltage and decide when it needs to recharge. I also have a circuit that controls the battery charge sequence and interrupts the power when the battery is charged, sending a signal to the Arduino interrupting its power saving mode. The Arduino enters the power saving mode when the charging sequence is initiated. The charging circuit uses 12 V and 450 mA which I plan to supply with a 12 V, 6 W solar panel.
My question is: can I charge the battery while the Arduino is still on, but in power saving mode?
If not, how can I make this system self-charging while keeping the Arduino on continuously?

can I charge the battery while the Arduino is still on, but in power saving mode?

You can draw power from a Li-ion battery whilst charging it, but it isn't recommended. This is because the load on the battery affects the ability to detect the different phases of charging, and determine the end-of-charge condition.
Instead you should provide a bypass facility so that if external power is applied the external power is routed to the Arduino to power it, but when the power is removed the battery provides the power to the Arduino.
The circuit I usually use is:

simulate this circuit – Schematic created using CircuitLab
When 5 V is applied the battery charges up. Q1 is held off. The 3.3 V regulator is then powered through D1. When the 5 V is removed Q1 is turned on by R1 pulling the gate low and the battery powers the 3.3 V regulator.

Application Note AN1149 by Microchip Inc:

It is NOT encouraged to attach the system load directly to Li-ion batteries when using a stand-alone Li-ion battery charge management controller with automatic termination feature.

Why not?

1. The charge may never end.

Most Li-ion battery chargers are based on Constant Current and Constant Voltage (CC-CV) modes. The termination is based on the ratio of charge current and preset constant current (Fast Charge). If the system draws current from the battery, the charge current will never meet the termination value. This causes the non-termination of the charge management circuit.

2. The total system current is limited by the charge current.

It is because the charger will deliver total system and battery charging current through the output pin. This solution may be feasible for
some applications that run on constant current, but it is not recommended.

So what's the alternative?
A load-sharing switch with a P-MOSFET:

Q1 is OFF when the gate is high
and no current flows from the battery cell to the system load

Q1 is ON when the gate is low and current flows from the battery cell to the system load.

The App Note contains some really good practical advice on component selection, I highly recommend reading it.

If you need to charge it and run at the same time, I would recommend getting a PowerBoost module from Adafruit. They can handle both, and they also have a low-battery indicator.


text:
Flash ESP8266 from SPIFFS filesystem
I'm searching for a way to flash an ESP8266 programmatically, i.e, without user interaction (and especially without the Arduino IDE).
Assuming I can put the program to be flashed on the SPIFFS filesystem, is there a way to flash the ESP with that file?

yes, but why store it in SPIFFS? see the ESP8266HTTPUpdateServer and ESP8266httpUpdate libraries examples

I said I wanted no user interaction.  Besides, I don't want a server in my ESP.

how do you get the file to SPIFFS? the ESP8266httpUpdate library downloads an update bin from a server and updates using the Updater object without storing the bin to SPIFFS.

Yes, it is (or at least WAS possible a few years ago) to have an ESP8266 self-program if you can get the file onto the file system, by using the Update core that is used by OTA and httpUpdate. This was a example program to do it, but I don't know if it still works. I would also suggest that you look at using LittleFS instead of SPIFFS as the latter has been depreciated.
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <FS.h>

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

  SPIFFS.begin();
  Dir dir = SPIFFS.openDir("/");

  pinMode(BUILTIN_LED, OUTPUT);
  digitalWrite(BUILTIN_LED, LOW);

  File file = SPIFFS.open("/firmware-update.bin", "r");

  uint32_t maxSketchSpace = (ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000;
  if (!Update.begin(maxSketchSpace, U_FLASH)) { //start with max available size
    Update.printError(Serial);
    Serial.println("ERROR");
  }

  while (file.available()) {
    uint8_t ibuffer[128];
    file.read((uint8_t *)ibuffer, 128);
    Serial.println((char *)ibuffer);
    Update.write(ibuffer, sizeof(ibuffer));
  }

  Serial.print(Update.end(true));
  digitalWrite(BUILTIN_LED, HIGH);
  file.close();
}

void loop() {
}

Perfect!  This is exactly what I was looking for.  Also thanks for the suggestion of LittleFS, I will consider it.

Yes, it still works, but now you need to pass data as a pointer:
Update.write(&ibuffer, sizeof(ibuffer));

it is an array so it is a pointer already


text:
How to override automatic control in Blynk app?
I am a beginner to Blynk, and have successfully built a simple water temperature control project. It consists of an ESP32, a plug-in water heater, and an AC relay board. The ESP32 controls the relay board, while the water heater is plugged into the relay board.
The code I have will turn on the relay once the water temperature dips below 16°C. On the Blynk app, I want to add a button that allows the user to manually control the operation of the relay. But I am stumped as to how to code it. Since I have programmed the ESP to turn off the relay once the temperature is above 16°C, if I try to switch it on manually at 20°C, for example, the relay will not remain on, because the if statement will fail.
How can I code this to have a manual override capability, so that once the user turns on the button inside the Blynk app, the ESP will allow manual control of the digital pin (delay trigger), and will only revert back to automatic temperature control mode once the button is turned off?
#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>
#include <OneWire.h>
#include <DallasTemperature.h>

#define ONE_WIRE_BUS 14        //data wire connected to pin 14
#define RELAY_PIN 23           //IoT relay connected to pin 23

OneWire oneWire(ONE_WIRE_BUS); //instance to communicate with any OneWire device

DallasTemperature sensor(&oneWire); //pass reference to Dallas Temperature object

BlynkTimer timer;       //create Blynk timer object for timed intervals
float waterTemp;        //temperature from DS18B20 in C

char auth[] = "xxxxxxx";
char ssid[] = "xxxxxxx";
char pass[] = "xxxxxxx";

void setup() {
  Serial.begin(9600);
  sensor.begin();
  Blynk.begin(auth, ssid, pass);
  sensor.setResolution(9);           //default is 9 bit
  timer.setInterval(1000L, sendTemp);
  pinMode(RELAY_PIN, OUTPUT);
  digitalWrite(RELAY_PIN, LOW);
}

void sendTemp() {
  sensor.requestTemperatures();      //must request reading first
  waterTemp = sensor.getTempCByIndex(0);
  if (waterTemp != DEVICE_DISCONNECTED_C) {
    Serial.print("Temp = ");
    Serial.println(waterTemp);
    Blynk.virtualWrite(V1, waterTemp);
    if (waterTemp < 16) {
      digitalWrite(RELAY_PIN, HIGH); //turn on IoT relay
    } else {
      digitalWrite(RELAY_PIN, LOW);  //turn off IoT relay
    }
  } else {
    Serial.println("Error: Could not read temperature data");
    Blynk.notify("Error: Could not read temperature data");
    digitalWrite(RELAY_PIN, LOW);
  }
}

void loop(void) {
  Blynk.run();
  timer.run();
}

use a state variable

if(is_manual){ do new stuff}else{ run old code} Also, this sounds like a fire hazard. I would have another thing make sure to kill everything if it gets too hot, not just the esp either, those can lockup. A thermal fuse would be good.

Roughly like this:
Make a global variable int mode;
Read a Blynk app 3-way switch in the loop();
Set mode to the 1, 2, or 3 received from the Blynk app (for ON/OFF/AUTO);
Replace this bit of code:
if (waterTemp < 16) {
  digitalWrite(RELAY_PIN, HIGH); //turn on IoT relay
} else {
  digitalWrite(RELAY_PIN, LOW);  //turn off IoT relay
}

with
if (mode == 1) {
  digitalWrite(RELAY_PIN, HIGH);
} else if (mode = 2) {
  digitalWrite(RELAY_PIN, LOW);
} else {
  if (waterTemp < 16) {
    digitalWrite(RELAY_PIN, HIGH); //turn on IoT relay
  } else {
    digitalWrite(RELAY_PIN, LOW);  //turn off IoT relay
  }
}

You will still have to decide what happens when DEVICE_DISCONNECTED_C == TRUE, etc, but that is the gist of it.


text:
Arduino Uno cant be powered by VIN pin
Im trying to power an Arduino Uno from a pack of 8 AA batteries (so 12V) and it just doesn't turn on. When I connect the barrel jack, it works! Any idea why the VIN doesn't work? Thank you in advance.

VIN pin should be connected directly to barrel jack. Could you test if they are connected in your Uno?

@AleksejVasinov Actually there's a diode in the + of the barrel jack connection, so it's not directly connected. A simple continuity test may fail if not done right.

I have known some inferior Chinese clones to use sub-par headers with bad connections in them. Try connecting to the pin underneath the board where the VIN is soldered.


text:
NodeMCU minimum supply voltage)
I have read several articles an datasheets, but I couldn't find an affordable answer...
This is my problem: I need to power a NodeMCU (on Vin pin) with 3xAA batteries. Which is the minimum operating voltage at Vin accepted by NodeMCU? In other words, which voltage drop from 4.5 will let NodeMCU still working?
thanks.

i run several simple devices on 2xAA batteries connected to VCC. Only uses about 2/3rds of the battery, but for me, that's years of operation before they drop down to under 2.5v...

If you have 2xAA why don't you connect them directly to 3V3 pin?

good idea. so good in fact, that's what i did (VCC == 3.3v)

The NodeMCU uses the SPX3819 3.3v voltage regulator.
That regulator, according to the datasheet has a dropout of maximum 700mV, but much less at lower currents.
Taking the maximum, that means that you need to supply 3.3 + 0.7 = 4V to the board for the regulator to regulate properly. However, it is doubtful you will be using that much current, so probably nearer a 350mA dropout - which means 3.3 + 0.35 = 3.65V.
However, the ESP8266 itself will work down to 2.5V - so if you operate the board with the regulator out of regulation (not recommended, but it should work fine), you could probably go as low as 2.8 to 3V without problems.

But I can't connect 4.5v to 3.3 pin, correct?

No. That's why I say 2.8 to 3v because the regulator will drop an unknown amount.

In other words: my 3xAA battery pack could work until it supplies at least 3.5-3.6v?

Sounds about right.


text:
Cannot use radio transmitter after switching to LowPower library
My Arduino Mini board has DHT22 temperature sensor and 433MHz radio transmitter modules. I'm using DHT and RCswitch libraries to make use of them. Code looks like this:
void setup() {
  tempSwitch.enableTransmit(RADIO_PIN);
  dht.begin();
}

void loop() {
  float temp = dht.readTemperature();

  unsigned long message = createTemperatureMessage(SENSOR_ID, temp);
  tempSwitch.send(message, 32);

#ifdef MY_DEBUG
  unsigned int sleepCount = 1;
#else
  // 3600s / 2 / 8s == 225
  unsigned int sleepCount = 225;
#endif
  for (; sleepCount > 0; sleepCount--) {
    LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
  }
}

So I'm reading temperature and sending it using RCswitch library. Initially I just had delay(1000); instead of fancy LowPower sleep loop but I wanted to make my "device" more battery-friendly so I switched to low-power sleep.
The problem is that now Arduino is only sending data first time and after sleeping 30 minutes (in "release" mode) it does not send anything anymore. If I reduce 30 minutes to 8 seconds it is capable of sending data as well as if I replace sleep with delay(30*60*1000);.
From beyond it looks like something is not caching up after the sleep. Do I need to "wake" radio module in any special way? How to fix that?

I've never tried this, but if you are putting the Arduino to sleep I would expect it to cut power to the devices (does it?) if it does then after a 30 minute sleep I would expect the devices to come back up in the initial state.  Guessing by your code the initial state of the radio is Tx Disabled, so try moving the
tempSwitch.enableTransmit(RADIO_PIN);

to before the
float temp = dht.readTemperature();

line.
I'd also be concerned that the DHT22 is not in the correct state after you wake up.
Can you try doing a 1 second LowPower sleep in debug mode, I suspect it would work more often.

You idea kind of worked (I just called setup() instead) but with addition of delay(1000); after power-down sleep itself.


text:
Morse encoder code not working as expected on Arduino UNO
I'll start saying that I don't have much experience working with Arduino and programming in C. I have an Elegoo Arduino UNO clone.
Recently I was trying to build a morse encode which converts a text to morse and then flashes a LED to communicate the morse code. The code is as follows
#define OUT_PIN 8
#define END_PIN 7

const short dot_time = 200; // Time LED is ON for dot
const short dash_time = dot_time*3; // Time LED is ON for dash
const short same_letter_space = dot_time; // Time LED is OFF between dots/dashes of the same letter
const short letter_space = dot_time*3; // Time LED is OFF between letters
const short word_space = dot_time*5; // Time LED is OFF between words
const char letter_separator[] = "_";
const char word_separator[] = "/";

typedef struct {
  char * morse;
  char letter;
}morse_pair;

morse_pair morse_table_letters[] = {{".-", 'A'}, {"-...", 'B'}, {"-.-.", 'C'}, {"-..", 'D'}, {".", 'E'}, {"..-.", 'F'}, {"--.", 'G'}, {"....", 'H'}, {"..", 'I'}, {".---", 'J'},//
{"-.-", 'K'}, {".-..", 'L'}, {"--", 'M'}, {"-.", 'N'}, {"---", 'O'}, {".--.", 'P'}, {"--.-", 'Q'}, {".-.", 'R'}, {"...", 'S'}, {"-", 'T'}, {"..-", 'U'}, {"...-", 'V'},
{".--", 'W'}, {"-..-", 'X'}, {"-.--", 'Y'}, {"--..", 'Z'}};
morse_pair morse_table_digits[] = {{"-----", '0'}, {".----", '1'}, {"..---", '2'}, {"...--", '3'}, {"....-", '4'}, {".....", '5'}, {"-....", '6'}, {"--...", '7'}, {"---..", '8'},//
{"----.", '9'}};

char test_text[] = "aaa";

morse_pair letter_encoder(char letter){
  int letter_value = (int) letter;
  if(letter_value >= 97){
    //lowercase
    return morse_table_letters[letter_value-97];
  }
  else if (letter_value>=65){
    //uppercase
    return morse_table_letters[letter_value-65];
  }
  else {
    //digits
    return morse_table_digits[letter_value];
  }
}

char* word_to_morse(char* word, size_t len){
  Serial.print("Encoding word: ");
  Serial.println(word);
  size_t len_morse = 0;
  char* letters[len];
  for(size_t l=0;l<len;l++){
    letters[l] = letter_encoder(word[l]).morse;
    len_morse += strlen(letters[l])+1;
  }
  char* morse_string = malloc(len_morse*sizeof(char));
  for(size_t l=0;l<len;l++){
    strcat(morse_string, letters[l]);
    if(l<len-1){
      strcat(morse_string, letter_separator);
    }
  }
  strcat(morse_string, word_separator);
  Serial.print("Result: ");
  Serial.println(morse_string);
  return morse_string;
}

char* text_to_morse(char* text){
  Serial.print("Encoding text: ");
  Serial.println(text);
  size_t len = strlen(text);
  char* text_morse = malloc((4*len+len)*sizeof(char));
  char* swp = text;
  for(char* ewp = text;ewp!=(text+len);ewp++){
    if(*(ewp+1)==' ' || *(ewp+1) == '\0'){
      char * wtm = word_to_morse(swp, ewp-swp+1);
      strcat(text_morse, wtm);
      swp=ewp+2;
      free(wtm);
    }
  }
  Serial.print("Result: ");
  Serial.println(text_morse);
  return text_morse;
}

void morse_to_pin(char* text_morse){
  Serial.println("Playing with pins");
  size_t len = strlen(text_morse);
  for(size_t l=0;l<len;l++){
    char letter = text_morse[l];
    Serial.println(letter);
    if(letter == '.'){
      digitalWrite(OUT_PIN, HIGH);
      delay(dot_time);
    }
    else if(letter=='-'){
      digitalWrite(OUT_PIN, HIGH);
      delay(dash_time);
    }
    else if(letter=='_'){
      digitalWrite(OUT_PIN, LOW);
      delay(letter_space);
    }
    else if(letter=='/'){
      digitalWrite(OUT_PIN, LOW);
      delay(word_space);
    }
    else {
      digitalWrite(OUT_PIN, LOW);
      delay(same_letter_space);
    }
  }
}

void start_comm(){
  Serial.println("Start comm.");
  digitalWrite(END_PIN, HIGH);
  delay(2000);
  digitalWrite(END_PIN, LOW);
}

void end_comm(){
  Serial.println("End comm.");
  digitalWrite(END_PIN, HIGH);
  delay(500);
  digitalWrite(END_PIN, LOW);
  delay(500);
  digitalWrite(END_PIN, HIGH);
  delay(500);
  digitalWrite(END_PIN, LOW);
}

void setup(){
  Serial.begin(9600);
  pinMode(OUT_PIN, OUTPUT);
  pinMode(END_PIN, OUTPUT);
}

void loop ()
{
  start_comm();
  delay(1000);
  char* ttm = text_to_morse(test_text);
  morse_to_pin(ttm);
  free(ttm);
  delay(1000);
  end_comm();
  delay(1000);
}

The part of the code that converts text to a morse string behaves correctly when run on my laptop, but when I upload it to my Arduino UNO behaves weirdly and the morse LED doesn't flashes at all.

Edit:
the Arduino UNO just seems to run only the start_comm and end_comm functions, as if there's nothing inbetween. It changed behaviour and doesn't behaves always the same, before it printed some garbage to the serial monitor, but now it just skips the whole code inbetween the two functions mentioned above.

So how exactly is the text_to_morse() function behaving on the Uno? Is it printing the correct morse text? If not: What is it actually printing? We need to narrow down the error source here

@chrisl you're right, I'll update as soon as I can with and example

"behaves correctly when run on my laptop, but" not on "my Arduino UNO". you use malloc(), it works on your laptop because your laptop have plenty of memory, but only has 2k RAM in Arduino. You should check whether your malloc() allocated memory successfully in the heap with if (text_morse != NULL) { // rest of your code };, or better off, not to use static allocated memory than dynamic allocated memory.

I kind of solved it, I was using malloc incorrectly and was accessing uninitialized bits, thus causing undefined behaviour. The code below should work correctly
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define OUT_PIN 8
#define END_PIN 7

const short dot_time = 200; // Time LED is ON for dot
const short dash_time = dot_time * 3; // Time LED is ON for dash
const short same_letter_space = dot_time; // Time LED is OFF between dots/dashes of the same letter
const short letter_space = dot_time * 3; // Time LED is OFF between letters
const short word_space = dot_time * 5; // Time LED is OFF between words
const char letter_separator[] = "_";
const char word_separator[] = "/";
const char unkown_letter[] = "?";

typedef struct {
  char * morse;
  char letter;
} morse_pair;

const morse_pair morse_table_letters[] = {{".-", 'A'}, {"-...", 'B'}, {"-.-.", 'C'}, {"-..", 'D'}, {".", 'E'}, {"..-.", 'F'}, {"--.", 'G'}, {"....", 'H'}, {"..", 'I'}, {".---", 'J'},//
  {"-.-", 'K'}, {".-..", 'L'}, {"--", 'M'}, {"-.", 'N'}, {"---", 'O'}, {".--.", 'P'}, {"--.-", 'Q'}, {".-.", 'R'}, {"...", 'S'}, {"-", 'T'}, {"..-", 'U'}, {"...-", 'V'},
  {".--", 'W'}, {"-..-", 'X'}, {"-.--", 'Y'}, {"--..", 'Z'}
};
const morse_pair morse_table_digits[] = {{"-----", '0'}, {".----", '1'}, {"..---", '2'}, {"...--", '3'}, {"....-", '4'}, {".....", '5'}, {"-....", '6'}, {"--...", '7'}, {"---..", '8'},//
  {"----.", '9'}
};

const char* letter_encoder(char letter) {
  int letter_value = (int) letter;
  if (letter_value >= 97 && letter_value <= 122) {
    //lowercase
    return morse_table_letters[letter_value - 97].morse;
  }
  else if (letter_value >= 65 && letter_value <= 90) {
    //uppercase
    return morse_table_letters[letter_value - 65].morse;
  }
  else if (letter_value>=48 && letter_value<=57) {
    //digits
    return morse_table_digits[letter_value].morse;
  }
  else {
    //Boh
    return unkown_letter;
  }
}

void word_to_morse(char* morse_word, char* word, int len) {
  Serial.print("Encoding word: ");
  Serial.println(word);
  for (int l = 0; l < len; l++) {
    strcat(morse_word, letter_encoder(word[l]));
    if (l < len - 1) {
      strcat(morse_word, letter_separator);
    }
  }
  strcat(morse_word, word_separator);
  Serial.print("Word result: ");
  Serial.println(morse_word);
}

void text_to_morse(char* morse_text, char* text, int len) {
  Serial.print("Encoding text: ");
  Serial.println(text);
  char* swp = text;
  int morse_len = 0;
  for (char* ewp = text; ewp != (text + len); ewp++) {
    if (*(ewp + 1) == ' ' || *(ewp + 1) == '\0') {
      int w_len = ewp - swp + 1;
      char * morse_word = (char*) malloc((5*w_len+w_len)*sizeof(char));
      strcpy(morse_word, "");
      word_to_morse(morse_word, swp, w_len);
      morse_len += strlen(morse_word);
      Serial.print("Word result: ");
      Serial.println(morse_word);
      Serial.print("Word len: ");
      Serial.println(morse_len);

      strcat(morse_text, morse_word);
      swp = ewp + 2;
      free(morse_word);
    }
  }
  morse_text = (char*) realloc(morse_text, ++morse_len*sizeof(char));
  Serial.print("Text result: ");
  Serial.println(morse_text);
}

void morse_to_led(const char* text_morse, int len) {
  Serial.println("Flashing morse with pins");
  for (int l = 0; l < len; l++) {
    char letter = text_morse[l];
    Serial.println(letter);
    switch(letter){
      case '.':
        digitalWrite(OUT_PIN, HIGH);
        delay(dot_time);
        break;
      case '-':
        digitalWrite(OUT_PIN, HIGH);
        delay(dash_time);
        break;
      case '_':
        digitalWrite(OUT_PIN, LOW);
        delay(letter_space);
        break;
      case '/':
        digitalWrite(OUT_PIN, LOW);
        delay(word_space);
        break;
      default:
        digitalWrite(OUT_PIN, LOW);
        delay(same_letter_space);
        break;
    }
  }
}

void start_comm() {
  Serial.println("Start comm.");
  digitalWrite(END_PIN, HIGH);
  delay(dash_time);
  digitalWrite(END_PIN, LOW);
}

void end_comm() {
  Serial.println("End comm.");
  digitalWrite(END_PIN, HIGH);
  delay(dot_time);
  digitalWrite(END_PIN, LOW);
  delay(dot_time);
  digitalWrite(END_PIN, HIGH);
  delay(dot_time);
  digitalWrite(END_PIN, LOW);
}

void setup() {
  Serial.begin(9600);
  pinMode(OUT_PIN, OUTPUT);
  pinMode(END_PIN, OUTPUT);
}

void loop ()
{
  //Start
  start_comm();
  delay(2000);

  //Convert
  char test_text[] = "test";
  int len = strlen(test_text);
  char * morse_text = (char*) malloc((5*len+len)*sizeof(char));
  strcpy(morse_text, "");
  text_to_morse(morse_text, test_text, len);
  morse_to_led(morse_text, strlen(morse_text));
  free(morse_text);
  delay(2000);

  //End
  end_comm();
  delay(2000);
}


text:
Selenoid motor not responding to NodeMCU instructions
I just start a project migrating from Arduino Uno to NodeMCU, basically this projects control some selenoid motors triggered by a website instructions. For example: if website returns 2, the motor #2 start work.
I hace everything ready, fetching from the website but, the motors are not working. In Arduino Uno works but in NodeMCU did not.
The selenoid motor is this one from AliExpress: the 3v --> https://es.aliexpress.com/item/4000807560712.html
The circuit I made is like this:
NodeMCU / Motor
D2 -> Positive motor wire (red wire).
3.3V -> Positive motor wire (red wire).
GND -> Negative motor wire (black wire).
All this is attached to a protoboard for easy my work, but those are the connections of the circuit.
At otherwise, the code looks something like this:
void setup() {
  Serial.begin(115200);
  pinMode(D2, OUTPUT);

}

void loop() {
  digitalWrite(D2, LOW);
  delay(3000);
  digitalWrite(D2, HIGH);
  delay(3000);

}

I also tried instead of pin name D2 use 4 corresponding of the GPIO number. Didn't work.
The wired part is in Arduino Uno the same code and same circuit works perfectly, but in NodeMCU not.

Do you mean you have connected 3.3V AND D2 to the positive motor wire? Don't you use any kind of motor driver?

@chrisl When I plug the 3.3V wire from NodeMCU to the motor, the motor react, but when the loop start and pass digitalWrite(D2, LOW) the motor still works. The same code/circuit on the Arduino Uno works, the motor go HIGH/LOW when the codes indicates. Thanks!

So basically you are shorting the output pin by setting it to LOW while it is directly connected to 3.3V?

So you connected 3.3V and pin D2 both to the positive motor wire. When the pin is high the motor runs and gets its current from the 3.3V pin. When you set the pin to LOW you essentially short the 3.3V pin to ground through the output hardware of the pin. That is highly risky. The output hardware of the pin only can withstand a certain amount of current (around 20mA, 40mA absolute max). Since you have nothing that would limit the current in this path you can easily fry the output hardware of the pin. Don't do that! The same is valid for driving a motor directly only from the digital output pin.
The correct way of controlling a motor with an Arduino or ESP is by using a fitting driver. For just turning it on and off a simple transistor or MOSFET is sufficient (depending on the current draw of the motor a MOSFET is better than a bipolar transistor). Google something like "MOSFET as switch" and you will get many tutorials on that. You can also add the term "Arduino" and you will get tutorials specifically for Arduinos.
Why it worked for the Uno but not for the NodeMCU? You didn't describe how exactly you connected it on the Uno (to the 3.3V pin or the 5V pin?). Probably the digital output pin on the NodeMCU cannot sink enough current so that it is not able to lower the voltage enough. Though if it would be able to do this it would also cause a power failure for the whole microcontroller. Maybe that also happened with your Uno difficult to say without more information.

Thanks @chrisl!


text:
Space taken by Global Variables
Using Nano's for small programmes I get compilation reports about the amount of space taken by global variables.
On a typical progamme it says something like Sketch uses 16316 bytes (53%) of program storage space. Maximum is 30720 bytes. Global variables use 1798 bytes (87%) of dynamic memory, leaving 250 bytes for local variables. Maximum is 2048 bytes. Low memory available, stability problems may occur.
If I count up the number of bytes taken by the declared global variables it is 126 bytes, depending on how bool's take up memory ( one bit or one byte ).
Can I get the compiler to give me a dump of what it is actually assigning as global variable space to reconcile the difference between 126 bytes and 1798 bytes.  Then I could change the programme to get round the memory problem and keep using the Nano's.
Thanks in advance for any useful insights.
Thanks to those who commented for the help.
Checking the memory requirement for the global variables, includes and begins still only used 34% so I realised that something in the main loop was using extra memory.  Then the penny dropped, I had print messages left over from tracing problems and these become stored constants when compiled.  Moved these to a conditional compile section so they are only compiled during tracing for bugs. Problem solved. Once again thanks for the helpful hints.

Start with an empty sketch and see its RAM requirements. Then add Serial.begin(9600); and notice the difference. Your 1798 bytes are certainly used by some library. And yes, there`s a tool avrdump , but not that easy to use.

If you dive into command line levels, you can ask the linker to generate a map file. However, this is not trivial for the beginner.

Here's a hint for future use: this form (note the 'F' macro) Serial.print(F("Your message here.\n")); will store the message text in flash instead of RAM. That will work for any object that uses Print library. Though your concern wasn't (yet) running out of RAM, in a larger program, adding text messages can cause various kinds of out-of-RAM crashes.

Please do not answer questions in the comments. There is a nice big box underneath where answers go. @Harry - if you find the answer yourself (as you did it seems) feel free to make an answer yourself.

RAM is precious on a microcontroller, PROGMEM (program memory) not quite as much so. On the Arduino Uno and the Nano (using an Atmega328P) you have:

1 kB of EEPROM
2 kB of RAM
32 kB of PROGMEM

Clearly, there is a lot more program memory than RAM.
Variables are copied into RAM at program startup
The problem with constants in general (including string constants like "hello") is that the compiler generates code to copy them into RAM at program startup, because most C functions do not expect to find data in PROGMEM. (It has to generate different instructions to access PROGMEM).
Benchmark memory use
To test memory use, I'll start off with a sketch that simply returns how much memory is free, without doing anything else. Tested on IDE 1.0.6, Arduino Uno, on Ubuntu.
#include "memdebug.h"

void setup ()
  {
  Serial.begin (115200);
  Serial.println ();
  Serial.print (F("Free memory = "));
  Serial.println (getFreeMemory ());
  }  // end of setup

void loop () { }

Output:
Free memory = 1702

Since we started with 2048 bytes of RAM, already we have used 2048 - 1702 = 346 bytes. These are used as follows:
34 bytes for the HardwareSerial instance (Serial)
64 bytes for the Serial transmit buffer
64 bytes for the Serial receive buffer
4 bytes for the Serial transmit buffer head and tail pointers
4 bytes for the Serial receive buffer head and tail pointers
9 bytes for keeping track of millis / micros
4 bytes for memory allocation (__malloc_heap_start, __malloc_margin)
128 bytes for the heap safety margin
6 bytes for a few nested function calls (main -> setup -> getFreeMemory)
16 bytes for the compiler vtable for HardwareSerial
4 bytes for variables __brkval and __flp (used in memdebug)
2 bytes pushed onto the stack in main (to save registers)
2 bytes pushed onto the stack in setup (to save registers)
4 bytes pushed onto the stack in getFreeMemory (to save registers)
1 byte because the stack pointer starts at 0x8FF rather than 0x900

(That's 346 bytes accounted for)
Tips
The stack starts at the highest possible address and grows downwards. Each function call would add 2 bytes to the stack (the return address) plus any local (auto) variables would be allocated there.
The heap safety margin is a buffer between the top of the heap and the bottom of the stack. Without it, if you did a "malloc" and got all available memory, there would be no memory left for function calls and local variables in functions.
The vtable is used by the compiler to generate late bindings for virtual functions used by classes.
The compiler generates code to push registers onto the stack when you call a function (the registers used inside that function) so that if the same register was used by the calling function, it would not be corrupted.
Printing constants
Let's print a constant by adding this line:
  Serial.println ("Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmo");

Output is now:
Free memory = 1630
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmo

So the free RAM has gone down by 72 bytes, which happens to be be how long that string is (allowing one byte for the 0x00 terminator at the end).
Why? Because the string was copied from PROGMEM, where it must be when the Arduino is turned off, into RAM.
The first thing we can do is use the F() macro, which cunningly expands out to print directly from PROGMEM, thus saving RAM. So we change the line above to read:
  Serial.println (F("Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmo"));

Output:
Free memory = 1702
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmo

Back to 1702 bytes of free memory. So, lesson #1 is to use the F() macro as illustrated above whenever printing constants.
More information
I have more information on my page about RAM usage which discusses putting arrays of constants into PROGMEM as well as what I mention above.


text:
Is there accurate connection procedure for connection between an esp32 and ultrasonic sensor(HC-SR04)?
I am currently working on a project which integrates esp32 and HC-SR04 and send the data from HC-SR04 to my own domain. The connection diagram is this

And the code which I use is this,
const int trigPin = 5;
const int echoPin = 18;
#define SOUND_SPEED 0.034
#define CM_TO_INCH 0.393701

long duration;
float distanceCm;
float distanceInch;

void setup() {
 Serial.begin(115200); // Starts the serial communication
 pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
 pinMode(echoPin, INPUT); // Sets the echoPin as an Input
}

void loop() {
 digitalWrite(trigPin, LOW);
 delayMicroseconds(2);
 digitalWrite(trigPin, HIGH);
 delayMicroseconds(10);
 digitalWrite(trigPin, LOW);

 duration = pulseIn(echoPin, HIGH);

 distanceCm = duration * SOUND_SPEED/2;

 distanceInch = distanceCm * CM_TO_INCH;

 Serial.print("Distance (cm): ");
 Serial.println(distanceCm);
 Serial.print("Distance (inch): ");
 Serial.println(distanceInch);

 delay(1000);
}

But the module doesn't give out the distance. Can anyone suggest a better method for connection. Thanks in advance!

Can you be more specific about the problem? If it "doesn't give out the distance", what happens instead? Does it crash? Does it always return the same distance? Is the distance wildly inaccurate? Or something else? You know what you mean, but we don't.

So normally after connection, the output according to the code comes out something like,
Distance(cm): 0.00
Distance(inch):0.00

But when I connect to an Arduino the sensor works perfectly

please add a connection diagram and test code to your post ... your question should stand on its own, without an outside link

Does your variant of the ESP32 board actually give out 5V on the VIN pin?

I checked it using a multimeter and it gives me only about 3 V. I did the same with the arduino UNO and it gave me about 3.3 V at the 5 V pin.

If the Arduino is giving you 3.3V at the 5V pin either your Arduino is broken, or you are drawing massive currents from it, or your multimeter doesn't work, or you don't know how to use your multimeter properly.

I know how to use a multimeter when I see one @Majenko. I use only one ultrasonic sensor so know way the sensor is gonna draw massive current from the esp32

Then there must be something wrong somewhere if you are only measuring 3.3V on the 5V pin of the Arduino...

Suriya,
You aren't crazy - it appears the ESP32 GPIO pins (at least the ones I tested) won't drive the HC-04 sonar sensor trigger pin sufficiently high to trigger a sonar pulse.  I tested the NewPingExample.pde code example from the NewPing library's 'example' folder on both a MEGA2560 and a ESP32_DevKitC_V4. The MEGA implementation worked right off the bat, but I never could get the ESP module to work.  So, I took a look at the Trigger/Echo pin (by default the NewPing.h file uses the 'Single Pin' mode, so you have to make sure the TRIGGER_PIN and ECHO_PIN defines use the same pin).  The two scope traces below are from the MEGA2560 and the ESP32.  As you can see, the ESP32 output only goes to 1.865V - not high enough to actually trigger the device.  The MEGA implementation output goes to over 3V and consistently triggers the echo (the big rectangle to the right of the narrow trigger signal).
You might want to try using the STMicro VL53L0X time-of-flight LIDAR chip instead - it is much smaller, uses less current, and doesn't suffer from self-interference if you plan to use more than one sensor. See this post on my blog site for some ideas

Thank you for the reply @starship15. I really appreciate your time for clarifying me with results!


text:
SparkFun RedBoard PTH Kit wrongly configured hardware
I have a SparkFun RedBoard PTH Kit. It's not made by SparkFun, but by https://inmotion.pt (that doesn't exist anymore). I soldered it, and bought a FTDI adapter, but when I try to upload the blink example the Arduino IDE I get this error:
Sketch uses 1030 bytes (3%) of program storage space. Maximum is 32256 bytes.
Global variables use 9 bytes (0%) of dynamic memory, leaving 2039 bytes for local variables. Maximum is 2048 bytes.
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0xa6
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0xa6
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 3 of 10: not in sync: resp=0xa6
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 4 of 10: not in sync: resp=0xa6
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 5 of 10: not in sync: resp=0xa6
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 6 of 10: not in sync: resp=0xa6
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 7 of 10: not in sync: resp=0xa6
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 8 of 10: not in sync: resp=0xa6
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0xa6
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0xa6
Problem uploading to board.  See https://support.arduino.cc/hc/en-us/sections/360003198300 for suggestions.

Or if I try to reset while uploading:
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x63
avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0xff
avrdude: stk500_getsync() attempt 3 of 10: not in sync: resp=0xfe
avrdude: stk500_getsync() attempt 4 of 10: not in sync: resp=0xff
avrdude: stk500_getsync() attempt 5 of 10: not in sync: resp=0xfe
avrdude: stk500_getsync() attempt 6 of 10: not in sync: resp=0xff
avrdude: stk500_getsync() attempt 7 of 10: not in sync: resp=0xff
avrdude: stk500_getsync() attempt 8 of 10: not in sync: resp=0xfe
avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0xfe
avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0xff
Problem uploading to board.  See https://support.arduino.cc/hc/en-us/sections/360003198300 for suggestions.

And the link here at the end suggests the problem is wrongly configured hardware: https://support.arduino.cc/hc/en-us/articles/4401874331410--Error-avrdude-when-uploading
So think the problem is that when I connect the ports from the Arduino to the FTDI, two ports don't match:

simulate this circuit – Schematic created using CircuitLab

Here's a picture of the soldering, though I don't think that is the problem: https://i.sstatic.net/aa2j5.jpg

I am using these drivers: https://github.com/MCUdude/MiniCore for the Arduino. With these settings:

The options only have these variants:

328P / 328PA
328 / 328A
328PB

But my processor says 328P-PU. I tried every one of them and they all give me the same error above.

Can I even use this FTDI adapter? If yes what would the setup be?

RX goes to TX, transmit to receive. one Gnd is enough and you don't need CTS

Thanks, but still having the same errors

try to manually reset the board while the IDE attempts to upload

With the reset button on board?

I tried to reset it many times but still have the same errors :( Also updated the question with new information that might help.

select variant 328P/328PA

As I said in the post I've tried every one of them and tried again now after you. All of the variants give the same errors.

I got it to work!
The problem was that I had connected the Arduino to the FTDI and not both the FTDI and the Power Brick. The SparkFun product page said that you can use like that, and the version from https://inmotion.pt that I have is identical so I though it should have worked.
Thank's a lot @jurah for you help!


text:
ESP32-C3 SPI Class documentation/features?
ESP32-C3 has a nice feature called GPIO Matrix which allows to map most of it's peripherals to any GPIO pin. And it has feature called IO_MUX which allows direct & faster operations for some of the high speed peripherals, including SPI. The API from ESP-IDF (HAL SDK) provides some library documentation on SPI functions.
But Arduino-ESP32 core documentation seems to completely miss SPI library & it's functions. It refers to basic Arduino SPI class, but it lacks description of features ESP32 family has.
I've found this example for ESP32 (note that I'm looking for ESP32-C3 info) which sets SPI pins through SPI.begin method actually.
I've also found this source which seems to feature a lot of SPI internal HAL functions. And a C++ SPI class sources are here. But it's actually doesn't have any useful comments on how to use IO_MUX or allowed values for ::setFrequency() method.
So basically I'm asking for a documentation on ESP32-C3 Arduino specific SPI class features. But to narrow things down I'm actually looking now how to initialize SPI2 (which is the only generally available SPI master on C3) as IO_MUX at the fastest SPI clock speed possible from the Arduino core/SPI class. Any suggestions are also welcomed!

Hi NStorm, I know your post is from a while ago, but for everyone's and anyone's sake: I'm still figuring out how to use the GPIO Matrix with ESP32-C3 and Arduino, but if you are using Arduino with it, then the default pins for SPI2 are defined here. Depending on whether you're initializing the peripheral yourself or a device is doing it for you, there are ways to pass in a different SPI clock speed.


text:
Reading & writing a configuration file on an Adafruit Circuit Playground Express
I would like to store an application's configuration in a file stored on the Circuit Playground Express (CPX) flash. The application itself needs to be able to update the configuration file. Things I need to store are basic, for example:

NeoPixel brightness (eg. brightness = 0.9)
NeoPixels on/off (eg. NP_enable = [0,0,1,0,1,0,1,1,1,1]

ArduinoJason seems appropriate, but I cannot even get to the point of writing files to the CPX. The TinyUSB libraries are supposed to give the ability to write to the CPX SPI Flash, but I cannot get any of the examples included with this library to compile.
I am trying to compile the msc_external_flash example provided with the TinyUSB library. I get the following 2 errors:
In file included from /home/pi/Arduino/libraries/Adafruit_TinyUSB_Library/examples/MassStorage/msc_external_flash/msc_external_flash.ino:28:0:
/home/pi/Arduino/libraries/Adafruit_TinyUSB_Library/src/Adafruit_TinyUSB.h:31:2: error: #error TinyUSB is not selected, please select it in "Tools->Menu->USB Stack"
#error TinyUSB is not selected, please select it in "Tools->Menu->USB Stack"
^~~~~
msc_external_flash:65:6: error: #error No QSPI/SPI flash are defined on your board variant.h !
#error No QSPI/SPI flash are defined on your board variant.h !
^~~~~

The board selected is SAMD-->Circuit Playground Express.
There is no Tools menu item for selecting the USB stack.
Regarding the second error,
From msc_external_flash.ino:
  #if defined(EXTERNAL_FLASH_USE_QSPI)
    Adafruit_FlashTransport_QSPI flashTransport;
  #elif defined(EXTERNAL_FLASH_USE_SPI)
    Adafruit_FlashTransport_SPI flashTransport(EXTERNAL_FLASH_USE_CS, EXTERNAL_FLASH_USE_SPI);
  #else
    #error No QSPI/SPI flash are defined on your board variant.h !
  #endif

of the files named variant.h, this looks like the best candidate:
/home/pi/.arduino15/packages/arduino/hardware/samd/1.8.12/variants/circuitplay/variant.h
but the file does not contain the string "EXTERNAL_FLASH", nor anything I see that is CPX specific.
Arduino version is 1.8.19, which I am running on a Raspberry Pi 3 B+ running Buster.
Thanks,
Scott

please describe the problem and ask a question ... this site is not a forum

ArduinoJson has an example that reads a configuration file from the SD card. See JsonConfigFile.ino. You can easily adapt it for any other filesystem, such as SPIFFS and LittleFS.

install the Adafruit SAMD core. it looks like you are using the Arduino SAMD core, which has only basic support for the Adaruit board

The board selected is SAMD-->Circuit Playground Express. I can run other CPX examples, like IRNeoPixels, I assume I have the Adafruit SAMD core.

yes but you can't compile Adafruit specialties with the Arduino SAMD core

The problem was using the Arduino SAMD board core instead of the Adafruit SAMD board core. The Adafruit SAMD board core is not visible unless you add:
https://adafruit.github.io/arduino-board-index/package_adafruit_index.json
to the "Additional Boards Manager URLs:" field of the Arduino IDE preferences panel.
Once you do that...
Then install the "Adafruit SAMD Boards" from the Arduino IDE Boards Manager.
Then select the menu item:
Tools -->
Board: -->
Adafruit SAMD (32-bits ARM Cortext-M0+ and Cortext-M4) boards -->
Adafruit Circuit Playground Express (SAMD21)
I have not seen this procedure in any Adafruit documentation.

https://learn.adafruit.com/adafruit-feather-m0-basic-proto/setup


text:
How do I control the rotation of my servo?
#include <Servo.h> // servo library
Servo servo;
int trigPin = 5;
int echoPin = 6;
int servoPin = 7;
int led= 10;
long duration, dist, average;
long aver[3];   //array for average

void setup() {
  Serial.begin(9600);
  servo.attach(servoPin);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  servo.write(0); // close cap on power on
  delay(100);
  servo.detach();
}

void measure() {
  digitalWrite(10,HIGH);
  digitalWrite(trigPin, LOW);
  delayMicroseconds(5);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(15);
  digitalWrite(trigPin, LOW);

  pinMode(echoPin, INPUT);
  duration = pulseIn(echoPin, HIGH);
  dist = (duration/2) / 29.1; // obtain distance
}

void loop() {
  for (int i=0; i<=2; i++) {
  // average distance
  measure();
  aver[i] = dist;
  delay(10); // delay between measurements
  }

  dist = (aver[0]+aver[1]+aver[2])/3;

  if (dist < 50) { // Change distance as per your need
    servo.attach(servoPin);
    delay(1);
    servo.write(0);
    delay(3000);
    servo.write(150);
    delay(1000);
    servo.detach();
  }

  Serial.print(dist);
}

This is my first time in robotics. The servo is a Tower Pro SG90. It rotates over 360° and ony spins in one direction, but I want it to rotate for just about 90° and to rotate back to its original place after. This is the code I used. I'm making a trash bin where the lid automatically opens.

Please no code as image. copy and paste the code as text and format it correctly by selecting it in the question editor and clicking on the {} button

You should buy a normal servo, not a servo with continuous rotation. The Tower Pro SG5010, for example, should basically meet your needs.
But depending on the size of the bin and the mechanical control of the lid, you may want to choose a servo with greater actuating force.

A continuous rotation servo cannot be set to specific angles, only specific speeds. That's the point for continuous rotation servos.
So for your trash bin you should buy a normal servo (not continuous rotation). Such servo can be moved to specific angles between 0 and 180°.


text:
How to set number in address field?
I want to build structure of record. The problem is that I can't build the address field correctly. Can any one help me?
P.s: the address[16:2] is start from bit 61 to bit 47 so please you can't say you should shift it by 32.

For this I would use bit fields:
typedef union {
    struct {
        uint8_t raw[8]; // Raw access to the bytes
    };
    struct {
        unsigned data:32;
        unsigned cs14:1;
        unsigned cs13:1;
        unsigned cs12:1;
        unsigned cs11:1;
        unsigned cs10:1;
        unsigned cs9:1;
        unsigned cs8:1;
        unsigned cs7:1;
        unsigned cs6:1;
        unsigned cs5:1;
        unsigned cs4:1;
        unsigned cs3:1;
        unsigned cs2:1;
        unsigned cs1:1;
        unsigned cs0:1;
        unsigned address:15;
        unsigned parity:1;
        unsigned stop:1;
    };
    struct {
        unsigned :32;
        unsigned cs:15;
        unsigned :17;
    };
} Packet;

Then you can:
Packet p;
p.data = 0x493DE26CUL;
p.address = 0x13f3;
p.cs3 = 1;
// or
p.cs = 0x0080;

etc.


text:
Multiple Arduinos connected to one display
I have one display screen, and 5 Arduino Nanos. They are checking to see if passwords in a text file hash to a specific hash, then display it on the screen when found.
Since they aren't all sending signals to the screen, is it possible to wire it so that all of them are connected to one screen, and then have the one that finds the correct password send the signal to the screen, and how would I go about doing this?

What type of screen is it? What protocol are you using to communicate with it?

I'd have a coordinator that listens to the nanos and gets the password to display. I'd also not use nanos.

in theory yes.  one can make a multiplexer for just about any type of circuit.  just need to make sure you have some exclusionary mechanism that ensures only one can talk (usually first one gets it until it sends a signal saying it is done)

k thanks, I will work with the coordinator idea, also I know nanos aren't the best option but for what I'm doing they are certainly very cheap and I already have around 6, the project involves clustering them so if I were to use unos or something else the price would increase drastically

Why do you think you need 5 Arduino Nanos? Why not just one? And why do they all need to be connected to a display? The display has some kind of display driver IC (this highly depends on your display: 7-Seg, LCD, OLED,...) and this ONE controller has some kind of interface that you can just connect ONE master to. That should totally be enough.

well the idea is that it is a cluster, I am splitting up the work between them, one arduino can test one at a time, 5 can test five at a time, the idea is every nano has one fifth of a password list(stored on an sd card), that they are checking constantly, then when one of them finds it, it will display it on the screen

It should be possible to connect all nanos to the display, just like you would if there was only one nano as long as there is only one nano that actively drives the bus (what ever bus that is). All the other nanos need their bus pins to be inputs (not configured for the bus). So you could have them being inactive by default and only access the bus once they found a matching hash.
But: if multiple nano's are configured for bus usage at a time, communication would be corrupted. In case the display uses a push-pull bus (SPI, UART, ...) this is even electronically an issue, because their bus pins would short the supply voltage and possibly get destroyed. So you need some kind of protection in that case, a current limiting resistor in the easiest form.
As mentioned in comments, the "clean" solution is to have one dedicated controller to be the coordinator.
Some thoughts:

there is a real (not just a hypothetic) chance for bus contentions, because multiple passwords lead to the same hash and you even want to compare hashes for multiple passwords. The occurence of such a collision needs to be expected, though it is not predictable when or if it actually happens.

you probably want to configure the cluster, e.g. to distribute the hash of interest among the Nanos or to stop the cluster when a match is found. Those things would be easier if there's one dedicated master which you can communicate with directly.

the coordinator would always have control over the display. What if you wanted to continously display information on the screen, e.g. a progress bar? That would be difficult to implement afterwards when there's no master.


text:
Conversion from ASCII uint8_t to string
I am sending a string from a Raspberry Pi to an ESP32 via BT. I am getting one ASCII value per line. How to convert it into one whole String? I tried as follows, but I get an error while running the method  printReceivedMEssage(buffer):
invalid conversion from 'uint8_t {aka unsigned char}' to 'uint8_t* {aka unsigned char*}' [-fpermissive]
uint8_t buffer;

void printReceivedMessage(const uint8_t* buf) {
  char string_var[100];
  size_t bufflen = sizeof(buf);

  for (int i = 0; i < bufflen; ++i) {
    Serial.println(static_cast<char>(buf[i]));
  }

  memcpy( string_var, buf, bufflen );
  string_var[bufflen] = '\0'; // 'str' is now a string
  Serial.print("string_var=");
  Serial.println(string_var);
}

void loop() {
  buffer = (char)SerialBT.read();
  Serial.println(buffer); // THIS SHOWS AN ASCII VALUES ONE PER LINE
  printReceivedMessage(buffer); // ERROR
  delay(1000);
}

https://majenko.co.uk/blog/our-blog-1/reading-serial-on-the-arduino-27

Your buffer is only one byte

There are multiple problems with your code. They suggest, that you don't know what strings really are.
In C/C++ strings are actually arrays of characters (char). A uint8_t is the same size of a single character, so you can only save a single character in it. For saving a string, you would need an array of them. So buffer should be declared like
uint8_t buffer[20] = "";

Now buffer can hold a string of 19 characters. The 20th character is the terminating null character \0, which marks the end of a string. You must always leave enough space for the null character to terminate your strings correctly.
Serial reading: There are many ways how you can read from Serial. Look at the Serial.readStringUntil() function, which will read from Serial until it reaches a specified character. This way you can easily divide the continuous stream of bytes from Serial into distinct messages. It is common to end all ASCII encoded messages with a newline \n character to mark the end of the message. With Serial.readStringUntil('\n') (note the single quotes for a single character) you will read until it reaches the newline character (or it times out). You can then process the read string as a full message.
Providing a string as parameter to a function: In C/C++ you cannot just provide an array as parameter to a function as other variables. It is a bit more complex. That is because internal the array consists just of a few bytes in a row and the variable just points to the first element of it. It is a pointer (thats a specific C/C++ term). Pointers are marked with *, which you already did with your
void printReceivedMessage(const uint8_t* buf)

function. So the parameter is just a pointer to a uint8_t. That also explains the error message, because you provided an uint8_t, but the function expects a pointer to uint8_t instead. While you still can access the array data through this parameter (given you have implemented what I wrote above about the array), sizeof(buf) will only give you the size of the pointer (2 bytes on most Arduino platforms). So you need to add a parameter and also provide the size of the array. Or you can utilize the correct termination of strings with the null character and get the length of the string with strlen(). That functions iterates the pointer of the array, until it finds the null character and gives you the resulting length.


text:
ESP32 access point with an ENC28J60 ethernet module
Does anyone know if the following is possible? Any advice would be much appreciated.
I am programming an Ethernet connected Arduino to be a webserver. What would be ideal is a small portable "router" so I can take the whole test setup and my laptop without depending on my home/company network.
My idea:

Set up an ESP32 as an access point
Connect an ENC28J60 module to it

I hope:

My laptop can connect to the ESP over WiFi (status: done)
My board can connect over UTP
They both get IP addresses
I can test the Arduino webserver from my laptop

What I found is that I could use the Ethercard for ESP32 or the [EthernetENC][2] libraries.
I've been trying with EthernetENC, but no luck. Is this even possible?

This is my minimal code for the ESP32 so far:
#include <WiFi.h>
#include <SPI.h>
#include <EthernetENC.h>

const char* ssid = "ESP32router01";
const char* pass = "01234567";          // At least 8 characters

void setup() {
  WiFi.softAP(ssid, pass);
  Ethernet.init(5);
}

void loop() {
}

remove the Arduino and the ENC28J60 from the project

https://forum.arduino.cc/t/adapter-for-ethernet-shield-to-communicate-on-wifi/529679/3

esp8266 Arduino supports routing between network interfaces and supports enc28j60 as network interface in WiFi library. STA and SofftAP are the network interfaces you know. I don't know if it supports routing for the 'new' network interlaces

@Juraj : Thanks, the TL-WR702N would be the easy/convenient way, I'll consider that. But I also have an ESP8266  at hand so I can explore your suggestion.

I'm still planning on doing this project and have found: https://github.com/martin-ger/esp_wifi_repeater#enc28j60-ethernet-support - This library supports an ENC28J60 ethener adapter so that's what I'll be trying, I don't know when but I'll try to post my findings.

Did you figure it out? I have a similar problem.