text:
need help for exam please (deadline tomorrow)
what we're required to do on exam
You don't have to completely give me the answers, I just started learning this yesterday so I'm pressured on learning it properly + the exam, thx

We can't help you if you don't tell us at least what you have available. (Sensors, Boards, etc.).

That doesn't mention what sensor you are using for the intruder alarm. I'm sure there are several tutorials and opensource projects about this on the web. Have you searched for them?

I just asked someone and they said we didn't have to use sensors, just make sure 3 LED lights and the buzzer works together.

That doesn't make much sense. Where do you get the distance from if you don't use sensors?

I'm not sure as well, the tool for that isn't discussed at all in our handouts except now which didn't specify what we should use. I think it's the ultrasonic distance sensor since that's what I saw on my kit

I'm guessing the question is just asking you to create a conditional loop that will have the Arduino illuminate the appropriate LED when each stipulated condition is met.

You should easily find tutorials for your sensor. The ultrasonic sensor typically used in many kits is the HC-SR04. Just google for something like "HC-SR04 tutorial"

Please include the rest of the question in the question, instead of a link to a picture of the text of the question. Being specific about the actual problem(s) faced is helpful. I might consider a tutorial, or writing this exam off and starting sooner for the next one.

As written, the exam does not look like you are expected to build
something functional. Rather, that you must show that you understand how
to drive LEDs and a buzzer, how to write conditional code, etc. I would
suggest using a pot to simulate a distance reading, and writing
something along these lines:
void loop() {
    // Simulate a distance reading between 0 and 4 meters.
    float distance = analogRead(A0) * (4.0/1023);

    // React to the sensor reading.
    if (distance < 3) {
        // ...
    }
    // etc.
}


text:
LoRa recieves only 2-4 packets, then stops working
I'm working on LoRa project using [Ai-Thinker RA-01 SX1278 433MHz LoRa][1] with [sandeepmistry/arduino-LoRa][2] library. I modified LoRaReciever example so it looks like this
#include <SPI.h>
#include <LoRa.h>

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

  Serial.println("LoRa Receiver");

  if (!LoRa.begin(433E6)) {
    Serial.println("Starting LoRa failed!");
    while (1);
  }
}

void loop() {
  // try to parse packet
  int packetSize = LoRa.parsePacket();
  LoRa.onReceive(onReceive);
}
void onReceive(int packetSize) {

  if (packetSize) {
    // received a packet
    Serial.print("Received packet '");

    // read packet
    while (LoRa.available()) {
      Serial.print((char)LoRa.read());
    }

    // print RSSI of packet
    Serial.print("' with RSSI ");
    Serial.println(LoRa.packetRssi());
  }
}

I receive 2-4 packets successfully, but then I don't receive any, even though the transmitter is still transmitting. (If I restart my Arduino it receives 2-4 packets again).
I have both LoRa modules really close to each other (about 10 cm) could it cause the problem? - Even when I tried like 15m with walls, problem stayed.
Sometimes, the receiver gets bugged and starts receiving packets all the time (one packet like 50 times), when it's bugged like this, it doesn't stop receiving (unique) packets after any number.
Do you know where the problem could be? Thanks.
I use Arduino Mega
#include <SPI.h>
#include <LoRa.h>

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

  Serial.println("LoRa Receiver");

  if (!LoRa.begin(915E6)) {
    Serial.println("Starting LoRa failed!");
    while (1);
  }
}

void loop() {
  // try to parse packet
  int packetSize = LoRa.parsePacket();
  if (packetSize) {
    // received a packet
    Serial.print("Received packet '");

    // read packet
    while (LoRa.available()) {
      Serial.print((char)LoRa.read());
    }

    // print RSSI of packet
    Serial.print("' with RSSI ");
    Serial.println(LoRa.packetRssi());
  }
}

This is original LoRaReciever example, but I don't receive anything using it.
[1]: https://www.laskarduino.cz/ai-thinker-ra-01-sx1278-433mhz-lora-modul/
[2]: https://github.com/sandeepmistry/arduino-LoRa

start with the example code ... it seems that you made questionable changes to the example code

When using the default example code, I don’t get anything recieved at all.

I found the solution.
The problem was with calling onRecieve in loop not in setup
It should have looked like this...
#include <SPI.h>
#include <LoRa.h>

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

  Serial.println("LoRa Receiver");

  if (!LoRa.begin(433E6)) {
    Serial.println("Starting LoRa failed!");
    while (1);
  }
  LoRa.onReceive(onReceive);
  LoRa.receive();
}

void loop() {
  //do nothing
}
void onReceive(int packetSize) {

  if (packetSize) {
    // received a packet
    Serial.print("Received packet '");

    // read packet
    while (LoRa.available()) {
      Serial.print((char)LoRa.read());
    }

    // print RSSI of packet
    Serial.print("' with RSSI ");
    Serial.println(LoRa.packetRssi());
  }
}

source: Stack Exchange

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

sort: votes


text:
Controlling DC motor with joystick using Arduino
I am working on modifying code to control two DC motors with a joystick using Arduino. The code I have works, but the motor accelerates very rapidly and is difficult to control. I would appreciate any help or pointers to get the motor under control. Here is the code I have so far:
const int ledPin = 3; //Led to Arduino pin 3 (PWM)

//Variables
bool started= false;//True: Message is started
bool ended  = false;//True: Message is finished
char incomingByte ; //Variable to store the incoming byte
char msg[3];    //Message - array from 0 to 2 (3 Drive_Analog_Values -PWM - e.g. 240)
byte index;     //Index of array
bool started1= false;//True: Message is started
bool ended1  = false;//True: Message is finished
char msg1[3];    //Message - array from 0 to 2 (3 Drive_Analog_Values - PWM - e.g. 240)
byte index1;     //Index of array
bool started2= false;//True: Message is started
bool ended2  = false;//True: Message is finished
char msg2;
bool started3= false;//True: Message is started
bool ended3  = false;//True: Message is finished
char msg3;
int Fwd_Drive = 0;
int Rev_Drive = 0;
int Left_Turn = 0;
int Right_Turn = 0;
char Dump = '0';
char Retract = '0';

void setup() {

//setup interrupts
cli();//stop interrupts

//set timer1 interrupt at 1Hz
  TCCR1A = 0;// set entire TCCR1A register to 0
  TCCR1B = 0;// same for TCCR1B
  TCNT1  = 0;//initialize counter value to 0
  // set compare match register for 1hz increments
  OCR1A = 15624;// = (16*10^6) / (1*1024) - 1 (must be <65536)
  // turn on CTC mode
  TCCR1B |= (1 << WGM12);
  // Set CS10 and CS12 bits for 1024 prescaler
  TCCR1B |= (1 << CS12) | (1 << CS10);
  // enable timer compare interrupt
  TIMSK1 |= (1 << OCIE1A);

 sei();//allow interrupts

  //Start the serial communication
  Serial.begin(9600); //Baud rate must be the same as is on xBee module
  pinMode(ledPin, OUTPUT);
  pinMode(13, OUTPUT);
  pinMode(2, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
}

ISR(TIMER1_COMPA_vect){ //timer1 turns off all values every 1 second
   analogWrite(5, 0);
   analogWrite(6, 0);
   analogWrite(9, 0);
   analogWrite(10, 0);
   digitalWrite(2,LOW);
   digitalWrite(4,LOW);
}

void loop() {
  //digitalWrite(13, LOW); //Debug LED
  while (Serial.available()>0){
        //Read the incoming byte
        incomingByte = Serial.read();
        //digitalWrite(13, HIGH);//Debug LED
        //Start the message when the '<' symbol is received
        if(incomingByte == '<'){
            started = true;
            index = 0;
            msg[index] = '\0'; // Throw away any incomplete packet
        }

        //End the message when the '>' symbol is received
        else if(incomingByte == '>'){
            ended = true;
            break; // Done reading - exit from while loop!
        }
        //Read the message!
        else{
            if(index < 4){ // Make sure there is room
                msg[index] = incomingByte; // Add char to array
                index++;
                msg[index] = '\0'; // Add NULL to end
            }
        }

        if(incomingByte == '['){
            started2 = true;
            msg2 = '\0';
        }
        else if(incomingByte == ']'){
            ended2 = true;
            break; // Done reading - exit from while loop!
        }
        //Read the message!
        else{
            msg2 = incomingByte;
        }
      if(incomingByte == '{'){
            started3 = true;
            msg3 = '\0';
        }
        else if(incomingByte == '}'){
            ended3 = true;
            break; // Done reading - exit from while loop!
        }
        else{
            msg3 = incomingByte;
        }
    }

 if(started && ended){//Driving Logic
        int Drive_Analog_Value = atoi(msg);
        //analogWrite(ledPin, Drive_Analog_Value);//Only for debugging
        //Serial.println(Drive_Analog_Value); //Only for debugging
        if(Drive_Analog_Value>130){
            Rev_Drive = 0;
            Fwd_Drive = map(Drive_Analog_Value, 131, 255, 0, 70);
        }
        else if(Drive_Analog_Value<124){
            Fwd_Drive = 0;
            Rev_Drive = map(Drive_Analog_Value, 0, 123, 70, 0);
        }
        else{
            Fwd_Drive = 0;
            Rev_Drive = 0;
        }
        analogWrite(5, Fwd_Drive);
        analogWrite(6, Rev_Drive);
        index = 0;
        msg[index] = '\0';
        started = false;
        ended = false;
}

that cannot be all of your code ... it does not compile

please format your code properly the if, else if and else should be at the same indent level

Have you tried outputting the drive numbers (like Fwd_Drive) to Serial and look if they look correct?

The numbers aren't  correct.  They are way higher than they should be.  Would it be as simple as changing the mapping values?

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


text:
Robotdyn esp8266 interrupt from arduino timing
I use a Robotdyn, uno+wifi r3 atmega328p+esp8266. I need to control motor speed and operate few servos. Since the uno has a single timer, I use the esp8266 pin 2 to control motor speed, while the arduino pins to control servos.
I've used the serial channel for uno to send a list of speeds to operate the motors to the esp.
Now I need to trigger esp to change from one speed to another, and I was considering using one of the uno pins to trigger an interrupt for the esp, for this notification. I need the speed change as instantaneous as possible. I am using I2C 5v to 3.3v logic level converter for raising the interrupt from uno pin to pin 4 of esp.
Now the question, how long should I hold the uno pin high for the interrupt to be detected? A quick filp;
digitalWrite(outGoingIntrPin, HIGH);
digitalWrite(outGoingIntrPin, LOW);
seems to sporadically work. I think I need to introduce a delay between these statements, but I do not know how much should that delay be.
Any suggestions to improvise is welcome.

The Uno has 3 Timers in total. Considering that Timer0 is used for delay()/millis() and another timer for the servo library you have still one Timer left to operate your (I suspect 2) DC motors


text:
How to Independently run positional and continuous servos using millis()?
I am setting up 3 servos (2 position servos and 1 '360' continuous rotational servo) with Arduino. but I failed to run these independently. It runs one after another. I wish to run it in loop independent to each other. Here is the code which I use to run positional servo and CR (360) servo. default servo positions are 90.
*CR 360 servo should be running independently 90-60-120-90 (in loop)
*Pos servo should be running one after another (in loop)
To run positional servos (tilt/pan):
//tilt servo
    for (pos = 90; pos >= 60; pos -= 1)     //90 ~ 60
  {
    tiltservo.write(pos);
    delay(30);
  }

  for (pos = 60; pos <= 120; pos += 1)      //60 ~ 120
  {
    tiltservo.write(pos);
    delay(30);
  }

  for (pos = 120; pos >= 90; pos -= 1)       //120 ~ 90
  {
    tiltservo.write(pos);
    delay(30);
  }

//pan servo
for (pos = 90; pos >= 60; pos -= 1)          //90 ~ 60
  {
    panservo.write(pos);
    delay(30);
  }

  for (pos = 60; pos <= 120; pos += 1)       //60 ~ 120
  {
    panservo.write(pos);
    delay(30);
  }

  for (pos = 120; pos >= 90; pos -= 1)       //120 ~ 90
  {
    panservo.write(pos);
    delay(30);
  }

To run CR 360 servo:
 legservo.writeMicroseconds(1600);      //CW
 delay(5000);                           //run for 5s
 legservo.writeMicroseconds(1300);      //CCW
 delay(5000);                           //run for 5s

Tried this to independently run CR servos, but how to put some wait (3s-4s) in between FW and RW.
if (millisNow - lastMillis >= 10000)
{
lastMillis = millisNow;
if (crservoState == 0)
 {
   legservo1.writeMicroseconds(2150); //FW
   crservoState = 1;
 }
  else
 {
   legservo1.writeMicroseconds(850);  //RW
   crservoState = 0;
 }
}

Trial code after suggestions:
uint32_t milliSNow = millis();

  if (milliSNow - lastTimeServoRotate >= 1000)
  {
    if (crservoState == 0)
    {
      if (milliSNow - lastTimeServoRotate >= 10000)
      {
        legservo1.writeMicroseconds(2150);    //FW run
        crservoState = 2;
        lastTimeServoRotate = milliSNow;
      }
    }

    if (crservoState == 1)
    {
      if (milliSNow - lastTimeServoRotate >= 10000)
      {
        legservo1.writeMicroseconds(850);     //RW run
        crservoState = 3;
        lastTimeServoRotate = milliSNow;
      }
    }

    if (crservoState == 2)
    {
      if (milliSNow - lastTimeServoRotate >= 3000)
      {
        legservo1.writeMicroseconds(1500);    //FW STOP
        crservoState = 1;
        lastTimeServoRotate = milliSNow;
      }
    }

    if (crservoState == 3)
    {
      if (milliSNow - lastTimeServoRotate >= 3000)
      {
        legservo1.writeMicroseconds(1500);     //RW STOP
        crservoState = 0;
        lastTimeServoRotate = milliSNow;
      }
    }
  }

https://arduino.stackexchange.com/questions/83977/how-to-run-2-different-servo-continuous-rotation-and-regular-servo-in-parallel/83984#83984

@ArduinoFan thanks for sharing the link, I tried this but this is for controlling same type of servos, in my case i need to set up positional servo and CR as well, so its getting mixed operation. while running pan/tilt one after another with continuously running CR servo CW/CCW with wait time of 2s. any help would be appreciated. Thanks.

The last code snippet you posted should work, albeit with 10 second (rather than 3–4 s) pauses between FW and RW. If it doesn't work, you have an issue elsewhere in your code. Maybe you are sharing the lastMillis variable with the code handling the positional servos?

@EdgarBonet Thanks for your comment. This code works to run CR in this manner..

when start, it run after 10s

servo1 run for 10s FW then immediately run for 10s RW in loop. but I wish to hold/wait for 3s after 10s FW and 10s RW run each.

'lastMillis' is only used for CR servo, its not clashing with POS servo variable.

Re “I wish to hold/wait for 3s after 10s FW and 10s RW run each”: This is not in your code snippet. If you want these pauses, you have to explicitly ask the servo to stop, and your cycle has four phases: FW, pause, RW, pause.

@EdgarBonet Thank you. I uploaded it as 'Trial code', Could you please check it?
since its working but the fw/rw run time is 3s instead of 10s and holding time is 10s instead of 3s though i defined it to run for 10s and hold/stop for 3s. where I am mistaking? please suggest~

@EdgarBonet I just flipped (milliSNow - lastTimeServoRotate) check from 10000 to 3000 and it run. (milliSNow - lastTimeServoRotate), this checks the time elapsed time.
But when start, it wait for 10s to run, even I set it to check with >= 1000 (~1s), I didn't get it. Please suggest.

This is covered in the Blink Without Delay Arduino tutorial.
Let me paraphrase the main part of the example code here:
uint8_t ledState = LOW;
uint32_t lastTimeLedChanged = 0;

void loop() {
    uint32_t now = millis();
    if (now - lastTimeLedChanged >= 1000) {

        // Save the last time we updated the LED.
        lastTimeLedChanged = now;

        // Compute the new state of the LED.
        if (ledState == LOW) {
            ledState = HIGH;
        } else {  // ledState is HIGH
            ledState = LOW;
        }

        // Set the LED to the computed state.
        digitalWrite(LED_BUILTIN, ledState);
    }
}

This will make the LED cycle between its two possible states at the
desired rate. You can apply this principle as-is to your continuous
rotation servo.
For the positional servos, the same principle can still be applied, but
there is a catch. Whereas both the LED and the CR servo cycle between
two states, the pair of positional servos goes through many states
(92 240 if I counted correctly). You will thus need:

more variables to store the current state of the servo pair
more code to compute the new desired state
more code to update the state

In order to figure out how to represent the state, you have to look at
your current delay()-based code, see how many calls to delay() are
performed on each full cycle, and figure out how to identify each of
these calls. Each of these delays corresponds to one state of your
system. I would say that you need one variable to know in which of the
for loops you are, and another variable to know the last position you
wrote to the servo in that loop. I will call each of the original for
loops a “phase”. There are two six such phases:

phase 0: tilt: 90° → 60°
phase 1: tilt: 60° → 120°
phase 2: tilt: 120° → 90°
phase 3: pan: 90° → 60°
phase 4: pan: 60° → 120°
phase 5: pan: 120° → 90°

Note there were only two for loops in the original question, but
it was then edited to include six loops, thus I edited my answer.
An then you will need to store the time of the last update, thus:
int phase = 0;  // which of the six phases we are in
int pos = 90;   // last position written to a servo
uint32_t lastTimeServoMoved = 0;

Once you have the proper variables to describe the state, updating it is
not hard. If you have reached the end of a phase, move to the next one.
Then update the position by one step. Thus:
void loop() {
    uint32_t now = millis();
    if (now - lastTimeServoMoved >= 30) {

        // Save the last time we updated a positional servo.
        lastTimeServoMoved = now;

        // Compute the new state.
        if (phase == 0 && pos == 60)
            phase = 1;
        else if (phase == 1 && pos == 120)
            phase = 2;
        else if (phase == 2 && pos == 90)
            phase = 3;
        else if (phase == 3 && pos == 60)
            phase = 4;
        else if (phase == 4 && pos == 120)
            phase = 5;
        else if (phase == 5 && pos == 90)
            phase = 0;
        if (phase == 1 || phase == 4)
            pos += 1;
        else
            pos -= 1;

        // Set the servo to the computed state.
        if (phase < 3)
            tiltservo.write(pos);
        else
            panservo.write(pos);
    }
}

I personally do not like this kind of repetitive code. If you are
comfortable with data structures, I would recommend using an array of
structs to store all the information describing the moves that are done
in each phase:
struct {
    Servo *servo;   // which servo to move
    int step;       // steps by which it moves
    int final_pos;  // final angular position
} moves[] = {
    { &tiltservo, -1, 60 },   // tilt:  90 ->  60
    { &tiltservo, +1, 120 },  // tilt:  60 -> 120
    { &tiltservo, -1, 90 },   // tilt: 120 ->  90
    { &panservo,  -1, 60 },   // pan:   90 ->  60
    { &panservo,  +1, 120 },  // pan:   60 -> 120
    { &panservo,  -1, 90 }    // pan:  120 ->  90
};

Then the actual code becomes simpler:
void loop() {
    uint32_t now = millis();
    if (now - lastTimeServoMoved >= 30) {

        // Save the last time we updated a positional servo.
        lastTimeServoMoved = now;

        // Compute the new state.
        if (pos == moves[phase].final_pos) {
            phase +=1;
            if (phase == 6)
                phase = 0;
        }
        pos += moves[phase].step;

        // Set the servo to the computed state.
        moves[phase].servo->write(pos);
    }
}

thank you so much for your detailed explanation with example. Its good to understand. I tried this but CR servo doesn't wait for 5s between CW and CCW move.
The actual operation should be:
` CR servo:  (in loop)
running CW for 5s,
wait for 2s,
CCW for 5s `
` Pos (pan/tilt) servo:  (in loop)
1st pan move from 90~60, 60~120, 120~90 then
2nd tilt move from 90~60, 60~120, 120~90 `
Please suggest.

@Emlinux: This doesn't seem to match the code in your question. Please, update the question with the relevant information. Try to be as clear as possible, in order to avoid more misunderstandings of your requirements.

sorry for the misunderstanding. I updated it accordingly. Thanks.

Thanks for updating the solution. I understood it. Though I didn't use data structure much, but its good to use it here efficiently. I will prefer to learn and use it like this.
since there is 1 more leg_servo (CR 360) included, I tried to add that in loop with position servos like this. but I am unable to pause that for 2~3 seconds after CW/CCW run for 10s.
if (millisNow - lastMillis >= 10000)  { lastMillis = millisNow;
if (crservoState == 0) { legservo1.writeMicroseconds(2150);
crservoState = 1; } else { legservo1.writeMicroseconds(850);   crservoState = 0; } }

Please suggest some. Thanks.

@Emlinux: Please, try to understand the general approach illustrated by this answer: breaking down the cycle into phases, identifying the individual steps within each phase, figuring out how to encode and update the state... Although the code I show is specific to the tilt and pan servos, the approach is generic and, if you understand it, you can apply it to the CR servo. Do not rush into writing code: do the thinking and analysis first.

yes @Edgar Bonet, I tried the same so I shared few lines of code in my previous post. since I need to run the CR servos independent to POS servos (pan/tilt), I tried to run it independently for 10s FW and 10s RW and it runs but I am not sure how to put some wait_delay (like 3s) between FW and RW. Thanks.

since its not well visible the code mentioned in my previous comments, i put it in the end of the post. please check and guide. Thanks.


text:
Can the Arduino-HomeKit-ESP8266 library be used with the WiFi101 library?
I am currently trying to create a project to setup a HomeKit remote control to control my smart home devices with the Arduino-HomeKit-ESP8266 library.
I am currently using a Arduino-based TinyCircuit device with the Atmel ATWINC1500 WiFi module. Is there any solutions available or any way to modify the code to make it work with my current WiFi shield, as it uses the WiFi101 library instead of the WiFi library?
I am trying to test the "ConnectWithWPA.ino" from the WiFi101 examples with the HomeKit library. The code requires a "pgmspace.h" which I am not too sure what is it for.
ConnectWithWPA.ino:
/*

 This example connects to an unencrypted WiFi network.
 Then it prints the  MAC address of the WiFi shield,
 the IP address obtained, and other network details.

 Circuit:
 * WiFi shield attached

 created 13 July 2010
 by dlf (Metodo2 srl)
 modified 31 May 2012
 by Tom Igoe
 */
#include <SPI.h>
#include <WiFi101.h>
#include <arduino_homekit_server.h> // INSERTED CODE

//access the config defined in C code
#include "arduino_secrets.h"
///////please enter your sensitive data in the Secret tab/arduino_secrets.h
char ssid[] = SECRET_SSID;        // your network SSID (name)
char pass[] = SECRET_PASS;    // your network password (use for WPA, or use as key for WEP)
int status = WL_IDLE_STATUS;     // the WiFi radio's status

extern "C" homekit_server_config_t config; // INSERTED CODE

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

  // check for the presence of the shield:
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present");
    // don't continue:
    while (true);
  }

  // attempt to connect to WiFi network:
  while ( status != WL_CONNECTED) {
    Serial.print("Attempting to connect to WPA SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network:
    status = WiFi.begin(ssid, pass);

    // wait 10 seconds for connection:
    delay(10000);
  }

  // you're connected now, so print out the data:
  Serial.print("You're connected to the network");
  printCurrentNet();
  printWiFiData();

  arduino_homekit_setup(&config); // INSERTED CODE
}

void loop() {
  // check the network connection once every 10 seconds:
  delay(10000);
  printCurrentNet();

  arduino_homekit_loop(); // INSERTED CODE
}

void printWiFiData() {
  // print your WiFi shield's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP A'ddress: ");
  Serial.println(ip);
  Serial.println(ip);

  // print your MAC address:
  byte mac[6];
  WiFi.macAddress(mac);
  Serial.print("MAC address: ");
  printMacAddress(mac);

}

void printCurrentNet() {
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print the MAC address of the router you're attached to:
  byte bssid[6];
  WiFi.BSSID(bssid);
  Serial.print("BSSID: ");
  printMacAddress(bssid);

  // print the received signal strength:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.println(rssi);

  // print the encryption type:
  byte encryption = WiFi.encryptionType();
  Serial.print("Encryption Type:");
  Serial.println(encryption, HEX);
  Serial.println();
}

void printMacAddress(byte mac[]) {
  for (int i = 5; i >= 0; i--) {
    if (mac[i] < 16) {
      Serial.print("0");
    }
    Serial.print(mac[i], HEX);
    if (i > 0) {
      Serial.print(":");
    }
  }
  Serial.println();
}

It produced this error when verifying:
Alternatives for osapi.h: []
ResolveLibrary(osapi.h)
  -> candidates: []
In file included from libraries\HomeKit-ESP8266\src/wolfssl/wolfcrypt/settings.h:171:0,
from \libraries\HomeKit-ESP8266\src/wolfssl/wolfcrypt/types.h:27,
from \libraries\HomeKit-ESP8266\src/wolfssl/wolfcrypt/ed25519.h:26,
from \libraries\HomeKit-ESP8266\src/crypto.h:12,
from \libraries\HomeKit-ESP8266\src/arduino_homekit_server.h:15,
from \ConnectWithWPA.ino:17:
\libraries\HomeKit-ESP8266\src/user_settings.h:15:10: fatal error: osapi.h: No such file or directory
 #include "osapi.h"
          ^~~~~~~~~
compilation terminated.

After adding osapi.h into the HomeKit src folder.
Alternatives for user_config.h: []
ResolveLibrary(user_config.h)
  -> candidates: []
In file included from \libraries\HomeKit-ESP8266\src/user_settings.h:15:0,
                 from \libraries\HomeKit-ESP8266\src/wolfssl/wolfcrypt/settings.h:171,
                 from \libraries\HomeKit-ESP8266\src/wolfssl/wolfcrypt/types.h:27,
                 from \libraries\HomeKit-ESP8266\src/wolfssl/wolfcrypt/ed25519.h:26,
                 from \libraries\HomeKit-ESP8266\src/crypto.h:12,
                 from \libraries\HomeKit-ESP8266\src/arduino_homekit_server.h:15,
                 from \ConnectWithWPA.ino:17:

\libraries\HomeKit-ESP8266\src/osapi.h:29:10: fatal error: user_config.h: No such file or directory
 #include "user_config.h"
          ^~~~~~~~~~~~~~~
compilation terminated.

After adding one example of user_config.h into the HomeKit src folder.
Alternatives for pgmspace.h: []
ResolveLibrary(pgmspace.h)
  -> candidates: []
In file included from \libraries\HomeKit-ESP8266\src/homekit_debug.h:12:0,
                 from \libraries\HomeKit-ESP8266\src/user_settings.h:16,
                 from \libraries\HomeKit-ESP8266\src/wolfssl/wolfcrypt/settings.h:171,
                 from \libraries\HomeKit-ESP8266\src/wolfssl/wolfcrypt/types.h:27,
                 from \libraries\HomeKit-ESP8266\src/wolfssl/wolfcrypt/ed25519.h:26,
                 from \libraries\HomeKit-ESP8266\src/crypto.h:12,
                 from \libraries\HomeKit-ESP8266\src/arduino_homekit_server.h:15,
                 from \ConnectWithWPA.ino:17:
\libraries\HomeKit-ESP8266\src/esp_xpgm.h:15:10: fatal error: pgmspace.h: No such file or directory
 #include <pgmspace.h>
          ^~~~~~~~~~~~
compilation terminated.

My TinyCircuit uses these components:

TINYZERO PROCESSOR BOARD
TINYSCREEN OLED TINYSHIELD
WIFI TINYSHIELD (ATWINC1500)
Lithium Ion Polymer battery - 3.7V 150MAH

you can't use it.


text:
Encrypting and decryption RSA (Or other asymetric encryption) on Arduino Mega
I want to encrypt and decrypt like 200 char strings on arduino mega, but I failed to find any library/code that can do that. Do you have any experience with doing that? Thanks.
I'd like to use any asymmetric encryption
The key should be ideally at least 128bit long.

what search terms did you use? ... google returns a lot of hits for arduino encryption lib

Arduino RSA, Arduino asymetric encryption, arduino mega RSA… but I didn’t find any that supports this.

Try "public key" as a substitute term for "asymetric". I see EC-related stuff that would seem to qualify as "other asymetric" per title.

try arduino encryption lib


text:
Procedure for changing frequency of Nano or similar
I need to get interrupts at one of three specific rates: 1920, 2000, and 2400 per sec, at a fairly high precision (~10 ppm). I've asked about this on Electronics but I think here might be more appropriate.
I can't use the standard 16MHz with internal timers, since 16MHz / 2400 (for example) gives 66666.666... counts.
I would use an external standard, but I don't seem to be able to find one that fits the need. Something small and precise at 48KHz / 96KHz etc would be fine.
Alternatively, I could swap the crystal / resonator for one running at 18.432MHz, which divides evenly by those freqs and shouldn't tax a 328p. Can I even do that on a Nano, or some clone / comparable, with the required 10ppm?
-- extra removed --

Sure you can swap the crystal. The maximum is 20MHz, so 18.whatever is well within the capabilities. You'll have to adjust the board settings to match of course (F_CPU).

Whoo, 10 ppm, quite a challenge! Did you consider the initial precision, the influence of temperature and voltage/current, drift, ageing? You might need something better than a simple crystal, for example an oven-controlled crystal oscillator.

Oh, and of course the jitter due to different numbers of clocks for instructions, leading to different interrupt latency.

@thebusybee - I know 10ppm is asking a lot. If I could find a reasonably priced TXCO at 48 or 96 KHz in a small package I'd do that for sure. As for jitter, a small amount is OK in exchange for longer-term (~30 msec) accuracy.

You could use a TXCO of higher frequency and divide it. -- All this seems to call for a more hardware based solution, perhaps a CPLD or FPGA. Why do you need such an accuracy?

You could use an internal timer.
You are using interrupts, and you are probably aware that interrupt
handling inevitably incurs some jitter. Thus, if you do not mind an
extra single CPU cycle of jitter, you could reconfigure the timer on
each interrupt in order to control the average interrupt period.
Here is how I would do it, with Timer 1 running in normal mode (CTC mode
would require an extra operation):
// Interrupt period in units of 1/2^16 CPU cycles.
// For 2.4 kHz, that is 16000/2.4*65536 = 436906666.666...
uint32_t interrupt_period = 436906667;

ISR(TIMER1_COMPA_vect) {
    // Update the timer for the next interrupt.
    static uint32_t accumulator;
    accumulator += interrupt_period;
    OCR1A = accumulator >> 16;

    // The periodic task goes here...
}

void setup() {
    // Configure Timer 1.
    TCCR1A = 0;            // normal mode
    TCCR1B = _BV(CS10);    // clock @ F_CPU
    TIMSK1 = _BV(OCIE1A);  // enable COMPA interrupt
}

void loop(){}

Here, accumulator is a 32-bit extension of the timer's output compare
register. The upper 16 bits are copied into the actual timer
register, whereas the lower 16 bits ensure that the accumulated
error never exceeds one cycle.
This way of updating the timer should only take about 2 µs per
interrupt. It is a constant time operation, so it doesn't add extra
jitter to your task, other than the single cycle of jitter induced by
rounding to the next edge of the CPU clock.
There are a couple of caveats though:

This can only work on an Arduino clocked off a crystal (e.g., a
Micro). Those clocked off a ceramic resonator (Uno...) would be too
unstable in frequency to meet your 10 ppm requirement.
Even though a crystal is more than stable enough to meet your
requirement, it is unlikely to be accurate enough. You will then need
to calibrate it, e.g. by outputting a PWM signal (analogWrite())
into a frequency meter. Then adjust the variable interrupt_period
according to the measured clock frequency.

Edit: I added the timer configuration to the code, and here comes an
explanation of how this code works.
Think of the timer as a digital alarm clock. It measures time in units
of CPU cycles instead of hours and minutes. It rolls over every
216 cycles instead of every 1440 minutes. But it is
otherwise a regular alarm clock. It has two alarms called “COMPA” and
“COMPB”, but you only need one. In order to perform a periodic task, you
turn the alarm on and, every time it rings, you advance the alarm time
by the required period. That is, you set:
new alarm time = previous alarm time + task period
Note that the addition has to be computed modulo the roll-over period of
your clock : 1440 minutes for a regular alarm clock,
216 cycles for the timer. Thankfully, the arithmetics on
unsigned numbers do this automatically.
Now, lets say the task period is 43 minutes and 35 seconds,
but the alarm can only be set with a resolution of one minute. What you
can do is compute the “ideal” alarm time on paper (this is the
accumulator variable), and truncate it to the resolution of the clock
when setting the alarm. If you start at 00:00:00, you will compute the
next ideal time to be 00:43:35 and set the alarm to 00:43. When it
rings, you add the period to the previously computed time, you get
01:27:10, and you set the alarm to 01:27. Etc. Here is the list of the
alarm times as computed and as actually set on the clock:
computed  set
───────────────
00:00:00  00:00
00:43:35  00:43
01:27:10  01:27
02:10:45  02:10
...

Note that, even though the limited resolution of the alarm setting
creates some jitter, the average task period is still exactly
43 minutes and 35 seconds.
The code I wrote above does exactly the same. The “ideal” alarm time is
computed as a fractional number of CPU cycles, written down in binary
fixed point, with 16-bits on each side of the radix point. In hex, it is
1A0A.AAAB CPU cycles. The computed alarm times are multiples of this
period, whereas the times actually written to OCR1A are the same
truncated to an integer:
computed   set
───────────────
1A0A.AAAB  1A0A
3415.5556  3415
4E20.0001  4E20
682A.AAAC  682A
...

Thanks much for this, but, sorry, I don't get how it works. I gather there's some initial setting up of the counter that you don't show? It seems that we're outputting wildly variable values to OCR1A: 1A0A, 3415, 4E20, 682A etc. What's going on?

@JimMack: See expanded answer.

Very nice. I knew that somehow I should implement Bresenham's algorithm to average away the error, but I couldn't see a way to do it. I'll ask another question based on this, to try to solve another issue.


text:
How to change variable/sketch through a GUI
Over the past few months, I've been working on a wearable computer mouse using an Arduino and a 9-dof sensor. Most of the sketch is complete, and works as expected.
Recently, I started investigating how to enable a non-technical user to adjust the sensitivity of the device. Currently, I do this by changing a couple of variables in the sketch. My goal is to be able to create a basic GUI, with some buttons (perhaps unsurprisingly), to accomplish the same.
Requirements:

ability to adjust sensitivity (couple of variables inside sketch) of arduino device through a GUI
does not slow down sketch (I read that you can use serial, but wouldn't constantly checking for serial slow down the operation of the microcontroller?)
can be saved as an executable (easy to set up for a nonprogrammer)

It's fine for the solution to upload a new sketch to the microcontroller, or change variables in the EEPROM. Whatever you suggest is best. I came across this, and a few other similar topics, but due to my inexperience was unable to judge whether that's the best way forward.
I'm not looking for a complete solution, of course. Rather, I would really appreciate any guidance on what the basic "structure" of the solution should be. Then I can determine which parts I can do myself, and which I'll need to seek help on.
Thank you very much for looking at this.

As its a wearable mouse, how does it communicate with the PC? What Arduino are you using?

There's 2 devices. A custom PCB handheld with the sensor, ATSAMD21 microprocessor, nrf24 module. That sends the information through the radio module to a USB dongle. The dongle has the same module, and uses the ATMEGA32U4. It has the arduino leonardo bootloader uploaded.

I guess your dongle is configured as HID device for the PC.

I don't think this question should be closed. It is focused enough in my eyes. The OP already has some basic approaches and we just need explain the obvious misunderstandings. I was about to write an answer when the question was closed

ok @chrisl, I still think it is too broad but if you can write an answer I reopened

Reflashing (and with that recompiling) the sketch for every variable change is very over-the-top.
As you already want to write your own program for the PC I would suggest using Serial. That will be the easiest to implement. This would work like the following:

On the Arduino: You regularly check if there is data in the Serial buffer, read if in that case. You read until a newline character \n, which acts as message delimiter (to distinguish one message from the other). If a full message was received (meaning: you read the newline character) you process the message and write the new values to EEPROM (for saving them permanently).

On the PC application: Let the user determine each value. You open the Arduinos COM port (the user will have to select the correct one) to communicate via Serial. Then you send each value, that you want to write to the Arduino, in a specific format. For example <value_name>:<value>. And don't forget the newline character at the end. Then you can close the COM port and exit the application.

This requires the user to choose the corresponding COM port. With using a custom USB profile (I think a custom HID profile should also be able to receive data) you could eliminate that, but this is a big step in difficulty for you to program.

I read that you can use serial, but wouldn't constantly checking for serial slow down the operation of the microcontroller?

No, not really. The actual receiving of data is done by the USB hardware. As processing load you only have the placing of data in the buffer (happens inside an ISR), which only is done when actual data is received, and the checking if there is data in the buffer. That also needs very short time. It should not interfere with your sampling rate. The 9-DoF sensor is most likely way slower. The actual processing of the data is also only done when you actually send data. Here the longest will be saving the data in EEPROM.
So all in all you have little to no impact on performance.

Hi Chris,
Thank you very much for taking the time to respond. This is what I was looking for; gives me a fairly good idea of the next steps of research to take.
So for the arduino code, would I be writing the code that checks for serial data in a ISR? I'm not sure what you mean by:
"As processing load you only have the placing of data in the buffer (happens inside an ISR), which only is done when actual data is received"

Do you know what interrupts and ISR are? If not I can include a short explanation about that

@ZhelyazkoGrudov: Re “would I be writing the code that checks for serial data in a ISR?”: No. That ISR is provided by the Arduino core library. You would just have to check for Serial.available() within your loop().

No thank you Chris, I don't to waste your time; will do some research first. Already familiar with interrupts, just need to check out ISRs. I think my main concern, perhaps unfounded as you mentioned, is that checking for serial using the serialUSB library for custom PCB will slow the device now.
@Edgar Bonet, thank you Edgar. So the serial.available() is an ISR? A bit confusingly, the arduino website suggests that ISRs shouldn't return anything, but this one does. https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/

I'm not sure if you both remember me, but this must be like the 5th question I've had that you've answered. I really appreciate it :)

About ISR: The actual data receiving is done with ISRs in the background. You don't have to do anything with them (since that is all hidden in the Serial object). You only use Serial.available(), which checks if you have new data in the buffer. And as described: This works that fast, that it won't really change your performance. It just takes a few clock cycles. Your 9-DoF sensor will be way slower.

Also: If it would make an impact, then you would get problems at other places too. The way to go in such a case would be to use a faster microcontroller. But you already have a fast microcontroller (depending on how you are clocking it on your PCB up to 48MHz). Checking Serial isn't a problem on the Uno, which is only 16MHz. You should try it out.

Thank you, Chris! Makes sense.

Hi Chris. Just in case this pops up as a notification, I've started implementing this.


text:
String operations printing random character on Serial Monitor
I want to extract the file name MyFile.txt out of a path which is stored in a string "C:\\MyDirectory\\MyFile.txt";
I found a simple c code which does the job.
string filename = "C:\\MyDirectory\\MyFile.bat";

// Remove directory if present.
// Do this before extension removal incase directory has a period character.
const size_t last_slash_idx = filename.find_last_of("\\/");
if (std::string::npos != last_slash_idx)
{
    filename.erase(0, last_slash_idx + 1);
}

// Remove extension if present.
const size_t period_idx = filename.rfind('.');
if (std::string::npos != period_idx)
{
    filename.erase(period_idx);
}

I had to alter few things for arduino code
example replace find_last_of with lastIndexOf, erase with remove and rfind with lastIndexOf
Here the ino file
#include<string>
void setup() {
  Serial.begin(9600);

}

void loop() {
   String filename = "C:\MyDirectory\MyFile.bat";

// Remove directory if present.
// Do this before extension removal incase directory has a period character.
const size_t last_slash_idx = filename.lastIndexOf("\\");
if (std::string::npos != last_slash_idx)
{
    filename.remove(0, last_slash_idx + 1);
}

// Remove extension if present.
const size_t period_idx = filename.lastIndexOf('.');
if (std::string::npos != period_idx)
{
    filename.remove(period_idx);
}
Serial.println(filename);
delay(1000);
}

Expected output MyFile
When I look into Serial Monitor I get
c$$⸮'<;⸮⸮/<⸮⸮$⸮''⸮;,#$$⸮'<;⸮⸮'<⸮⸮$⸮''⸮:$#$$⸮'<;⸮⸮'<⸮⸮$⸮''⸮;$#$$⸮'

What am I doing wrong?

Did you choose 9600 baud in the serial monitor?

Yes this was on 9600

#include<string>

Remove this. Arduino uses its own String class, different from the STL
string.

String filename = "C:\MyDirectory\MyFile.bat";

There is no '\M' escape sequence in C++ strings. You probably mean
"C:\\MyDirectory\\MyFile.bat".

const size_t last_slash_idx = filename.lastIndexOf("\\");

String::lastIndexOf() returns an int, not size_t.

if (std::string::npos != last_slash_idx)

No std::string here. String::lastIndexOf() returns -1 to signify
that the character was not found.
With all these fixes, your sketch should work as intended.


text:
How to debug "No device found on cu.usbserial, An error occurred while uploading the sketch"
I am testing a project on Arduino Nano. I copy-paste the code on the Arduino IDE and click "Upload". I see:
No device found on cu.usbserial-<unique id>
An error occurred while uploading the sketch

The computer sees the board: when I disconnect the board from the USB socket, the list of ports in Tools > Port no longer shows this port.
The error thing happens:

if I press the reset button first, then click "Upload"
if I change the USB cable (I tried 5 different ones, one of which worked a few years ago, the last time I used this same board)
if I use a simple blink code
if I connect to a different USB port
if I upgrade the Arduino IDE to the latest software from arduino.cc .

The Get board info command shows that the computer can read the VID and the PID, but not the serial number or the board type. If I connect an Arduino Uno to the same socket, I can see the serial number and the board type, but I get the same error message (just with a different port ID). Neither boards show signs of degradation.
The Boards Manager shows that the Arduino AVR Boards, which include Arduino Uno and Arduino Nano, are installed.
When I click "Upload", the IDE compiles the program, then the Nano's L LED blinks, then the TX blinks, then a pause, then the L, then the RX, then the L, then the RX, and then the IDE shows the error. So I suspect that the error is not what the IDE says.
Furthermore, the connection between the Arduino and the IDE is working because the Serial Monitor shows the output of the previous program (at 9600 baud).
Some Arduinos can reset by connecting RX to GROUND and uploading code, but this one does not have an RX pin.
How can I debug this error?

then how did you solve the problem?

@Juraj: By chance, I was poking around the menus and found Tools > Board, just above Processor, as I wrote in the answer (which I wrote at the same time as you wrote your first comment).

so you say you didn't have the board selected at all?

It was showing Board: "Arduino Nano", left over from the last time I used it a few years ago. But when I dove into the sub-menus, Arduino Nano did not have a tick on it. Clicking it solved the issue. It may be a bug in the IDE...

I doubt it was the real problem, but ok

The structure of the boards changed from having multiple copies of the same board with different processors to one board with multiple processor options within it. The same goes for bootloader variants for some boards. If your preferences file contained the settings for the old style of boards from before you upgraded the IDE (at some point) then it won't necessarily map those settings across to the new way of doing it - hence you get an error because the settings don't match your board.

@Majenko That sounds plausible. Can you write an answer?

It seems that everything is working as it should and the computer and the board can see each other. The only thing left to do is to select the board type so the IDE knows how to send the code in a way that the board can interpret.
Select Tools > Board > Arduino AVR Boards > Arduino Nano.
If you have an old or non-Arduino board, try the old bootloader in the processor, as in  CH340 Nano avrdude: stk500_getsync() not in sync resp=0xa4 .


text:
Unable to use rising edge interrupt for external clock Arduino 2650
I'm messing about with an Arduino Mega2560r3 and failing to get timer 4 to trigger on the rising edge of an external clock. It only ever triggers on the falling edge.
I've tried
     TCCR4B = (1 << CS42) | (1 << CS41) | (1 << CS40);

and
     TCCR4B = (1 << CS42) | (1 << CS41);

... one of which should do the trick, but now I've pulled all my hair out and I'm turning to the wider community to see what I'm not seeing!
void setup() {
  DDRE = (1 << PE5);   //Dig pin 3 as output

  noInterrupts();
// Configure Timer 4 (only ICP4 (pin 49) and ICP5 (pin 48) are connected with Arduino MEGA2560 r3)
  TCCR4A = 0;
  TCCR4B = 0;
  TCCR4B = (1 << CS42) | (1 << CS41) | (1 << CS40);    // CTC mode does not reset when using force
  TIMSK4 = (1 << ICIE4);    // enable capture interrupt
  interrupts();
}

ISR(TIMER4_CAPT_vect)
{
  PORTE ^= (1 << PE5);  // Toggle PE5
}

Scope output below - blue is external clock (yes I know it's a sine wave!) and magenta is pin 3 output

You seem to be mixing up two very different things.

You can use an external signal to drive the timer. That is, the timer
will “tick” on the edges of that signal. In this mode, the timer
behavior could be more accurately described as being a “counter”,
since it is counting the external signal's edges. The external signal
has to be fed to pin Tn (for timer n). Only the pins T0 (38) and T5
(47) are routed out on the Arduino Mega2560.

You can use a timer to timestamp the edges of an external signal.
This is called “input capture”. When an edge is detected, the current
value of the counter register is immediately copied to the input
capture register ICRn, and an interrupt can be delivered. The
external signal has to be fed to pin ICPn (ICP4 = 49, ICP5 = 48).

If you want to use input capture, you most likely want to clock the
timer from the system clock, maybe through a prescaler. And you want to
read the ICRn register within the ISR. The edge that triggers the
capture is selected via the bit ICESn (Input Capture Edge Select) of the
control register TCCRnB.

Thanks for your help - I mistakenly thought ICPn was also the ext timer input. I'll have to use timer 5 to use get the external clock working, but now you've explained this, I'm not sure which will be more elegant for this aplication... (I tried to upvote your answer but I'm too noob here)


text:
How to add library to Sloeber
Slober has a menu option: Arduino -> Add a library to the selected project
HOWEVER, the "Import Arduino libraries" dialog that comes up only shows 18 libraries, and has no obvious way to add more.
I selected Arduino -> How To, and selected "Add a library to a sketch", but it told me nothing new. It assumes the library I want to add is in the list, and says nothing about how that list itself is managed, where the libraries in it came from, how to add others, etc.
I theorized that Sloeber's list might be somehow generated from the one maintained by the Arduino IDE... but no, the list of libraries shown in Sketch -> Include library is ENORMOUSLY longer than Sloeber's list.
So... where, exactly, does Sloeber's library list come from, and how does one go about adding a library to it that's NOT in the list? Say...

From whatever repository the Arduino IDE itself gets libraries from when you go to Library Manager (confession: I don't use Arduino often enough to know where those libraries are actually hosted, or who decides what qualifies to be listed. I assume it's something like MavenCentral and hosted by the Arduino organization... but I might be completely wrong)

From a "zipfile" (containing whatever files, with whatever additional metadata, is required for Arduino's IDE to regard it as a valid library zipfile)

From a random Github repo, like https://github.com/mrkaleArduinoLib/gbj_htu21 (with library.json, library.properties, and subdirectories for src/ and examples/)

In Arduino or in Window menu in Preferences in Arduino section in Library Manager subsection

the library folders are set in Preferences too

(blush) Argh, I completely forgot that Slober has its own preferences that are separate from File -> Properties. (I do Arduino development just often enough to forget little details like that in between projects). Go ahead and list it as an answer, and I'll accept it :-)

In Arduino or in Window menu in Preferences


text:
Using 4-digit 7-segment display on Arduino Nano
I want to merge two projects: a "Don't touch your face" hat for Nano and a 7-segment 4-digit display for Uno. I tested both independently and they work. I added an RGB LED to the first, so I use 6 digital pins: 2 for the ultrasonic sensor, 1 for the buzzer, and 3 the RGB LED.
The Nano project takes 6 digital pins and no analog pins, leaving 4 digital pins and 8 analog pins. The Arduino Uno takes 12 digital pins. So I suppose that it's possible to replace the digital pins of the Uno with analog ones at the right voltage.
Even without the Nano project claiming 6 digital pins, the Nano only has 11 digital pins (D2-D12), not enough for a 7-segment 4-digit display. But I couldn't find a tutorial online on how to do so.
Is it possible to use a 7-segment 4-digit display on Arduino Nano?

The "Don't Touch your face hat"  uses only three I/O pins (D10-D12), and the 7-segment sketch appears to use 12 (D2-D13).  A0-A7 are the same exact pins as D14-D21, so you have plenty of digital I/O.  Change the hat sketch to use D14-D16 instead of D10-12, test again with the two separate sketches with all the hardware, then try to combine the code and post your code attempt.

Uno and Nano have nearly the same pinout. Both have D0-D13 and A0-A5 (all can work as digital pins as the analog function of A0-A5 is just additional functionality). Excluding the Serial pins we have D2-D13 and A0-A5, so 12+6=18 pins. I cannot see the hat project (since I don't have an account there), but if we take the 3 pins that DaveX mentioned and the 12 for the 7 segment display we get 15 pins. You have enough pins.

@chrisl I can't find D0, D1 and D13 on my nano, which are they? Yes, if A0-A5 can serve as digital pins, then it's simply a replacement of pin numbers. The Uno code compiles and uploads to Nano, so I'll try this simple replacement tomorrow.

D0 and D1 are marked as TX and RX since this is connected to hardware serial. D13 is on the same side with A0, right at one end of the header next to the 3.3V pin.

You can try to use a shift register.

@DaveX Your comment works perfectly. I shifted the previous pins to D2-D7 and moved the 4-digit 7-segment pins to D8-D12 and A0-A6. I still have two pins left: D13 and A7. I am unable to use A7 with #define D1 21, but the code works on pin D12 (with #define D1 12). Could you confirm that A7 should work just as well? And could you write an answer and I'll edit it with my code?

There are chips such as the MAX7219 designed to control 7 segment displays from devices such as an Arduino, there are also some well-established libraries such as LEDCONTROL to drive them. In fact the MAX7219 doesn't have to drive 7 seg displays, you can use it to drive any collection of up to 64 LEDs, I use one for a simple illuminated Christmas tree. You'll need some basic soldering skills to connect the chip to an Arduino but it's very simple.
E.g. see: https://www.maximintegrated.com/en/products/power/display-power-control/MAX7219.html


text:
Can't get 1 second on a ATMega168 timer
  TCCR1A = 0;
  TCCR1B = 0;
  OCR1B =  0xFF00;
  TCCR1A = (1<<WGM10) ;
  TCCR1B = (1<<CS12) | (1<<CS10);; //set the pre-scalar as 1024
  TIMSK1 = (1 << OCIE1A);

This doesn't produce a 1 second timer, it seems to produce a 0.5 second timer? I've calculated it based on the fact that I'm using the internal 8MHz internal clock on the chip.
Where am I going wrong?
EDIT: OK, I truly don't understand anything about timers, this is the first time I've ever tried one. I tried to figure it out using this tutorial: https://exploreembedded.com/wiki/AVR_Timer_programming
All the examples are related to 16MHz, and the calculations are confusing to me because of the switch between formats which I don't know. After a lot of googling I figure out what I should be pushing into the calculator is ((8000000/1024)*1)-1) = 7811.5 (Although what I do with this number is a mystery) I think I'm supposed to subtract this from 65536 or perhaps some other randomly generated number. You then take the result of this and turn it into the hexadecimal equivalent of a boy band name, like E17 use lots of arrows to point away from things that look like the names of radio stations, WGM10 (bringing you all the hits of the 80's and 90's)
I apologize for the sarcasm, I couldn't help myself. What I really need to know is:

How do you actually calculate a 1-second delay one timer 1 when you are using the 8MHz internal clock of the ATMega168PA ? What are the numbers to type into a calculator?
Which switches should I be setting? I thought these were the correct ones.
What does OCIE1A stand for, can't find it in the documentation or the tutorial, only in the example code?

I should probably also add all I am doing is incrementing a count and displaying the count in my loop.
ISR (TIMER1_COMPA_vect)
{
  count++;
}

Re “I tried to figure it out using this tutorial”: This tutorial suggests periodically resetting the timer. This should not be done: it is a sure way of missing ticks. I suggest looking for a better tutorial. And then, this is mandatory, reading the datasheet (just the chapter on Timer 1).

TCCR1B = (1<<WGM10); doesn't do anything, because on the next line, you overwrite TCCR1B. Secondly, for the /1024 prescaler, you need to set both the CS12 and the CS10 bit. So TCCR1B |= (1<<CS12) | (1<<CS10);. I don't understand how your code is actually giving you a .5Hz signal.

Sorry, I was meeting around when editing the question. I've pasted directly from the code.

In normal mode, the timer counts from 0 to 65535 (0xffff), and then
rolls over back to zero. With a prescaler set to 1024, the period is
then 1024 × 65536 = 67108864 CPU cycles.
If you want to control the timer's period, you should not use normal
mode, but rather CTC mode (for “clear timer on compare match”). In this
mode, it counts from 0 to the value stored in OCR1A, and then starts
back at zero. With the same prescaler, the period is then
1024 × (OCR1A + 1) CPU cycles.

I have added the line: TCCR1A= (1<<WGM12) | (1<<WGM13); But this appears to have no effect.

@RickDearman: 1. If you select mode 12 (_BV(WGM12)|_BV(WGM13)), then the TOP of the count is selected by ICR1. Use mode 4 if you want TOP to be OCR1A.
2. The bits WGM12 and WGM13 belong to TCCR1B, not to TCCR1A.


text:
how can I delete contents of an SD card in arduino?
I have a datafile, datalog.txt I can open, read and write cool. What is the best way to delete all the file contents?
Should I try rewriting the SD card file with NULL data?
I have been reading the "SD.h" header file. I see a flush() and truncate() function should I use one of these?
or maybe I should just close  and reopen the file, and overwrite the data. But I'm concerned that this might lead to some miss representations if the old data is not completely removed.
I am using a teensy 4.1 with built_in SD card.

Just open the file. There is no "not completely removed".

To remove a file use SD.remove("datalog.txt");
SD library's FILE_WRITE is O_READ | O_WRITE | O_CREAT | O_APPEND so it would append at the end of the existing file.
to start with an empty file: File file = FS.open("datalog.txt", O_READ | O_WRITE | O_CREAT);
EDIT: opening the file with O_READ | O_WRITE | O_CREAT doesn't clear the content of the file, only starts to overwrite it from the beginning.


text:
Synchronizing an internal frequency to an external one
In this question:
Procedure for changing frequency of Nano or similar, @EdgarBonet gave a very nice method of generating timings that don't divide the system clock evenly. He also said that it would require tuning of the exact value by measuring the resulting frequency. I'd like to see if that tuning could be made automatic.
Suppose I had a precise external reference that could interrupt at a a sub-multiple of my frequency, say 60Hz. Is there a way to use that precision to, over time, bring my generated frequency into rough agreement with it?
In other words, for a frequency of 2400 Hz, and a reference of 60 Hz, I would adjust the period of the generator so that there are exactly 80 cycles of the 2400 Hz signal in each 60Hz period, even though there might be variations within the periods of those 80 cycles.
In effect this is a crude phase-locked loop multiplier. I know it can't be highly precise, but even close would be very valuable.

You could use the input capture feature of Timer 1 to timestamp the
edges of the reference input signal. This way you can compute the period
of the input relative to the CPU clock, compare to the expected nominal
period, and use this to adjust the interrupt period.
Combining this idea with the answer to the previous question gives:
const float input_frequency = 60;
const float interrupt_frequency = 2400;
const uint32_t nominal_input_period = round(F_CPU / input_frequency);
const uint32_t nominal_interrupt_period =
    round(F_CPU / interrupt_frequency) * 65536;

volatile uint32_t interrupt_period = nominal_interrupt_period;

uint16_t last_input_timestamp;

ISR(TIMER1_COMPA_vect) {
    // Update the timer for the next interrupt.
    static uint32_t accumulator;
    accumulator += interrupt_period;
    OCR1A = accumulator >> 16;

    // The periodic task goes here...
}

void setup() {
    // Configure Timer 1.
    TCCR1A = 0;            // normal mode
    TCCR1B = _BV(CS10);    // clock @ F_CPU
    TIMSK1 = _BV(OCIE1A);  // enable COMPA interrupt

    // Capture the first input edge.
    TIFR1 |= _BV(ICF1);  // clear interrupt flag
    loop_until_bit_is_set(TIFR1, ICF1);
    TIFR1 |= _BV(ICF1);  // clear interrupt flag again
    last_input_timestamp = ICR1;
}

void loop() {
    // Detect edges of the input signal.
    if (bit_is_set(TIFR1, ICF1)) {
        TIFR1 |= _BV(ICF1);  // clear interrupt flag

        // Update the interrupt period.
        uint16_t input_timestamp = ICR1;
        uint32_t input_period =
            (int16_t) (input_timestamp - last_input_timestamp
                - (uint16_t) nominal_input_period)
            + nominal_input_period;
        last_input_timestamp = input_timestamp;
        uint32_t new_interrupt_period = round(nominal_interrupt_period
                * ((float) input_period / nominal_input_period));
        noInterrupts();
        interrupt_period = new_interrupt_period;
        interrupts();
    }
}

Note that rounding the input period to an integer number of cycles comes
with a rounding error of 1.25 ppm, well within your 10 ppm
requirement. You can do better if needed, by using fixed point or
floating point computations. Note also that the Timer rolls over
multiple times per cycle of the input signal, which is dealt with by
some arithmetic tricks, hence the casts to uint16_t and int16_t in
the expression of input_period.
Strictly speaking, this is not a phase lock loop. It is more like a
frequency lock loop. A real PLL would probably be a bit more involved.
However, if you can tolerate your resulting frequency to be 10 ppm
off, this approach is likely to be good enough.

This is great. I never would have worked out the subtleties of int vs uint vs float here. I'll have to study this more to completely get it. You've clearly mastered this device.

One thing is unclear to me. Reading the Atmel docs, it seems that the ICF1 flag in the TIFR1 register is set when an interrupt occurs, and at one point you check if (bit_is_set(TIFR1, ICF1)), so that makes sense. But then you TIFR1 |= _BV(ICF1) to clear the interrupt, which seems to be the opposite of clearing the bit. What am I missing?

@JimMack: Re “the ICF1 flag [...] is set when an interrupt occurs”: No, it is set when a capture event occurs. We could enable the capture event interrupt, but given that this is not time critical (60 Hz is slow), I prefer to just poll the flag in loop(). Re “TIFR1 |= _BV(ICF1) [...] seems to be the opposite of clearing the bit”: As per the datasheet: “ICF1 can be cleared by writing a logic one to its bit location.” This is how most (all?) interrupt flags work, which is indeed confusing!


text:
Optimised random alphanumeric string generator
I'm trying to build arduino nonce generator, but the only thing I found is this question on arduino forum but I can't find out how to make it work for me. I checked and Serial.available() is always 0 for me and if I delete the If I still get nothing
My code:
void setup() {
    Serial.begin(9600);
    randomSeed(analogRead(0));
}

void loop() {
    byte randomValue;
    char temp[5];
    char letter;
    char msg[50];     // Keep in mind SRAM limits
    int numBytes = 0;
    int i;
    int charsRead;

    if(Serial.available() == 0)
    {
        charsRead = Serial.readBytesUntil('\n', temp, sizeof(temp) - 1); // Look for newline or max of 4 chars
        temp[charsRead] = '\0';   // Now it's a string
        numBytes = atoi(temp);
        if(numBytes > 0)
        {
            memset(msg, 0, sizeof(msg));
            for(i = 0; i < numBytes; i++) {
            randomValue = random(0, 36);
            msg[i] = randomValue + 'a';
            if(randomValue > 26) {
                msg[i] = (randomValue - 26) + '0';
            }
            }
            Serial.println("Here is your random string: ");
            Serial.println(msg);
            Serial.print("I received: ");
            Serial.println(numBytes);
            delay(1000);
        }
    }
}

How do I make it work?
Do you have some working random alphanumeric string generator that you are using?

Why do you check for if(Serial.available() == 0)? If you want to read data from Serial you should check for if(Serial.available() > 0), which can be written shorter as if(Serial.available()). Please try that

Is this right? You are reading in a 4-digit number, and then using that as the number of digits to put random characters into a 50-byte array? Why not read a 2-digit number? Or at least test if the number is > 49 or not.

if(randomValue > 26) should be if(randomValue >= 26). Other than the fixes suggested in these three comments, the sketch should work as advertised.

@chrisl even with that, the code never goes into that if

Your problem seems to be related to how you get the actual length you want to generate. There are other ways you could do that. Since your max seems to be 4 characters, you could possibly enter "9999" which would overflow the 50 bytes temp variable.
You could simply read until \n and then atoi. Then cap at 50.
As a side note, here's a function I've used in the past to generate (pseudo)random strings for network requests (e.g. state or nonce parameters)
#define MAX_UID 8 /* Change to whatever length you need */

const char * generateUID(){
  /* Change to allowable characters */
  const char possible[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
  static char uid[MAX_UID + 1];
  for(int p = 0, i = 0; i < MAX_UID; i++){
    int r = random(0, strlen(possible));
    uid[p++] = possible[r];
  }
  uid[MAX_UID] = '\0';
  return uid;
}


text:
How can I get a Faster boot with the Adafruit Feather SAMD21?
The Adafruit Feather SAMD21 takes about two seconds from power being supplied to when setup() starts running.  How can I shorten that time so that setup() will run sooner?  I measure this time using a power supply and others appear to measure similar times with their eyeballs.
I understand that 328 microcontrollers can be made to boot quicker (almost instantly from a human perspective) using different bootloaders for example, but I haven't found one for the M0 SAMD21 nor another method.
The code isn't relevant because the blink example shows the same timeframe, but here's another example:
//no libraries, global variables, nothing.
setup(){
digitalWrite(LED_BUILTIN, HIGH);
}

loop(){
}

I dont think that is relevant because other people observe the same start time.  Anyway here it is, apologies for the formatting setup(){ digitalWrite(LED_BUILTIN,HIGH);} loop(){}  There is nothing else before or after.  The standard Blink example shows the same thing.

Measured with a power supply.  Other people observe about the same time.

After consulting the datasheet for the SAMD21, I verified that the processor starts immediately once the internal clocks are stable. This happens quickly. The reset vector directs execution to the Arduino bootloader, which certainly spins while waiting for the Arduino programmer to connect. If that does not happen during that delay, the bootloader jumps to the resident application. The delay with no activity is how the bootloader determines that you want to start the application. You can eliminate that by programming the processor using a hardware programmer/debugger, and getting rid of the Arduino bootloader.
The hardware programmers also allow source level breakpoint debugging. You just have to learn to use a decent IDE programming environment. A good prgrammer will cost you around $160.

I have no idea why this would be "voted down" since it is a valid and appropriate solution to the op's question.

Awesome idea and research!  Thanks. Do you have link to the type of programmer and IDE or what you mean by removing the bootloader?  Perhaps this?  https://learn.adafruit.com/how-to-program-samd-bootloaders


text:
Arduino IDE Java error
I'm running IDE version 1.8.16 under Windows 10.
Frequently I get the error message. The situation is solved only when exiting the IDE. Afterwards the compilation  may be finished with or without sketch errors.
Is there anything to do?
Exception in thread "AWT-EventQueue-0" Exception in thread
"Thread-18" java.lang.IndexOutOfBoundsException: len=-12
    at sun.font.FontDesignMetrics.charsWidth(FontDesignMetrics.java:501)
    at org.fife.ui.rsyntaxtextarea.TokenImpl.getWidthUpTo(TokenImpl.java:601)
    at org.fife.ui.rsyntaxtextarea.TokenImpl.getWidth(TokenImpl.java:570)
    at org.fife.ui.rsyntaxtextarea.RSyntaxUtilities.getTokenListWidth(RSyntaxUtilities.java:1180)
    at org.fife.ui.rsyntaxtextarea.RSyntaxUtilities.getTokenListWidth(RSyntaxUtilities.java:1159)
    at org.fife.ui.rsyntaxtextarea.SyntaxView.getLineWidth(SyntaxView.java:307)
    at org.fife.ui.rsyntaxtextarea.SyntaxView.calculateLongestLine(SyntaxView.java:110)
    at org.fife.ui.rsyntaxtextarea.RSyntaxTextArea.refreshFontMetrics(RSyntaxTextArea.java:2106)
    at org.fife.ui.rsyntaxtextarea.RSyntaxTextArea.setFont(RSyntaxTextArea.java:2545)
    at processing.app.EditorTab.applyPreferences(EditorTab.java:333)
    at processing.app.Editor.lambda$selectTab$52(Editor.java:1457)
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
    at java.awt.EventQueue.access$500(EventQueue.java:97)
    at java.awt.EventQueue$3.run(EventQueue.java:709)
    at java.awt.EventQueue$3.run(EventQueue.java:703)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:74)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:205)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
java.lang.IndexOutOfBoundsException: len=-12
    at sun.font.FontDesignMetrics.charsWidth(FontDesignMetrics.java:501)
    at org.fife.ui.rsyntaxtextarea.TokenImpl.getWidthUpTo(TokenImpl.java:601)
    at org.fife.ui.rsyntaxtextarea.TokenImpl.getWidth(TokenImpl.java:570)
    at org.fife.ui.rsyntaxtextarea.RSyntaxUtilities.getTokenListWidth(RSyntaxUtilities.java:1180)
    at org.fife.ui.rsyntaxtextarea.RSyntaxUtilities.getTokenListWidth(RSyntaxUtilities.java:1159)
    at org.fife.ui.rsyntaxtextarea.SyntaxView.getLineWidth(SyntaxView.java:307)
    at org.fife.ui.rsyntaxtextarea.SyntaxView.calculateLongestLine(SyntaxView.java:110)
    at org.fife.ui.rsyntaxtextarea.SyntaxView.updateMetrics(SyntaxView.java:903)
    at org.fife.ui.rsyntaxtextarea.SyntaxView.yForLine(SyntaxView.java:988)
    at org.fife.ui.rsyntaxtextarea.SyntaxView.yForLineContaining(SyntaxView.java:1013)
    at org.fife.ui.rsyntaxtextarea.RSyntaxTextAreaUI.yForLineContaining(RSyntaxTextAreaUI.java:263)
    at org.fife.ui.rtextarea.RTextAreaBase.yForLineContaining(RTextAreaBase.java:1218)
    at org.fife.ui.rtextarea.LineHighlightManager.repaintLine(LineHighlightManager.java:174)
    at org.fife.ui.rtextarea.LineHighlightManager.addLineHighlight(LineHighlightManager.java:69)
    at org.fife.ui.rtextarea.RTextArea.addLineHighlight(RTextArea.java:296)
    at processing.app.Editor.addLineHighlight(Editor.java:1670)
    at processing.app.Editor.statusError(Editor.java:2552)
    at processing.app.Editor$BuildHandler.run(Editor.java:1646)
    at java.lang.Thread.run(Thread.java:748)

do you have some unusual characters in the sketch?

I see this a lot and I am using Linux. It appears when there is an error in my code, sometimes as simple as a parenthesis  missing sometimes it just crashes. I close it and restart and everything is fine. This only messes with the current instance of the IDE, other windows and IDEs operating in the same and different work spaces and they are OK. The only consistent thing is it crashes during upload and I get lots of java errors. It will usually close, so I do not have to kill it. Sorry this does not solve the problem but lets you know it is not a windows only problem.


text:
'for loop' seems to change the execution of pow()
The first time, pow() works.  But inside of a 'for loop', or again afterwards, it doesn't behave !?  (I'm using a Chinese Pro Mini with Arduino 1.8.16)
EDIT
To clarify what I am asking, my question is: "Why does pow() only give the correct answer the first time?"
uint8_t places;
uint8_t temp8;
uint32_t n;

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

void loop() {
  places  = 5U;

  n = pow( 10, places);
  Serial.println(n);

  Serial.println("\nHERE'S THE SAME CODE INSIDE OF A 'FOR LOOP'\n");

  for (temp8 = 0; temp8 < places; temp8++)  {
    n = pow( 10, places);
    Serial.println(n);
  }

  Serial.println("\nNOW THE EXACT SAME CODE AS BEFORE GIVES A DIFFERENT RESULT\n");

  n = pow( 10, places);
  Serial.println(n);

  while(1){}
}

Here's what the serial monitor shows:

100000
HERE'S THE SAME CODE INSIDE OF A 'FOR LOOP'
99999
99999
99999
99999
99999
NOW THE EXACT SAME CODE AS BEFORE GIVES A DIFFERENT RESULT
99999

This seems like a case of a confused compiler. More specifically, a
confused optimizer.
On the first occurrence of pow(10, places), the compiler noticed that
places must be equal to 5, and so replaced the expression with its
value. If you disassemble the compiled code, you will notice it calls
Serial.println(100000);

On the following occurrences, the compiler did not notice that places
can not be anything other than 5, so it did not optimize-out the call to
pow(), and got the result 99999.9765625. This is 3 ULPs less than
the exact result, and is consistent with the accuracy you can expect
from pow(). Converting to an integer implicitly rounds towards zero,
hence the printed result: 99999.

What is ULPs?  My search came back with Ultra Low Power, but that's probably not what you were talking about.  I don't understand where the error is coming from, nothing really changed, and the calculation is seemingly very simple.  What can I do to make my sketch run properly?  Did I ask a low quality question?  I put a good deal of effort into it and felt that the result was to the best of my ability.  Perhaps this isn't the place for someone with my skills to be posting.  I feel like I have made a nuisance of myself and do not wish to do so again, Your candid thoughts would be appreciated.

@TRS-80: ULP = Unit in the last place. To get the correct result, write (or search for) an integer power function, or use round(pow(...)).

Great!  That fixed my problem, thanks very much!  You were extremely helpful with the programming aspect,  I guess I must have been violating boundaries by asking for etiquette advice.  Sorry.


text:
Random "Compilation error: Error: 13 INTERNAL: exit status 1". No clue how to resolve or even what causes this error
I am a beginner with Arduino. I have a program that is intentionally simple.
The code refuses to compile, spitting out the error Compilation error: Error: 13 INTERNAL: exit status 1. I have gotten this type of error multiple times, and I have no idea what causes it, nor how to fix it.
My code is below, by the way.
void setup() {
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);

  analogWrite(10, 10);
}

void loop() {
  digitalWrite(9, HIGH);
  digitalWrite(11, LOW);
  delay(250)
  digitalWrite(9, LOW);
  digitalWrite(11, HIGH);
}

comment out all lines ... then uncomment one at a time ... compile each time

might it be your board config? ide does some annoying stuff sometimes regarding where it caches crud, making getting a truly clean install more annoying than it should be.

If you read all the error message you'll see it complaining about a missing semicolon...

The problem with that error message is that you are only reading the very last line. That line says "Oops, it didn't compile". The actual error message occurs before that. You need to read the entire message to know what is going on.
With your code, for example, you get the following output:
blah.ino: In function 'void loop()':
blah.ino:13:3: error: expected ';' before 'digitalWrite'
   digitalWrite(9, LOW);

That is your actual error. It's telling you that there's a semi-colon missing before the digitalWrite on line 13.  There's nothing before the digitalWrite on line 13, but, if you look closely, you can see that line 12 has the semi-colon missing from the end of it.:
  delay(250)    <---- missing ;
  digitalWrite(9, LOW);

Thus it proves that it is always important to both read and (if you don't understand it) post the entire error message not just the last line.

Thanks, that works.


text:
UART connected device communication only works one way
As the title implies, I have two Arduino devices (Uno and Mega) connected to each other over UART (the Mega is hardware UART, the Uno is software UART); I need the Mega to send a command to the Uno, the Uno to perform the command, then the Uno to report back to the Mega when it has finished the task. In this way, I want to implement asynchronous programming to control various light patterns as well as several motors (code not shown, it is unnecessary as the light control is in an isolated segment) without needing any firmware hacking. Sending commands from the Mega to the Uno works, but the reverse is not true, and even polling waitloops do not work. Note that if I send the "affirm" command repeatedly for infinity, but then I hang the code in the Uno and the Mega has no way to stop the barrage; it starts receiving likely random bytes.
My code for the Mega is bulky and multi-file so I can't send the entire thing, but here is the control code:
lights::showRow(Serial1, 0, 0, 1, 1, 2, 2);
lights::waitUntilFinished(Serial1);
delay(500);
lights::clear(Serial1);
lights::waitUntilFinished(Serial1);
lights::chantO(Serial1);
lights::waitUntilFinished(Serial1);
lights::showRow(Serial1, 1, 0, 1, 1, 1, 2);
lights::waitUntilFinished(Serial1);
delay(500);
lights::clear(Serial1);
lights::waitUntilFinished(Serial1);
lights::chantX(Serial1);
lights::waitUntilFinished(Serial1);

These commands are implemented by:
namespace lights{
  boll ready = false;
  boll helloSent = false;
  void chantO(HardwareSerial coms){
    coms.write(1);
  }
  void chantX(HardwareSerial coms){
    coms.write(2);
  }
  void showRow(HardwareSerial coms, uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, uint8_t x3, uint8_t y3){
    coms.write(3);
    coms.write(x1);
    coms.write(y1);
    coms.write(x2);
    coms.write(y2);
    coms.write(x3);
    coms.write(y3);
  }
  void clear(HardwareSerial coms){
    coms.write(4);
  }
  void waitUntilFinished(HardwareSerial coms){
    while (coms.available() == 0){};
    Serial.println("Done.");
    // It can't say anything but "affirmed", so we can save some code by not checking.
  }
}

The light code:
/* To make life easy, I will include a wiring map. Change as needed.
 *  Note that each ring is 24 pixels, and is labeled with the first-position to access it. The next one is obviously going to be the final point.
 ____     ____     ____
/48  \___/72  \   /192 \
\____/   \____/   \____/
 |___     |___     |___
/24  \   /96  \   /168 \
\____/   \____/   \____/
 |___     |___     |___
/0   \   /120 \___/144 \_____[END]
\____/   \____/   \____/
 |
 |
[CONTROLLER]

*/

#include <Adafruit_NeoPixel.h>
#include <SoftwareSerial.h>

#ifdef __AVR__
  #include <avr/power.h>
#endif
#define PIN       6
#define NUMPIXELS 216
#define DELAYVAL 500

Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
SoftwareSerial coms(9, 8);
int white = pixels.Color(255, 255, 255);
int red = pixels.Color(255, 0, 0);

int getPixel(uint8_t x, uint8_t y, uint8_t num){
  if (x == 0){
    return 48 - (y * 24) + num;
  }
  else if (x == 1){
    return 72 + (y * 24) + num;
  }
  else if (x == 2){
    return 192 - (y * 24) + num;
  }
}

void setRing(uint8_t x, uint8_t y, int color){
  for (int i = 0; i < 24; i ++){
    pixels.setPixelColor(getPixel(x, y, i), color);
  }
}

void setup(){
  pinMode(9, INPUT);
  pinMode(8, OUTPUT);
  coms.begin(9600);
  Serial.begin(9600);
  pixels.begin();
  pixels.setBrightness(205); // 0.8 * 256 = 204.8; thus this is 80% power. Only 6 can be lit up before you have issues.
}

void loop(){
  if (coms.available() > 0){
    uint8_t d = coms.read();
    Serial.println("He talkin' me");
    Serial.print("He say ");
    Serial.println(d);
    switch (d){
      case 1:
        for (uint8_t x = 0; x < 2; x ++){
          setRing(0, 1, white);
          setRing(1, 0, white);
          setRing(2, 1, white);
          setRing(1, 2, white);
          pixels.show();
          delay(500);
          pixels.clear();
          pixels.show();
          delay(500);
        }
        break;
      case 2:
        for (uint8_t x = 0; x < 2; x ++){
          setRing(0, 0, white);
          setRing(2, 2, white);
          setRing(2, 0, white);
          setRing(0, 2, white);
          setRing(1, 1, white);
          pixels.show();
          delay(500);
          pixels.clear();
          delay(500);
        }
        break;
      case 3:
        Serial.println("Hello, World");
        setRing(coms.read(), coms.read(), red);
        setRing(coms.read(), coms.read(), red);
        setRing(coms.read(), coms.read(), red);
        pixels.show();
        break;
      case 4:
        pixels.clear();
        pixels.show();
        break;
    }
    coms.write(1);
  }
}

upload softwareSerial example sketch into both arduinos ... use hardware serial on the mega ... test connectivity between the two arduinos

You need to pass your HardwareSerial parameters by reference to prevent object copying.

You are passing your HardwareSerial (Serial1) objects by value. That means that the object is copied, which is not good - it breaks the connection between the incoming data buffer and the interrupt that loads the RX ringbuffer.
Instead you must either pass by reference or by pointer.  Personally I prefer pointers because it's what I am used to using, but you can use either.
For example:
  void waitUntilFinished(HardwareSerial &coms){ // <--- note the &
    while (coms.available() == 0){};
    Serial.println("Done.");
    // It can't say anything but "affirmed", so we can save some code by not checking.
  }

I would also consider changing this from a namespace to a class and passing the serial object you wish to use as a parameter to the constructor and storing the pointer to it in the class - then you only need ever pass it once and then use that pointer from then on. It would just simplify your code and clean things up somewhat.


text:
fingerprint scanner and GSM module- how do i put a timer condition using if statements?
I am using a fingerprint sensor and GSM module on Arduino MEGA 2560. I want a fingerprint to be scanned every minute, if a minute elapses with no finger scanned, then the next code for the GSM to send an SMS must be executed

const unsigned long timeLimit = 60000;
unsigned long prevTime;
unsigned long currTime;

void setup() {
  prevTime = millis();
}

void loop() {
  unsigned long currTime = millis();
  getFingerprintID(); //fingerprint func
  if (currTime - prevTime <= timeLimit) {
    if (finger.fingerSearch() == FINGERPRINT_OK) { //if the fingerprint matches
      prevTime = currTime;
    }
  } else {
    Serial.print("MAXIMUM TIME OF ");
    Serial.print(currTime / 1000);
    Serial.print(" SECONDS HAS LAPSED\n");
  }
}

Consider looking at this https://forum.arduino.cc/t/using-millis-for-timing-a-beginners-guide/483573 What you need to do is create a timer that every 60 seconds executes the code that you want and sets a flag if it was successful and based on that you can do whatever you need with the GSM.

do something like this ... modify the millis code in the comment from @Coder_fox to increment a counter every second ... the millis code does nothing else ...... check for fingerprint, if detected then clear the counter to zero, do nothing else ...... check the counter, if 60 then send SMS

@Coder_fox the issue i have now is that the timer starts when i run the code and lapses within 60 seconds regardless of how many times the fingerprint was scanned within the time period

i cleaned up your version. make sure to update the prevTime variable.
const unsigned long timeLimit = 60000;
unsigned long prevTime ;
unsigned long currTime;
unsigned long elapsedTime;
int id;
void setup() {
prevTime=millis();
}

void loop() {
  if (fingerprint()){
    currTime = millis();
    elapsedTime = currTime- prevTime;
    if (elapsedTime < 60*1000) {
      prevTime = currTime;
    } else {
       sendSms();
    }
  }
}

void sendSms() {
Serial.print("MAXIMUM TIME OF ");
Serial.print(currTime/1000);
Serial.print(" SECONDS HAS LAPSED\n");
}

bool fingerprint(){
  bool fingerPrintAccepted = false;
  if (finger.fingerSearch()==FINGERPRINT_OK){
    fingerPrintAccepted = true;
  }
  return fingerPrintAccepted;
}


text:
Arduino Visible Light Communication(Audio transmission)
I think this is a broad question. I'm currently implementing visible light communication with Arduino. I'm using a laser as my transmitter and LDR as my receiver. I'm able to transmit a text from one side to another. But I would like to go further on this project. I want to modify the system to transfer an audio file and live stream(play) on the receiver's side.
In order to play the stream in real time, data communication must happen much faster than simple text transfer.
(Like audio with 8KHz sampling rate with 16 bit per sample).
Need transmission speed of 8*16/8= 16,000 Bytes/s
I have identified a few barriers to achieve such as

Arduino has a 64-byte buffer.(can lead to buffer overflow)
LDR response time(min delay for the pulse is 10ms for text transmission project)

I wonder If this is a possible project to do with Arduino. If it's possible, I would like to know about changes to reach that kind of transmission speed. I'm sorry for my poor writing skills.
Thank You!

You should move to a better microcontroller board (there are many commonly used ones depending on your other requirements; you could try a Pi Pico for only about 4€) and you should use a phototransistor instead of the LDR (the response time is the reason why the receivers for IR remotes, which is a similar use case, use phototransistors).

"Arduino has a 64-byte buffer." - What buffer do you mean here? The buffer of the Serial object? I believe you can increase that. Though the speed will be your bigger problem.

@chrisl Yes, the buffer of the serial object. If I can consume the buffer with much speed, then there will be no overflow(I guess).  Thank you very much for the advice.!!


text:
Fatal exception preventing flashing ESP8266 ESP-01
My issue arose when attempting to flash several of my ESP8266 ESP-01 module (https://www.aliexpress.com/item/33010444450.html?spm=a2g0s.9042311.0.0.27424c4dNkKYQZ). In the past and with the first chip I got it working just fine with the loader from the Espressif website, but the second and third proved to be stubborn.
The problem:
The issue I am struggling with is that during flashing the software does not recognize/synchronize with the chip. When attempting to do this, the indicator blue-led on the chip is constantly on. When checking the communication with the chip in normal mode (at Baud 15200) the chip responds normally to AT commands and presents version number etc. When in flash mode, however, the chip responds at Baud 74880 by flooding TX with
Fatal exception (0):
epc1=0x400fffa8, epc2=0x00000000, epc3=0x00000000, excvaddr=0x00000000, depc=0x00000000

From research, I gathered that this could be a faulty flash in the past causing a wrong configuration in flash mode but I still haven't found a solution to this problem as the chip does not respond when attempting to re-flash.
The setup
As a setup, I have both an Arduino Uno with the chip removed(https://www.instructables.com/Flash-or-Upgrade-Firmware-on-ESP8266-ESP-01-Module/) as well as an ESP-dongle(https://www.aliexpress.com/item/32693314450.html?spm=a2g0s.9042311.0.0.506e4c4ddAqtwB) with a switch soldered on between GND and GPIO0. Furthermore:

Vin -> 3.3V
CH_EN -> 3.3V
Tx -> Tx
Rx -> Rx
GPIO_0 -> GND
GND -> GND

As software, I tried that from the Espressif website (latest version and that of Jan 2021) as well as NodeMCU Firmware Programmer. Again, the first chip responded after a while (also not ideal), but the second and others fail to do so.
The question
My question is thus what could be causing this problem, what I can do to rectify the issue, and finally what the most secure way to flash such chips is as my previous one clearly did not work.
Thanks for any tips in advance,
Cheers

try to pull-up io 2

Try using a lower baud rate. Maybe 57600. I have found that some chips that are difficult to program at 115200 will reliably program at a slightly lower baud rate.


text:
How to smooth transition to another color NEOPIXELS
I am working on a led strip project and was looking for ways to smooth transition from color to another. Problem is my current method is not so good.
#include <Adafruit_NeoPixel.h>

#define LED_PIN     25
#define LED_COUNT  60
#define BRIGHTNESS 50

Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRBW + NEO_KHZ800);

bool isFading = false;
unsigned long startTime;
uint32_t fadeDuration = 1000;          //fade for 3seconds
uint32_t startingColor = 0x00ffff00;      // W = 0x00 R=0xFF G=0xFF B=0x00  yellow
uint32_t targetColor = 0x008f00ff;        // W = 0x00 R=0x8F G=0x00 B=0xff  violet

void setup() {

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

    Serial.begin(9600);
  while (!Serial);
  Serial.println("Starting");

  strip.begin();
  strip.show();
  strip.setBrightness(BRIGHTNESS);

  for (int i = 0; i < strip.numPixels(); i++)
    strip.setPixelColor(i, startingColor);
  strip.show();

  delay(5000); // wait 5 seconds before fading

  isFading = true;
  startTime = millis();
}

void loop() {

  if (isFading) { //Fade from yellow to violet in 3 seconds
    for (int i = 0; i < strip.numPixels(); i++)
      strip.setPixelColor(i, getFadeColor(startingColor, targetColor, startTime, startTime + fadeDuration));
    strip.show();
  }

  if ( millis() >= startTime + fadeDuration){; // i intentionally did not include an overflow check to keep it simple
  Serial.println("Fade ended");
  isFading = false;
  }
}

uint32_t getFadeColor(uint32_t startColor, uint32_t endColor, unsigned long timeStart, unsigned long timeEnd) {

  uint8_t startWhite  = (startColor >> 24) & 0xff;
  uint8_t startRed    = (startColor >> 16) & 0xff;
  uint8_t startGreen  = (startColor >> 8 ) & 0xff;
  uint8_t startBlue    =  startColor & 0xff;

  uint8_t endWhite    = (endColor >> 24) & 0xff;
  uint8_t endRed      = (endColor >> 16) & 0xff;
  uint8_t endGreen    = (endColor >> 8) & 0xff;
  uint8_t endBlue      = endColor & 0xff;

  unsigned long timeNow = millis();

  uint8_t mapTime = map(timeNow, timeStart, timeEnd, 0, 255);
  uint8_t white   = map(mapTime, 0, 255, startWhite, endWhite);
  uint8_t red     = map(mapTime, 0, 255, startRed, endRed);
  uint8_t green   = map(mapTime, 0, 255, startGreen, endGreen);
  uint8_t blue    = map(mapTime, 0, 255, startBlue, endBlue);

  Serial.print("Time: \t");
  Serial.print(mapTime);
  Serial.print('\t');
  Serial.print("Color now: \t");
  Serial.println(strip.Color(  red,   green,   blue, white),HEX);

  return strip.Color(  red,   green,   blue, white);

}

The problem im having with this code is visually it would seem that it goes from
Yellow -> White -> violet
and it does not look like a proper transition. I have tried with other colors, and it always seems to pass throught the white color
Are there color theories i can apply for the transition? if you can show me an example sketches on how to do the transition that would also be great.

That happens if you directly fade between complementary colors. After half of the duration the components will be somewhere half brightness. So that looks white. How do you want it to fade between them?

Im not really sure how i want it, i guess  something that will go through the color wheel until the destination color. Are there other options?

@DrakeJest: If you want to go around (rather than across) the color wheel, you should interpolate in the HSV, rather than the RGB color space.

something that will go through the color wheel until the destination color

For that the FastLED library has the function ColorHSV(), which can be used to define colors using the HSV color space. It stands for Hue, Saturation and Value (or brightness). Hue is the value representing the position in the color wheel, so that is what you want to change.
Instead of
strip.Color(  red,   green,   blue, white);

use
strip.ColorHSV( hue, saturation, brightness );

and change hue over time with the algorithm, that you already programmed. When saturation and brightness stay the same the LEDs will cycle through the color wheel.
Note: The library provides the way from HSV to RGB color (with the above function), but it does not provide a way back. For getting back HSV from an RGB color you would need to write your own conversion function and I don't know how to do that. Though at the current state you don't need it.

I have looked into the colorHSV() function, so it returns the 32bit WRGB to be used in setPixelColor(). What i have is the starting RGB and the endpoint RGB, and i need to convert them to starting hue and enpoint hue. You mentioned that i do not need a function to convert RGB to HSV, so how do i get my start and end hue values?

My point was that the library doesn't have a function for going that way. I would suggest that you use an online color picker too to determine the HSV values and then just using them in the code (so that you don't use RGB values of your colors in your code). A short google search gave me this one. Input your RGB values, press Enter and then copy the HSV values.

By the way: When you look at the image of the HSV representation cylinder in the HSL and HSV wikipedia article you can see why you got white with your code. You moved at a straight line from one side of the cylinder to the other, passing the white in the middle in the process. Thats a good visual representation to help you understand the color space

Unfortunately my color source are generated by the code and will always output a RGB value. So i have two options rewrite a portion of my code and convert everything to HSV or use formulas like the one discussed here. i will have to think about it which is more compatible of what other things i might add to this project :)

there's a lot of rgb to hsl stand-alone snippets floating around.


text:
Low power microcontroller with gprs/gsm and maybe gps on board
Good day to ya all. I have a general question and a potential problem to solve.
My plan is to make a device which will work on 2 li-ion batteries. The purpose of this board is to take data from 3/4 sensors and send them via gprs to a server.( it would be ideal if it had gps on board also )
It must be small and it must at least hold half a year on those 2 ( at max 4 batteries ).
My question to you all is do you know a good low power microcontroller board with gsm/gprs chip on it (and maybe gps) ?
One solution would be to use a Arduino pro nano and a separate sim800 module and a separate gps module but this solution is just complicating. I need something with similar functionality of an Arduino and not so power hungry.
Hope to hear from you.

this is a Q&A site, not a brainstorming forum ... what is the actual arduino related problem that you are trying to solve? ... what is your question about the problem that you are trying to solve?

Nothing to brainstorm here. Just asking is there some arduino or ATMega based board with gsm/gprs finctionality on it.

If someone helps than that is good. You as a senior member here dont have to be rude. If you can help than great. I know too that there probably is and that it is ATmega based. That is the reason i ask here and not my mother for it. Thanks <3

i do not mean to be rude and I apologize if you perceived it that way ... you asked for the existence of a component ... i said that it probably exists ... shopping questions are off topic here, so you cannot ask where to get one, but you can ask if one exists

Thanks for the apologize. I asked just for help if someone knows anything or has used something similar. Something to let me dig into just to set me on a right path.