text:
Multiple if else statements for distance-triggered LEDs
I have a sketch that calculates simple distance from the device to the nearest preset GPS coordinate (there are 3 in total) and I would like to have LEDs in the neopixel strip light up according to the proximity of the location.
I managed to make it work with only one 5mm led and a simple if (shortestDist < 10) then digitalWrite(ledPin, HIGH); - else ledpin low. But I want to use a neopixel strip with 7 leds to light up according to various distance criteria.
In my attempt here, I tried to make specific leds light up when 50, 30 and 10m away but it doesn't work properly, and it's a pretty crude approach, as are my coding "skills" :D
I would also like some help on how to make some kind of shorthand for specific led strip setup depending on distance - for example at 50m distance, 2 leds red, 5 leds off, at 30m distance 5 leds red, 2 leds off and so on.
Hope someone can assist the newb :D Currently the leds don't all shut off when the distance is higher than 50.
void loop()
{

while (ss.available() > 0)
    gps.encode(ss.read());
if (gps.location.isUpdated())
{
    Serial.print(F("Lat Lon = "));
    Serial.print(gps.location.lat(), 6);
    Serial.print(", ");
    Serial.println(gps.location.lng(), 6);
}
else if (millis() - last > 1000)
{
    Serial.println();
    if (gps.location.isValid())
    {
        double shortestDist;
        for (int i = 0; i < 3; ++i)
        {
            double distanceToDest =
                TinyGPSPlus::distanceBetween(
                    gps.location.lat(),
                    gps.location.lng(),
                    positions[i].lat,
                    positions[i].lon);
            if (!i || distanceToDest < shortestDist)
                shortestDist = distanceToDest;
        }
        Serial.print(F("Next in range = "));
        Serial.print(shortestDist, 2); // decimal
        Serial.println(" m");

        if (shortestDist < 50)
        {
          pixels.clear();
          pixels.setPixelColor(0, pixels.Color(0, 250, 0));
          pixels.setPixelColor(1, pixels.Color(0, 0, 0));
          pixels.setPixelColor(2, pixels.Color(0, 0, 0));
          pixels.setPixelColor(3, pixels.Color(0, 0, 0));
          pixels.setPixelColor(4, pixels.Color(0, 0, 0));
          pixels.setPixelColor(5, pixels.Color(0, 0, 0));
          pixels.setPixelColor(6, pixels.Color(0, 250, 0));
          pixels.show();
          delay(50);
        }

        else if (shortestDist < 30)
        {
          pixels.clear();
          pixels.setPixelColor(0, pixels.Color(0, 250, 0));
          pixels.setPixelColor(1, pixels.Color(250, 250, 0));
          pixels.setPixelColor(2, pixels.Color(0, 0, 0));
          pixels.setPixelColor(3, pixels.Color(0, 0, 0));
          pixels.setPixelColor(4, pixels.Color(0, 0, 0));
          pixels.setPixelColor(5, pixels.Color(250, 250, 0));
          pixels.setPixelColor(6, pixels.Color(0, 250, 0));
          pixels.show();
          delay(50);
        }

        else if (shortestDist < 10)
        {
          pixels.clear();
          pixels.setPixelColor(0, pixels.Color(250, 0, 0));
          pixels.setPixelColor(1, pixels.Color(0, 250, 0));
          pixels.setPixelColor(2, pixels.Color(0, 0, 0));
          pixels.setPixelColor(3, pixels.Color(250, 0, 250));
          pixels.setPixelColor(4, pixels.Color(0, 0, 0));
          pixels.setPixelColor(5, pixels.Color(0, 250, 0));
          pixels.setPixelColor(6, pixels.Color(250, 0, 0));
          pixels.show();
          delay(50);
        }

        else
        {
          pixels.clear();
          pixels.setPixelColor(0, pixels.Color(0, 0, 0));
          pixels.setPixelColor(1, pixels.Color(0, 0, 0));
          pixels.setPixelColor(2, pixels.Color(0, 0, 0));
          pixels.setPixelColor(3, pixels.Color(0, 0, 0));
          pixels.setPixelColor(4, pixels.Color(0, 0, 0));
          pixels.setPixelColor(5, pixels.Color(0, 0, 0));
          pixels.setPixelColor(6, pixels.Color(0, 0, 0));
          pixels.show();
          delay(50);
        }

    }
    if (gps.charsProcessed() < 10)
        Serial.println(F("No GPS data."));
    last = millis();
    Serial.println();
}

}

you have a logic error in your code ... else if (shortestDist < 10) will never execute ... think about what you are telling your program to do

I rearranged the "else if shortestDist" by going "if shortestDist biggest value", else if smaller value and it works, as far as I can see it behaves properly

then you did not post your real code... think about this ... which if statement will execute when shortestDist = 5 ?

put serial.print statements inside the if blocks for debugging purpose

@jsotola I don't know how to post full code here other than pastebin - https://pastebin.com/BWVjdr1S - this works and leds turn on and off as they should. Take a look if you have the time, let me know if there's a better way to format it, as you can pretty much tell I'm not very well versed at this :D

the code in the pastebin is different from the code in your question ... you already posted code in your question ... why would you say that you don't know how to post code?

Common inexpensive GPS modules are likely to report positions that appear to jump around by perhaps 5 meters in good conditions.  Many factors affect GPS accuracy and this uncertainty.  Some are listed here.  It might be problematic to implement a 10 meter distance threshold feature unless conditions are favorable.

Consider constraining your "if" tests more.  For example, use "if ((shortestDist <= 50) && (shortestDist > 30))" instead of "if (shortestDist < 50)".  Continue similarly with the other "if" tests.  Otherwise, once shorttestDist is less then 50 only the 1st "if" test is executed as it will become true and stay true and none of the other "it" tests will be considered.

Consider only using mills(). The posted code uses delay() & millis(). Calling delay() is fine but using millis() is almost always better. Mixing the 2, though, should be avoided.

The logic in the code might be incorrect. It appears GPS data is only process and the LEDs updated when GPS information is unavailable (not new).

When writing embedded firmware, always consider hardware problem sources. Many find small batteries problematic during momentary current demands.  Batteries with small Amp-Hour ratings are more prone to dropping their voltage during a high current events.  Such as when a processor operates a relay or activates a sensor.

Thank you for the input - I will use this with 10m increments on a RC boat, it's just a concept test and the RC moves so slow, it should be good. I can maybe try with 15m, I think it should be ok as I did the walking test and GPS coordinates on the street and was pretty satisfactory. One thing that I noticed with my current IF "solution" - the leds I call up on the strip in the specific IF criteria do light up, but they blink, and in rhythm, so it might be something with else if (millis() - last > 1000)

For the LEDs.  I would recommend creating a version of your code that changes the LED at a fixed & expected rate.  You need to separate out any unexpected GPS affects that may be leading you astray. For the GPS. To get an understanding of GPS noise in your setting (trees, buildings, location, weather, ect) log the data of a stationary GPS for a day.  This will give you a good idea of what you might expect and perhaps ideas as to how to mitigate any noise for your given application.

Going on, a few here will write code and post it. I feel that doesn't help as much as the O.P. figuring out the code for them selves. That said, here are a few items I noticed. You are using delay() & millis(). Calling delay() is fine but using millis() is almost always better. Mixing the 2, though, should be avoided. Your logic might be incorrect. It looks like you only process GPS info & update the LEDs when the GPS info is unavailable (not new). When writing embedded firmware, always consider HW problem sources. Many find small batteries problematic during momentary current demands.

I decided to add a few of these comments to the answer since it might help others who happen across this question / answer.


text:
Ability to calculate bearing related distance with Arduino GPS
Pardon if there's a more precise/technical way of formulating this question :)
What I'm currently working on is a proximity warning with Arduino. There's a preset GPS location in the sketch and if I'm moving closer to it, once I cross a set distace threshold, action is triggered.
I think picture will do better explaining on what challenge I wish to overcome here. Calculating simple "straight line" distance between my current geolocation and the preset destination is easy, but as you can see in the illustration I made, it works from all directions.
100 meter from the target is valid here from any point, or any bearing that the subject might be approaching, which is tedious and not what I want to achieve.
Lower illustration shows what I'd wish to achieve - achieve the trigger criteria only if approaching the destination from certain "bearings"...if that's the right way to phrase it. Hope someone understands what I'm trying to do, if you have some pointers where to start looking and if this can even be achieved on Arduino - do let me know :) Thanks a lot

it's just geometry ... not really about arduino

Perhaps I phrased the question wrong - so it is possible that arduino could detect proximity to a set destination without making a "redundant" circle due to distance radius? Would this be something on the geometry side, or on GPS library side, for example - if location is 100m from the target with the appropriate bearing - then trigger.

so, you want the proximity alert to be valid only if you are walking on a road, for example

Maby reading this (my similar question) will be useful for you : https://arduino.stackexchange.com/questions/91196/how-to-find-the-correct-navigation-course-by-gps-navigation-with-arduino/91197#91197   and also this one for proximity trigger https://arduino.stackexchange.com/questions/91247/how-to-write-a-program-to-do-2-different-loop-task/91253#91253

Note, that you actually don't need specific bearings, but little cones around these bearings, since the position will have some noise in it

@jsotola yes that could be the idea, if I'm approaching the destination from one direction, it triggers, but if I approach the same destination but from another bearing, it doesn't do anything. Curious guy that's an interesting topic you made, I'll look into it!

@chrisl not sure what you mean with cones around bearings? I believe my GPS module parses the bearing data as well, I thought this idea of mine could work by looking at the destination address and preset bearing if that would be possible? For example only trigger action if the distance toward specific LAT LON is less than "value" and if bearing is in the range of "value".

"in the range of value", thats exactly what I meant. It's not just one value, but range range around that value, because the bearing might not be stable and have some noise in it.

Before suggesting a possible solution consider these aspects of the problem:

The question assumes a "flat earth".  For small distances this assumption likely contributes an error that can be ignored.  For larger distances consider calculating the great circle distance.
Consider not every GPS module populates all NMEA fields.  If bearing is supplied consider it is not valid unless the GPS module has moved more than the current accuracy of that GPS module.

While the criteria is simple (only alarm when approaching a given latitude and longitude (or MGRS coordinate) while traveling on a certain bearing), the implementation can be troublesome and / or tedious.  Consider noise.  The position of the GPS module might vary 10 meters while stationary.  Resulting in a false bearing.  The person carrying the GPS may not walk a straight line.  This additional noise may result in never raising an alarm.  If the GPS is carried in a car, roads may not exist for direct travel to the given latitude and longitude. Again, the alarm may never be given.
As it turns out, the assumptions made here indicate bearing is not a good criteria when determining direction of approach to a given latitude and longitude.  Rather, it may be simply the relation between the current latitude and longitude and the given latitude and longitude that offers the best solution.

source: Stack Exchange

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

sort: votes


text:
Interfacing Figaro TGS2600
I am trying to interface TGS 2600 gas sensor to Arduino, particularly to detect methane gas.
Can anyone tell me the conversion equation between Rs/Ro and ppm, so that I can get ppm values from the Rs/Ro ratio. I am looking to detect between 1-10ppm.

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


text:
When accessing a variable from an ISR, is a volatile pointer enough?
Let's say I want to modify a global variable from inside an interrupt service routine. I must ensure that any variables I modify are volatile. Does it work to use a volatile pointer to data I want to modify if the data itself is not volatile?
In my case the data is a struct, but does the answer change if the data is a class, array, or just a variable?
#include <Arduino.h>

#define PIN_INTERRUPT  2

typedef struct MyStruct
{
    int a_field;
} MyStruct;

MyStruct struct_data;
int array_data[32];

volatile bool _flag_ISR = false;
volatile MyStruct *_struct_ISR = &struct_data;
void myISR()
{
    // just some example stuff
    int read = digitalRead(PIN_INTERRUPT);
    _struct_ISR->a_field = read;
    _arr_data_ISR[4] = read;

    _flag_ISR = true;
}

void setup()
{
    attachInterrupt(digitalPinToInterrupt(PIN_INTERRUPT), myISR, CHANGE);
}

void loop()
{
    if (_flag_ISR)
    {
        // do processing here...
        _flag_ISR = false;
    }
}

I think I misunderstood your question the first couple passes through, probably because (I'm guessing) by "volatile pointer" you really meant "pointer to volatile" and the distinction is important.  So, are you asking: "with respect to communicating between the ISR and the main line of execution, is it sufficient to use a pointer-TO-volatile if the thing being pointed-to is, itself, not volatile qualified?"

First, beware that what you have written is not a volatile pointer, it's
a pointer to volatile data. If you always access the object through this
pointer, you should be fine. If you use the pointer in the ISR, but
access the data directly in the main code (bypassing the volatile
qualifier), then the program could fail.
Consider the following:
void loop()
{
    if (_flag_ISR) {
        _flag_ISR = false;
        Serial.println(struct_data.a_field);
    }
}

Once the compiler inlines the call to loop() from main(), the
main program looks like
int main()
{
    init();  // Arduino core initialization
    setup();
    for (;;) {  // inlined loop()
        if (_flag_ISR) {
            _flag_ISR = false;
            Serial.println(struct_data.a_field);
        }
    }
}

And now, since struct_data is not volatile, the compiler can
legitimately optimize the code by avoiding repeatedly accessing the same
RAM location:
int main()
{
    init();  // Arduino core initialization
    setup();
    register int data_copy = struct_data.a_field;
    for (;;) {  // inlined loop()
        if (_flag_ISR) {
            _flag_ISR = false;
            Serial.println(data_copy);
        }
    }
}

And now the program prints only zeros.

Voting yours up.  I think I took their "volatile pointer" phrasing too literally.  Assuming they confirm this understanding of what they meant your answer has pretty much everything I'd have to say about it anyway.  I'm sort of surprised you're using the register keyword.

@timemage: The register keyword is seldom useful in actual code. Here I am using it only to express the idea that the compiler can choose to keep a copy of the data in an internal CPU register (or set of registers).

It's the latter half of that that I was looking for.  You know, you're not even allowed to use it in `17.


text:
nRF24L01 +pa +lna link does not communicate
I’m trying to create a link between two nRF24L01 units. Each nRF24L01+-based module (purchased) is connected to Arduino Nano on a custom-designed PCB.

The printed wiring is per the hardware application, and is functionally verified by the positive result of the isChipConnected() method.

The NRF24L01 is fed from the Nano 3.3V output. According to the component’s datasheet this should be OK:
•   According to the datasheet the max consumption is 9mA when transmitting in high power. The Nano output can source up to 150mA. So it doesn't close to the limit.
•   I measured the 3.3V supply line and the value is 3.23V on both modules (the specified minimum is 3.0V).
•   The supply line is being filtered by a 10uF cap.
The two stations are using the same code; the roles are being defined by the level of an IO pin. It contains two modules - the application and the high-level driver class.
Now to the problem: According to the Arduino screenshots it appears that the transmitter does not sending the data. Since the low-level transmitting routine (radio.write()) is waiting for the receiver auto acknowledge, I considered also the possibility that receiver side doesn't send the auto-ACK. However, I Switched off the auto acknowledge in both stations and the result wasn't changed.
Any clue will be helpful. Thank tou.
#define Radio0_IRQ   2
#define TerminalPin  6
#define CsnPin       10
#define terminalRole 1

String msgHeader;
bool role;
/************************************************/
void(*resetFunc) (void) = 0;//declare reset function at address 0
/***********************************************************/
#include "radioPortClass.h"
RadioPort communicationPort;

/************************************************/
void setup(void)
{
  pinMode(TerminalPin, INPUT_PULLUP);
  role = !digitalRead(TerminalPin);
  if(role == terminalRole)
    msgHeader = "Terminal: ";
  else
    msgHeader = "Field unit: ";

  Serial.begin(9600);
  while (!Serial)
    delay(10);
  if (communicationPort.portInit(role))
    Serial.println(msgHeader + "Port initiated successfully\n\n");
  else if (!radio.isChipConnected ())
  {
    Serial.println(msgHeader + "Port initiation failed\n\n");
    delay(2000);
    resetFunc();
  }
}
/***********************************************************/
void loop(void)
{
  if (role == terminalRole)
  {
// Terminal role. Transmit a message and receive the reply
    if (!communicationPort.tx("Terminal to field unit"))
      Serial.println(msgHeader + "Failed, transmit timed out.\n\n");
    else
    {
      Serial.print(msgHeader + "Got response: ");
      delay(1000);
      Serial.println(communicationPort.rx());
      started_waiting_at = millis();
    }
    delay(3000);
  }
  else  // Field unit role. Receive each packet, print it and reply
  {
    String receive_payload = communicationPort.rx();
    if (receive_payload == "\0")
    {
      if((millis() - started_waiting_at) > rxDelay)
      {
        Serial.println(msgHeader + "Failed, receive timed out.\n\n");
        delay(100);
        resetFunc(); //call reset
      }
    }
    else
    {
      Serial.print  (msgHeader + "Got payload: ");
      Serial.println(receive_payload);
      if (!communicationPort.tx("Field unit to terminal"))
        Serial.println(msgHeader + "Failed, transmit timed out.\n\n");
      else
        Serial.println(msgHeader + "Sent response.\n\n");
    }
  }
}

Radio Driver
class RadioPort
{
  public:
    bool tx(String txData);
    String rx(void);
    bool portInit(bool role);
};
#include "RF24.h"
RF24 radio(9, CsnPin);

const uint64_t pipes[2] = {0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL};
#define rxDelay   1000
#define txDelay   100
unsigned long started_waiting_at;

/************************************************/
bool RadioPort::tx(String txData)
{
// First, stop listening so we can talk.
  radio.stopListening();
  bool success = radio.write(&txData, txData.length());
  radio.startListening();
  return success;
}
/************************************************/
String RadioPort::rx(void)
{
 // if there is data ready
  if (radio.available())
  {
// Fetch the payload, and see if this was the last one.
    uint8_t len = radio.getDynamicPayloadSize();
    char receive_payload[len + 1];
    radio.read(receive_payload, len);
// Put a zero at the end for easy printing
    receive_payload[len] = 0;
    return receive_payload;
  }
  else return "\0";      // Dummy statement, for the compiler warning
}
/************************************************/
bool RadioPort::portInit(bool role)
{
  pinMode(Radio0_IRQ, INPUT_PULLUP);
  radio.begin();//(5,CsnPin)
  if(!radio.isChipConnected ())
    return false;

  radio.enableDynamicPayloads();
  radio.setRetries(15,15);
  radio.setPALevel(0, true);
  radio.setChannel(105);
  radio.setAutoAck(false);//true);

  if (role == terminalRole)
  {
    radio.openWritingPipe(pipes[0]);
    radio.openReadingPipe(1,pipes[1]);
  }
  else
  {
    radio.openWritingPipe(pipes[1]);
    radio.openReadingPipe(1,pipes[0]);
    started_waiting_at = millis();
  }
  radio.startListening();
  return true;
}

"According to the Arduino screenshots" what screenshots? Are you confirming that each Arduino is in its correct role?

Yes: I open a serial monitor for every station. As can be seen from the code, the major activity of the LOOP method of the sketch is printing messages to the serial, which are visible on the serial monitor. All the messages are invoked by failure feedback of the tx and rx methods. The messages are prefixed with the station role, so I know which one sent it.


text:
No communication between two stations that include Arduino Nano and nRF24L01
I'm struggling to establish a link between two Arduino Nano using nRF24L01 (the module that contains PA and LNA). I assume I made a coding mistake (May be in the setup method?), and I need help in finding it.
I’m using the gettingStarted example from the TMRh20 V1.4.1 RF24 library, with slight modifications in the addressing and error messaging. The sketch contains the code for both the transmitter and the receiver, and the selection is done by the ROLE flag in compile time.
Hardware:

I'm using home-designed PCB. For this setup only the Arduino and RF24 modules are assembled.
Power:
a.    The RF24 is fed by the 3.3V output of the Arduino.
b.    There is a 47uF cap to filter the power.
c.    The power traces length is about 20mm, and 1.2 mm thick of 1oz copper.
Measurements
a.    The setup method verifies that the RF24 module is connected to the SPI bus and reacts to the commands. I verified this test by removing and inserting a module. It works.
b.    When the transmitter was running at repetition rate of 1 cycle per second, I used an oscilloscope to measure on the power line of the RF24 module a ripple of 50mV over DC level of 3.25V (per the data sheet the minimum supply voltage is 1.9V).
The setup method verifies explicitly that the RF24 module is connected to the SPI bus and reacts to the commands.

Debugging:

To begin with, the message ** “Transmission failed or timed out” **
was issued.
When I added the line “radio.setAutoAck(false)” to the setup method, the error message was changed into ** “Transmission succeeded; retransmission failed” **. This is odd because I had to explicitly specify a mode that the chip should be in by default.
I replaced both module in both sides to brand new units, to no avail.
I added to the library’s ** write ** function a print of the status register. It reflects transmission success (see below).

Currently the transmitter messages are as follows (the line numbers were added for the notes):
1   Start loop - TX station
2   WRITE TP 3 - TX OK: status=2E
3   Time to transmit = 960 us.
4   Transmission succeeded; transmitted: 0.08
5   Back transmission failed
Notes:

Lines 1, 3, 4 and 5 are issued by the main loop.
Line 2 is the WRITE printout.
a.  Bit 5 of the status is the TX_DS flag, which signify that the TX FIFO status. Active means that the packet was transmitted successfully.
b.  Bits 3:1 mean that RX FIFO is empty.
Line 4 – printout of the transmitted payload. The number is increased in every loop by 0.01.
Lines 5 tells us that the nothing was received from the other side (the receiver reports that he received nothing).

My problem is that either the transmitter doesn't transmit (low probability) or there is a mismatch between the stations. I assume I made a coding mistake (May be in the setup method?), and I’d appreciate any help in finding it.
Or, should I add voltage regulator to increase the 3.25V to 3.3V?
    #include <SPI.h>
#include "RF24.h"
// instantiate an object for the nRF24L01 transceiver
RF24 radio(9, 10);           // using pin 9 for CE, pin 10 for CSN
uint32_t address[2] = {0x123456, 0x654321};
byte role = 1;
float payload = 0.0;
uint16_t counter = 0;
int terminationTimer;
/***********************************************************/
void setup()
{
  Serial.begin(9600);
  while (!Serial) ;
  Serial.println("Starting...");

// initialize the transceiver on the SPI bus
  radio.begin();
// Modification - the installed library doesn't
// return flag. Instead, check the SPI bus by
// changing register contents
  radio.setPALevel(RF24_PA_HIGH);        // RF24_PA_MAX is default.
  bool paError = !radio.isChipConnected() | (radio.getPALevel() != RF24_PA_HIGH);
  radio.setPALevel(RF24_PA_MIN);
  paError |= (radio.getPALevel() != RF24_PA_MIN);
  if(paError)
  {
    Serial.println("Radio HW error");
    while (true) ;                // Halt
  }
  Serial.print("radio role = ");
  Serial.println(role);
  radio.setRetries(15,15);
  radio.setAutoAck(false);

  if(role == 1)
  {
    radio.openWritingPipe(address[1]);    // always uses pipe 0
    radio.openReadingPipe(1, address[0]); // pipe 1 for
    radio.stopListening();                // put radio in TX mode
  }
  else
  {
    radio.openWritingPipe(address[0]);    // always uses pipe 0
    radio.openReadingPipe(1, address[1]); // using pipe 1
    radio.startListening();               // put radio in RX mode
  }
  terminationTimer = millis();
//Serial.println("TP C");
} // setup
/****************************************************************/
void loop()
{
//Serial.println("TP D - start loop; role = " + String(role));
//delay(1000);
  if (role == 1)
  {
Serial.println("\nStart loop - TX station");
 // This device is a TX node
    unsigned long start_timer = micros();            // start the timer
    bool report = radio.write(&payload, sizeof(float)); // transmit & save the result
    uint32_t end_timer = micros();              // end the timer
    if (report)
    {
// All the code in this block is designed for testing only
      Serial.print(("Time to transmit = "));
      Serial.print(end_timer - start_timer); // print the timer
      Serial.println((" us."));
      radio.startListening();               // put radio in RX mode
      Serial.print("Transmission succeeded; transmitted: ");
      Serial.println(String(payload));
      Serial.print("Back transmission ");
      int tDelay = millis();
      while(((millis() - tDelay) < 250) && !radio.available()){}
      if(radio.available())
      {
        float pl;
        radio.read(&pl, sizeof(float));  // fetch payload from FIFO
        Serial.print("succeeded. Retransmitted: ");
        Serial.println(pl);
      }
      else
        Serial.println("failed");
      radio.stopListening();             // put radio in TX mode
      payload += 0.01;                   // increment float payload
    }
    else Serial.println(("Transmission failed or timed out")); // payload was not delivered
// to make this example readable in the serial monitor
    delay(1000);  // slow transmissions down to 1 per second
  }
  else
  {
Serial.println("\nStart loop - RX station");
// This device is a RX node
    uint8_t pipe = 0;
    if (radio.available(/*&pipe*/))   // is there a payload? get the pipe number that recieved it
    {
      uint8_t bytes;
      bytes = sizeof(float);         // get the size of the payload
      radio.read(&payload, bytes);   // fetch payload from FIFO
// The rest of the code in this block is for debugging
      radio.stopListening();          // put radio in TX mode
      delay(10);
      Serial.print("Received ");
      Serial.print(bytes);          // print the size of the payload
      Serial.print((" bytes on pipe "));
      Serial.print(pipe);             // print the pipe number
      Serial.print((": "));
      Serial.print(payload);
      if(radio.write(&payload, bytes))
        Serial.print("; back transmission succeeded.");
      else
        Serial.println("; back transmission failed");
      radio.startListening();          // put radio in RX mode
    }
    else
    {
      Serial.println("no receive");
      delay(700);
    }
  } // role
/*
  if((millis() - terminationTimer) > 10000)
  {
    Serial.println(("Halt"));
      while(true){}
  }
*/
} // loop

I gave up and switched to ESP32


text:
Libraries are not linked
I created 4 libraries, each in .h and .cpp files, and tested them individually. I kept the project flexibility by defining 3 flags that allow or disallow the usage of the libraries.
When integrating them into project I received linking errors.
During the debugging I reduced it to minimum - a single .ino file that contains the minimal declarations and calls; but the error messages are still fired.
I looked at the shrunk code (only 63 lines!) and saw no issue. I'd appreciate any help in finding the issue.

The code:
#define RadioIncluded
#define IrrigationStation
#define RTCincluded

/********************************************/

#ifdef RTCincluded
  class rtcHighLevel
  {
    public:
      String rtcInterpreter(String cmd);
  };
  rtcHighLevel rtc;
#endif

#ifdef IrrigationStation
class measureEC
{
  public:
  void   initMeasurementStation ();
    String SD12_Parser (String commandLine);
};
  measureEC soilParams;

class valveControl
{
  public:
    void   valveInit();
};
  valveControl valve;
#endif

#ifdef RadioIncluded
  class LoRaAddClass
  {
    public:
      void   LoRaBegin(long BAND);
  };
  LoRaAddClass LoRaAdd;
#endif

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

#ifdef RadioIncluded
  LoRaAdd.LoRaBegin(915000000);
#endif

#ifdef IrrigationStation
  valve.valveInit();
  soilParams.initMeasurementStation();
#endif

#ifdef RTCincluded
  String s = rtc.rtcInterpreter("A");
#endif
}
/*********************************************************/
void loop() {}

I see no code there for the functions, so of course it's not going to compile, and complain about there being no code for those functions.

If you had problems with the conditional code surrounding your declarations and class definitions in your header, you would receive an error from the compiler proper. That is, you'd get an error about something undeclared or undefined before linking rather than an unresolved symbol at linking. You're going to have to show more of the build output, ideally not as an image, and perhaps the .cpp file content as well.

I second Majenkos comment: You have the declaration of member functions in the declarations of your classes, but you never actually provide an implementation of those functions. You need to provide at least an empty implementation.

Linking to a library is another beast than separating your sketch into multiple source files. Please make clear what you want to do, and you might want to read relevant chapters about this in the documentation and/or Arduino forum. -- Commonly it is a sign of misunderstanding how libraries work, if you have preprocessor instructions like these conditionals. You might want to learn about the real concept before you try to go on. But as a primitive solution for a simple sItuation it might be OK, however, learn the Right Way as soon as possible. ;-)

Thank you very much for your constructive comments. Although I built some Arduino small sketches I never wrote such a project. First - the correct terminology I should have used is classes rather than libraries. Secondly, according to Majenko and chrisl, I added some lines of codes to every class declaration, and the errors disappeared. So I proceeded to adding the classes by including them.

The result was disappointing - linking errors. So I shrunk the classes to minimum and focused on the RTC and radio classes.. What I found is that: no errors when using the locally declared classes or when using the radio class only. Using the RTC class alone or together with the radio class causes error linkage.

#define RadioIncluded
#define RTCincluded
#ifdef RTCincluded
#include "RTC3231/rtcDS3231HighLevel.h"
/class rtcHighLevel
{
public:
String rtcInterpreter(String cmd) {return cmd;};
};/
rtcHighLevel rtc;
#endif
/***************************************/
#ifdef RadioIncluded
#define LoPowerLevel            5
#define HiPowerLevel            20
#include "communications/LoRaAdd.h"
/class LoRaAddClass
{
public:
void   LoRaBegin(long BAND) {long x = BAND;};
};/
//LoRaAddClass LoRaAdd;
#endif

Solved: while initially I devoted sub-directory for every class, no issues when all the classes were brought to the same folder with the INO file all the issues disappeared. Is this a known issue?

https://arduino.github.io/arduino-cli/0.19/sketch-specification/


text:
Automate capturing photograph on ESP32-CAM
I want to capture photographs from the ESP32 camera, but not doing it manually. Specifically, when a signal is sent from a sensor, I want ESP32 to understand that, and start taking photographs automatically for some seconds. The main problem, is the automation. I have searched on the web a lot, but can't find any answers. I am not expecting answers with code -since this is difficult- rather than some sites that provide solution to my problem. Thank you.

What sensor are you using?

@PythonSchlange ultrasonic.

ping it with an esp8266 monitoring the sensor.

So what about using if(distance <= distance_when_triggered) capture_photo();. I'm not sure if you want to make multiple photos at once, but then you'd have to put capture_photo(); into a for-loop. If this is what you were looking for, I'd suggest learning the basics of C/C++, which will make programming Arduino a lot easier.

Please have a look https://github.com/Yurik72/ESPHap/tree/master/examples/ESPHAPCamera
The project has different things, but definetelly doing what you asked, captures photo by external event, command...

I'll take a look at it. Thanks!


text:
Can UNO log more PCB 353b33 accelerometer data points compared to TDS3014B oscilloscope?
I'm currently recording data points from an analog accelerometer(PCB 353b33) using a TDS3014B oscilloscope which has Record Length of 10,000 points at a Sample Rate 1.25 Ga/s. I'm want to record more data points, would it be possible to use UNO as a data acquisition device and record much higher data points than the oscilloscope(>> 10,000)

For 10 minutes of sampling at 1.25Gsps using 32-bit floats you would need about 3 terabytes of memory. You're not going to even get close to that with a very very powerful desktop. An Arduino...? Dream on. It's never going to happen.
An Arduino has a couple of kB of memory. Plus a slow, crude, ADC. You may get a fraction of a second at its highest sample rate. To stretch it out over 10 minutes you'd be looking at no more than about 800 samples (16 bit values from a 10 bit ADC), so maybe one sample every 1 1/2 seconds.

No way. The UNO has only 2.5kb of RAM, so you can't cache the data points and you would need a very quick link to get the data out. And sampling at 1.25 GigaSamples/s is orders of magnitude beyond an UNO, as its maximum clock frequency is only 16 MHz. An Uno is about $20, while your TDS3014B is around $1500. Sometimes, there's a reason for a different price tag.

So if I want to log data for a period of time say 10 mins, then would using an uno a good idea considering the trade off's being the lower sampling rate. As the problem with the oscilloscope is that it's a triggered logging device and I need data for a period of 10 mins or more.

The sampling rate would be significantly lower, and depending on the signal quality you need, it might not be accurate enough (you did not specify what kind of signal you're measuring). And you need the UNO connected to a PC so that you can transmit and store the collected data right away.


text:
sim800l ftp error after http request
I am using esp32 CAM by Arduino IDE and send an image file by ftp using SIM800l GSM/GPRS  module  to a server and every thing is ok .
I can perform http request also and read some data from a website and every thing is ok.
Problem is ftp for large file  and http request can not work at the same time .
if I send AT+HTTPINIT after AT+FTPEXTPUT=1 , it fails
or if I send AT+FTPEXTPUT=1  after  AT+HTTPINIT again it fails .
I close http connection by AT+SAPBR=0,1 but problem exist
How to solve this problem?
How is possible to clear the setting done in the  the sim800l without restarting the module by AT+CFUN=1,1 ?

I found the way to solve the problem .
Http request must be terminated with command AT+HTTPTERM . After this command large ftp works and command AT+FTPEXTPUT=1 is without error . After termination of ftp if we want to do http request again the command AT+FTPEXTPUT=0 must be executed


text:
sim808 init error when trying to use DFRobot to get gps
I'm using "mega 2650 pro" Arduino with SIM808 BK-808 V-3.1 and I connect the vcc for the sim808 to 5volt pin in the arduino, and the arduino connected with laptop usb. and I add a sim to the sim808 module.
I upload the following code:
#include <DFRobot_sim808.h>
#include <SoftwareSerial.h>

#define PIN_TX 14
#define PIN_RX 15
SoftwareSerial mySerial(PIN_TX,PIN_RX);
DFRobot_SIM808 sim808(&mySerial);//Connect RX,TX,PWR,

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

//******** Initialize sim808 module *************
while(!sim808.init()) {
delay(1000);
Serial.print("Sim808 init error\r\n");
}

//************* Turn on the GPS power************
if( sim808.attachGPS())
Serial.println("Open the GPS power success");
else
Serial.println("Open the GPS power failure");

}

void loop() {
//************** Send the coordinates(latitude&lonitude)in the Serial Monitor *******************
if (sim808.getGPS()) {

Serial.print("latitude :");
Serial.println(sim808.GPSdata.lat);
Serial.print("longitude :");
Serial.println(sim808.GPSdata.lon);

}

}

but the output is
Sim808 init error
and I tried several codes to test AT commands, nothing work!
so what is the problem?

does Sim808 init error print only once?

no, several times. the while loop repeated @jsotola


text:
Is it advisable to use Serial.write in an ISR when loop() routinely uses Serial.read?
I do not know much electronics.
I have Nano v3 as I2C master, it reads 5-byte packets (of delimtted data) from PC's USB port, processes it and forwards it.
I now need to implement a way to signal PC if something went wrong down the line. I don't want to clutter I2C channel and its just a flag so I think interrupt is best for my purpose.
While writing the ISR function I am not sure if its advisable to write data using Serial, because loop might have read 2-3 bytes of the 5-byte message packet. And I don't know if it will overwrite data coming from PC or what...
What will happen if I Serial.write(0x1) (suddenly, in an ISR function) while loop() was reading data from same Serial?
I don't know how to test this myself.

Reading and writing of serial data are separate functions. When you .write() you just append the data to the TX buffer. When you .read() you just take the next character from the RX buffer.
All actual sending and receiving, and filling/emptying of the buffers is done inside the ISRs for the UART module.
That said, you really shouldn't use Serial inside an ISR. This is because the sending and receiving is done by an ISR, and if you are in your ISR then the sending can never happen until you leave your ISR.  For the odd occasional byte it's not really a problem, but if the TX buffer fills up Serial.write() will block until the TX ISR has sent some data - which won't happen since your ISR is blocking the TX ISR.
So it's best to avoid any Serial operations inside an ISR. Instead you would normally set flags and values in an ISR then check for those flags in loop() to report anything.

Roger that. Yeah I am writing just 1 byte and then error handling will take over. I'll mark as answer soon, thanks.


text:
What's the time out of Wire.begin()?
Here's a schematic of my project:

The purpose is to make laptop work as keyboard for desktop PC. Nano uses Serial.read() to get keystrokes from laptop and forwards key press and release data to Leonardo (using I2C) acting as USB-HID keyboard.
Nano's setup looks like:
void setup() {
  Wire.begin();
  Serial.begin(14400);
  Serial.write("Hello");  // https://serialport.io/docs/api-stream#serialpor|
  pinMode(LED_BUILTIN, OUTPUT);
}

Leonardo's setup looks like:
void setup() {
  Keyboard.begin();
  Wire.begin(4);
  Wire.onReceive(cbfunc);
}

I have tested both boards individually, but not the whole setup. Whenever either board connects to USB port it powers up due to +5 volt from USB. Now that I have i2c wires in place, I am confused -
if I connect leonardo & desktop first [and i2c-master (Nano) isn't powered on yet], what will happen at Wire.begin(4)? Will it wait (1s, 5s, forever) until i2c-master comes online?

why don't you write a sketch to test this?

Generally you should not provide power to any pin of a device, which is powered off. That can cause current flowing through clamping diodes to ground and might destroy the pins hardware or the device (also it can lead to weird situations, where the device is somewhat powered through the IO pin, which might lead to instability).
You can either cut the connection between the devices, if only one of them is powered (this should be possible with some extra components), or you can power both devices from one USB port. For the other port you would cut the V+ (positive supply voltage) line of the USB port/cable (this makes sure, that you don't get a bad current between both computers on the USB power line, if they provide a bit different voltage). Since the ground wire still connects both computers and the Arduinos, the communication will still work correctly.

if I connect leonardo & desktop first [and i2c-master (Nano) isn't powered on yet], what will happen at Wire.begin(4)?

The Wire.begin() line won't get stuck, since it doesn't do much on the lines and it doesn't know, if something is connected on the other end, until some transaction happens on the bus. But it might be, that any transaction from the powered Arduino (the master) might cause a blocked I2C bus (since at some places the library waits for the lines to get high. The connection through the clamping diodes might hold the line at low. I'm not sure about that). Then you would need to reset both Arduinos, to make sure, that the bus is in a healthy state.
The solution from above (powering both Arduinos from one USB port) will also make sure, that both Arduinos start at the same time and thus won't block the bus through the clamping diodes.


text:
How to let Stepper motor spin constantly?
When i run the code on the Arduino the Stepper only does a small turn every cycle. How can i make that constantly turning?
 #include <Servo.h>

Servo myservo;  // create servo object to control a servo
// twelve servo objects can be created on most boards

int pos = 0;    // variable to store the servo position
//Servo Teil
#include <Stepper.h>

const int stepsPerRevolution = 200;  // change this to fit the number of steps per revolution
// for your motor

// initialize the stepper library on pins 8 through 11:
Stepper myStepper(stepsPerRevolution, 8, 9, 10, 11);

void setup() {
  // set the speed at 60 rpm:
  myStepper.setSpeed(105);
  // initialize the serial port:
  Serial.begin(9600);
  //Servo
    myservo.attach(3);  // attaches the servo on pin 9 to the servo object
    //Servo

}

void loop() {
  // step one revolution  in one direction:
  Serial.println("clockwise");
  myStepper.step(stepsPerRevolution);
  //Servo
  for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees
    // in steps of 1 degree
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
  for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
  //Servo

}

Does the stepper motor work correctly, when you try it with one of the libraries examples? With your current code the stepper motor should do one revolution (200 steps) per loop() iteration (stopping after the 200 steps, then the servos moves and then the stepper starts again in the next iteration).

rewrite the loop() code ... get rid of the for statements ... refer to the example sketch blinkWithoutDelay for a way to run code at an interval .... every 15 ms move the stepper, then move the servo ... increment/decrement pos accordingly

Yes it does as you say chrisl. Thx jsotola will try it.

You don't "let" a stepper rotate, to get it to move you have to actively step it. When you're not stepping it it stops.

create N square waves, where N is the number of phases in your stepper motor. Make sure the N square waves are appropriately out of phase with one another. Connect amplified versions of the square waves to the stepper motor. The motor will rotate continuously, at a speed determined by the frequency of the square waves.


text:
Nano 33 BLE Sense LED flashing 3/5 slow/fast after upload
I'd successfully got my Nano 33 BLE Sense to read accelerometer data and subject to there being a difference between current and last readings, to send this via the EasyTransfer library to an XBee module over hardware serial that communicated with another module which published the readings to the AWS Cloud via a Nano IoT.  I then ambitiously decided I'd add more sensor data to the payload to include pressure, temperature and humidity.  I added these floats to my data structure (see code below) as well as Boolean flags to indicate if there had been an event (i.e. a reading over a threshold) and if any one of the flags was true, to transmit the payload.  The code compiles fine, uploads to complete but then the LED on the Nano flashes 3 times slowly and 5 times quickly in succession.  I had this last time because I'd forgotten a .begin() statement but adding this fixed the issue.  However, I've gone through my code and can't see what is causing the issue this time.  I have run smaller code units to check the sensors are working which they are. Help!!
#include <EasyTransfer.h>
#include <Arduino_LSM9DS1.h>
#include <Arduino_LPS22HB.h>
#include <Arduino_HTS221.h>

#define TX_PIN 6
#define RX_PIN 5

const float MOTION_TOLERANCE = 0.01;
const float PRESSURE_THRESHOLD = 1000.00;
const float TEMPERATURE_THRESHOLD = 20.00;
const float HUMIDITY_THRESHOLD = 50.00;

UART XBeeTx(digitalPinToPinName(TX_PIN), digitalPinToPinName(RX_PIN), NC, NC);

EasyTransfer ET;

struct SEND_DATA_STRUCTURE {

  String sensorLocation;
  bool motionEvent;
  float xAcc;
  float yAcc;
  float zAcc;
  bool pressureEvent;
  float pressure;
  bool temperatureEvent;
  float temperature;
  bool humidityEvent;
  float humidity;

};

SEND_DATA_STRUCTURE myData;

float xAccCurrent, yAccCurrent, zAccCurrent, xAccLast, yAccLast, zAccLast, pressureReading, temperatureReading, humidityReading;

// ================================================================
// ===                      INITIAL SETUP                       ===
// ================================================================

void setup() {

if(!IMU.begin()) {

  // Stop if IMU fails to initialise
  while(1);

}

if(!BARO.begin()) {

    // Stop if pressure sensor fails to initialise
  while(1);

}
if (!HTS.begin()) {

  // Stop if temp and humidity sensor fails to initialise
  while(1);

}

 // Accelerometer code
   IMU.setAccelFS(3);
   IMU.setAccelODR(5);
   IMU.setAccelOffset(0.003955, -0.010136, -0.013462);
   IMU.setAccelSlope (0.997163, 1.000438, 0.995678);

if (XBeeTx.available()) {

  XBeeTx.begin(9600);
  ET.begin(details(myData), &XBeeTx);

  }

   myData.sensorLocation = "Zone 1";

}

// ================================================================
// ===                    MAIN PROGRAM LOOP                     ===
// ================================================================

void loop() {

if (IMU.accelerationAvailable()) {

    IMU.readAcceleration(xAccCurrent, yAccCurrent, zAccCurrent);

  }

if ((abs(xAccLast -xAccCurrent) > MOTION_TOLERANCE) || (abs(yAccLast -yAccCurrent) > MOTION_TOLERANCE) || (abs(zAccLast -zAccCurrent) > MOTION_TOLERANCE)) {

  myData.motionEvent = true;
  myData.xAcc = xAccCurrent;
  myData.yAcc = yAccCurrent;
  myData.zAcc = zAccCurrent;

  xAccLast = xAccCurrent;
  yAccLast = yAccCurrent;
  zAccLast = zAccCurrent;

}

pressureReading = BARO.readPressure(MILLIBAR);
if (pressureReading > PRESSURE_THRESHOLD) {

  myData.pressureEvent = true;
  myData.pressure = pressureReading;

}

temperatureReading = HTS.readTemperature();
if (temperatureReading > TEMPERATURE_THRESHOLD) {

  myData.temperatureEvent = true;
  myData.temperature = temperatureReading;

}

humidityReading = HTS.readHumidity();
if (humidityReading > HUMIDITY_THRESHOLD) {

  myData.humidityEvent = true;
  myData.humidity = humidityReading;

}

if (myData.motionEvent || myData.pressureEvent || myData.temperatureEvent || myData.humidityEvent) {

 ET.sendData();

 delay(1000);

 myData.motionEvent = false;
 myData.pressureEvent =false;
 myData.temperatureEvent = false;
 myData.humidityEvent =false;

}

}

Add serial prints to find out how long each part of the code takes

Hi,  I could do the board is locking up so the serial monitor doesn't load.  Oddly if I comment out the if (XBeeTx.available()) and just begin() the XBeeTx and ET then it seems to load fine and I can see from the Xbee LEDs that data is being sent by one and received by the other.  So not sure why the XBeeTx.available() isn't triggering the right outcome - it obviously is available otherwise I couldn't begin it?

K, I have no experience with your hardware. Is 9600 the correct baudrate?

Are you sure that calling .begin() after .available() is correct? Seems odd to me.

I've got the code loading ok and the Xbees are obviously communcating but the nano board doesn't seem to be getting any data.  Looking at the GitHub docs for the EasyTransfer library there is some mentioned of a limit of 255 bytes for the struct() so I may have hit that issue but I have the same problem if my struct is just a string and 3 floats.  Worlds fine with 3 floats but adding the string seems to cause a problem.  odd!

Also saw a reference online to a similar (not the same) issue and slowing the baud rate to 1200 seemed to sort that out so I'll look at that as well.

"Odd behaviour" often is a sign that there is a problem with ram usage and if it works when you remove a string strongly suspects the same. Especially on a microcontroller where software is much more predictable, chances are relatively high that ram violations don't result in a crash, but unpredictable behaviour. But if it is a ram problem, decreasing the baudrate should make it even worse as more data is accumulated in a dynamic buffer, so my guess is, that this is only a phantom fix.


text:
Problems with Hardware Serial (UART) on Nano 33 BLE Sense
my new Nano 33 BLE Sense arrived today.  I'm working on a project to send data from the the Nano via an Xbee S2C module to a receiver module connected to a Nano 33 IoT.  I had the project working before using an MPU6050 and Mega 2560 board which worked (using Software Serial on the Mega).  On the IoT side, I am using 'Uart XBeeRx  (&sercom0, 5, 6, SERCOM_RX_PAD_1, UART_TX_PAD_0);' to process the data from the Xbee.  Having tried this syntax on the BLE Sense I hit problems and after some Googling found a different syntax.  However my new code isn't working in so far as it compiles, uploads and then crashes the BLE Sense (serial port disappears from tools and the onboard LED blinks slowly and erratically).  I need to keep resetting the board and suspect there is some issue with my hardware serial implementation.  I've cut the code down to simply send accelerometer data.  My code is as follows - the EasyTransfer library simplifies the Xbee comms.  Any help appreciated!
#include <EasyTransfer.h>
#include <Arduino_LSM9DS1.h>

UART XBeeTx (digitalPinToPinName(6), digitalPinToPinName(5), NC, NC);

EasyTransfer ET;

struct SEND_DATA_STRUCTURE {

  float xAcc;
  float yAcc;
  float zAcc;

};

SEND_DATA_STRUCTURE myData;

// ================================================================
// ===                      INITIAL SETUP                       ===
// ================================================================

void setup() {

XBeeTx.begin(9600);

ET.begin(details(myData), &XBeeTx);

}

// ================================================================
// ===                    MAIN PROGRAM LOOP                     ===
// ================================================================

void loop() {

  float x, y, z;

if (IMU.accelerationAvailable()) {
    IMU.readAcceleration(x, y, z);

  }

  myData.xAcc = x;
  myData.yAcc = y;
  myData.zAcc = z;

  ET.sendData();

}

why not use Serial1? (on Mega too)

Hi,  I tried that connecting my Xbee out and in pins to D0 and D1 (UART Rx and Tx) but the same problem and using Serial1.begin(9600) and &Serial1 in the ET.begin statement in the code above.  The Nano Sense seems to lose its USB connection and locks up.  Really can't work out why as it should work.  I think the board is OK as I can run some of the example scripts just fine (e.g. accelerometer and print to the USB serial).  Google seems really light on hits for UART Hardware Serial in the BLE Sense!

The two boards are use different Arduino cores.  The IoT 33 uses a chip family common to Arduino boards; the Nordic Semi ARM chip that's in the BLE Sense is much less so.  The ARM chips used in these devices are only so related.  The  "SERCOM_RX_PAD_1" naming is connected to Atmel (and the 33 IoT); using it as a search term in finding a solution to doing this on your BLE Sense maybe counterproductive.

Doh!  I'm a muppet!!   I'm making a call to IMU without having put IMU.begin() in setup.  I'd deleted it along with some other code that was redundant but added it back in and the project works like a dream!  BLE Sense unit works properly and receiver unit getting the data over the Xbee comms now.  Thanks for the comments though.

@RobM, if this is something that makes sense following from the question, in a way that might be useful to someone else, you can post an answer your own question.  If the solution has nothing to do with the question asked, then probably the thing to do is just delete the question.

You can't make calls to IMU if you haven't initialised it with IMU.begin()

You should be able to mark your own answer as accepted.


text:
Dealing with noise in arduino interrupt
I'm makeing two modules,
module2 gets sensor signal, and send wireless message to module1, with HC-12. Then module1 is going to do some work it is supposed to do. Circuit configuration is in the picture.
I tested HC-12 communication, and they send, receive well. But my problem is that,
when module1 gets turned ON, Interrupt gets activated (LOW) and module2 sends signal that's not supposed to send. It seems it is because of electromagnetic wave noise, from HC-12.
How can I filter this noise, using code ? Now I'm stuck for the last 3 days.

code
Module1
#include <SimpleTimer.h>

#include <LiquidCrystal_I2C.h>
#include <SoftwareSerial.h>

// #define IDlen 4
#define maxID 5

SoftwareSerial mySerial(2,3);
LiquidCrystal_I2C lcd(0x27, 16, 2);
int upButtonPin = 7;
int selectButtonPin = 6;
int downButtonPin = 5;
int sensors[maxID] = {1001,9999,9999,9999,9999};
int receivedID = 0;
int currentPos = 0;
String rcvMsg = "xxxx";

//void printSensor(int intID);
void menu();
void showAllSensors();
int removeID(int senNumInt);

void setup()
{
  Serial.begin(9600);
  Serial.println("Serial began.");

  mySerial.begin(9600);
//  mySerial.println("0000");

  lcd.begin();
  pinMode(upButtonPin,  INPUT_PULLUP);
  pinMode(selectButtonPin, INPUT_PULLUP);
  pinMode(downButtonPin, INPUT_PULLUP);
}

void loop()
{
  rcvMsg = "xxxx";
  lcd.setCursor(1,1);
  lcd.clear();
  lcd.print("Ready");
  if(digitalRead(upButtonPin)==LOW){
    lcd.clear();
    lcd.print("Up btn pressed!");
  }
  if(digitalRead(downButtonPin)==LOW){
    lcd.clear();
    lcd.print("Down btn pressed!");
  }
  if(digitalRead(selectButtonPin)==LOW){
    lcd.clear();
    lcd.print("Registered sensors:");
    delay(1000);
    lcd.clear();
    showAllSensors();
    menu();
  }
  if(mySerial.available()>0){

//    String rcvMsg = mySerial.readStringUntil('\n');
    rcvMsg = mySerial.readStringUntil('\n');
    Serial.print("Received msg: ");
    Serial.print(rcvMsg);
    Serial.print('\n');
    receivedID = rcvMsg.substring(0,4).toInt();
    Serial.println(receivedID);
    delay(50);

    for (int i=0;i<maxID;i++){
      if(sensors[i] == receivedID){
        String temp = String(receivedID);
        String ack = String(temp + "01"); // 01: success 02: reject (ID does not exist)
        mySerial.println(ack);
        Serial.print("Ack sent: ");
        Serial.print(ack);
      }
    }
  }
}

void menu(){
  lcd.print("UP: add sensor");
  lcd.setCursor(0,1);
  lcd.print("DOWN: del sensor");
  lcd.setCursor(0,0);

  while(1){
    if(digitalRead(upButtonPin)==LOW){
      lcd.clear();
      lcd.print("Add sensor:");
      delay(1500);
      lcd.clear();
      int senNumInt = 1000;
      char senNum[IDlen];
      sprintf(senNum, "%d", senNumInt);

      while(1){
        lcd.print(senNum);
        if(digitalRead(upButtonPin)==LOW){
          senNumInt++;
          sprintf(senNum, "%d", senNumInt);
          lcd.clear();
          lcd.print(senNum);
        }
        if(digitalRead(downButtonPin)==LOW){
          senNumInt--;
          sprintf(senNum, "%d", senNumInt);
          lcd.clear();
          lcd.print(senNum);
        }
        if(digitalRead(selectButtonPin)==LOW){
          lcd.clear();
          lcd.print(senNum);
          lcd.setCursor(0,1);
          lcd.print("Menu: OK, Down: Cancel");
          //센서 입력값을 받아서, 리스트에 넣어 놓기
          sensors[currentPos] = senNumInt;
          lcd.clear();
          showAllSensors();
          delay(1500);
          break; // 값 입력 후 저장한 것 보여주고... 나가기.
        }
        delay(200);
        lcd.clear();
      }
      delay(200);
      break;
    } // up button 누름 메뉴 끝

    if(digitalRead(downButtonPin)==LOW){
      lcd.clear();
      lcd.print("Remove sensor:");
      delay(1500);
      lcd.clear();
      int senNumInt = 1000;
      char senNum[IDlen];
      sprintf(senNum, "%d", senNumInt);

      while(1){
        lcd.print(senNum);
        if(digitalRead(upButtonPin)==LOW){
          senNumInt++;
          sprintf(senNum, "%d", senNumInt);
          lcd.clear();
          lcd.print(senNum);
        }
        if(digitalRead(downButtonPin)==LOW){
          senNumInt--;
          sprintf(senNum, "%d", senNumInt);
          lcd.clear();
          lcd.print(senNum);
        }
        if(digitalRead(selectButtonPin)==LOW){
          lcd.clear();
          lcd.print(senNum);
          lcd.setCursor(0,1);
          lcd.print("Delete sensor");
          delay(600);
          lcd.clear();

          //센서 입력값을 받아서, 리스트에서 찾은 후 삭제
          int result = removeID(senNumInt);
          if(result==1){
            lcd.print("Deleted.");
            showAllSensors();
          }else{
            lcd.print("No such ID!!");
          };
          delay(1500);
          break; // 값 입력 후 저장한 것 보여주고... 나가기.
        }
        delay(200);
        lcd.clear();
      }
      delay(200);
      break;
    } // down button 누름 메뉴 끝

    delay(200);
  }
  return;
}

void showAllSensors(){
  char imsi[IDlen];
  for(int i=0;i<maxID;i++){
    Serial.println(sensors[i]);
    sprintf(imsi, "%d", sensors[i]);
    lcd.print(imsi);
    delay(800);
    lcd.clear();
  }
  return;
}

int removeID(int senNumInt){
  int isFound = 0;
  for(int i=0;i<maxID;i++){
    if(sensors[i] == senNumInt){
      sensors[i] = 9999;
      isFound = 1;
    }
  }
  return isFound;
}

codeModule2
#include <SoftwareSerial.h>
#include <avr/sleep.h>
#include <SimpleTimer.h>

SimpleTimer timer;
const int wakeUpPin = 2; // pin of interrupt 0
const int LED = 8;
const int numMsg = 1; // For the safety, send multiple messages, everytime.
boolean armed = false;
SoftwareSerial mySerial(4,5);
String ID = "1001";
String code = "01";
String msg = "xxxx";
String rcvMsg = "xxxx";
int timerID = 0;
boolean isWaked = false;
int pulseWidth = 0;

/*
  Communication protocol
  01: powered on
  02: Sensor touched (Feed is full)
  03: alive
*/

void setup()
{
  String msg = String(ID + code);
  pinMode(wakeUpPin, INPUT_PULLUP);
  pinMode(LED, OUTPUT);
  timerID = timer.setInterval(1000, sendMsg);

  Serial.begin(9600);
  mySerial.begin(9600);
  Serial.println(msg);
  delay(100);
}

void loop() // 반복
{
  pulseWidth = pulseIn(wakeUpPin, LOW, 100000);
  Serial.println("start loop.");
  armed = true;
  delay(100);
  Serial.println("Now sleeping..");
  delay(200);
  sleepNow();

  Serial.println(pulseWidth);
  if(armed){
    Serial.println("Waked up. Send Feed full msg.");

    delay(200);
    code = "02";
    msg = String(ID + code);
    sendMsg();
    int count = 0;
    while(1){
      count++;
      if(count>200){      //prevent infinite loop
        count = 0;
        break;
      }
      Serial.print('*');
      if(mySerial.available()>0){
        Serial.println("RECEIVED!!!!");
        rcvMsg = mySerial.readStringUntil('\n');
        if(rcvMsg.substring(0,4).equals(ID)){
//          timer.deleteTimer(timerID);
          Serial.println("My msg is received successfully. Now sleep again..\n");
          break;
        }
      }
      delay(50);
    }
    armed = false;
  }
}

void wakeUpNow(){
  isWaked = true;
  return;
}

void sleepNow(){
  Serial.println("Entered sleep now()");
  delay(100);
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_enable();
  attachInterrupt(0,wakeUpNow, LOW);
  sleep_mode();
  // When wakes up, resume codes from here.
  sleep_disable();

  detachInterrupt(0);
  return;
}

void sendMsg(){
  for (int i=0;i<numMsg;i++){
    mySerial.println(msg);
  }
  return;
}

I'm not sure if this is a diagnostic test or an answer, because they may be roughly the same thing.  I'm guessing your testing these in close proximity.  What I'd tell you to do is put a stronger pull-up on pin 2.  Put 1kOhm (just to pick a number) from pin 2 to 5V and switch pinMode to INPUT rather than INPUT_PULLUP.  See what, if any, difference that makes.

emi/rfi choke collars/ferrite "beads" on vcc and signal wires might solve your problem in hardware. Try some from an old miniUSB cord and see if they help.

I know, it is not exactly what you asked for, but I recommend hardware filtering. I had problems with noise on interrupts and I was able to solve that with this component: https://www.st.com/content/st_com/en/products/emi-filtering-and-signal-conditioning/integrated-emi-filtering-and-esd-protection/computer-legacy-port-ipad/kbmf.html#overview
It is not expensive and saves you a lot of headache.
If you can't use SMD components, you can rebuild the circuit of that filter with capacitors and resistors, just be sure, that you put the filter as close as possible to the interrupt pin.


text:
Servo motor won't work for a specific code
I have written a code with interrupts to control the servo but my servos are not working. One is meant to work with interrupt but the other one has to simply move but it is also not working. Even the serial window shows that the code is working properly ut the servos aren't moving I have checked both my servos with same connections and Sweep example of Arduino and both work fine.
#include <TimerOne.h>                                 // Header file for TimerOne library
#include <Servo.h>
#define trigPin 12                                    // Pin 12 trigger output
#define echoPin 2                                     // Pin 2 Echo input

#define echo_int 0                                    // Interrupt id for echo pulse

#define TIMER_US 50                                   // 50 uS timer duration
#define TICK_COUNTS 4000                              // 200 mS worth of timer ticks

volatile long echo_start = 0;                         // Records start of echo pulse
volatile long echo_end = 0;                           // Records end of echo pulse
volatile long echo_duration = 0;                      // Duration - difference between end and start
volatile int trigger_time_count = 0;                  // Count down counter to trigger pulse time
volatile long range_flasher_counter = 0;              // Count down counter for flashing distance LED

int sound = 250;

Servo servo1; //Servos
Servo servo2;

const int button1 = 10; //Buttons
const int button2 = 8;
const int button3 = 13;
const byte interruptPin = 3;
int pos;

void setup() {
  servo1.attach(9); // servo for arm
  servo2.attach(5); // servo for base
  pinMode(trigPin, OUTPUT);                           // Trigger pin set to output
  pinMode(echoPin, INPUT);                            // Echo pin set to input
                      // Onboard LED pin set to output

  Timer1.initialize(TIMER_US);                        // Initialise timer 1
  Timer1.attachInterrupt( timerIsr );                 // Attach interrupt to the timer service routine
  attachInterrupt(echo_int, echo_interrupt, CHANGE);
  pinMode(interruptPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin),Metal_detected, HIGH);

  pinMode(button1, INPUT);
  pinMode(button2, INPUT);
  Serial.begin(9600);
}

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

  servo1.write(0); // These will make the servos move to the mapped angles
  servo2.write(90);

  distance_checking();
  if(digitalRead(button1) == HIGH)
  {

      while(digitalRead(button2) == LOW)
        {
          Serial.println("Entering Sweeping mode");
       for (pos = 30; pos <= 150; pos += 1)
       { Serial.print("Angle is :");
         Serial.println(pos);
         servo2.write(pos);
         distance_checking();
         //delay(0.1);                       // waits 15ms for the servo to reach the position
         if(digitalRead(button2) == HIGH)
          {
            Serial.print("Exiting Sweeping");
            goto label;}
          }
          for (pos = 150; pos >= 30; pos -= 1) { // goes from 180 degrees to 0 degree
          Serial.print("Angle is :");
          Serial.println(pos);
          servo2.write(pos);              // tell servo to go to position in variable 'pos'
          distance_checking();
          //delay(0.1);                       // waits 15ms for the servo to reach the position
          if(digitalRead(button2) == HIGH)
          {
            goto label;
            Serial.print("Exiting Sweeping");}
          }

 }
 }
//reset th
label:
  if(digitalRead(button2) == HIGH){

    servo1.write(0);
    servo2.write(90);
    Serial.println("press the sweeping button to enter sweeeping mode");
    delay(300);
  }

}

void distance_checking()
{

if (echo_duration/58 <= 20)
{
Serial.println("the servo angle is 30");
servo1.write(30);
delay(1500);
}

else {
servo1.write(0);
}

delay(500);
}

void Metal_detected()
{if(digitalRead(button2) == LOW)
{delay(5000);
  Serial.print("Metal detected at servo angle:");
Serial.println(servo2.read());
servo1.write(servo1.read());
servo2.write(servo2.read());
Serial.println("Motion is stopped");
Serial.println("Press reset to go to the home position");

}
//while(digitalRead(button2) == HIGH)
// {
//  Serial.print("Reseting");
//  return 0;}
 }
void timerIsr()
{
    trigger_pulse();                                 // Schedule the trigger pulses
                             // Flash the onboard LED distance indicator
}

// --------------------------
// trigger_pulse() called every 50 uS to schedule trigger pulses.
// Generates a pulse one timer tick long.
// Minimum trigger pulse width for the HC-SR04 is 10 us. This system
// delivers a 50 uS pulse.
// --------------------------
void trigger_pulse()
{
      static volatile int state = 0;                 // State machine variable

      if (!(--trigger_time_count))                   // Count to 200mS
      {                                              // Time out - Initiate trigger pulse
         trigger_time_count = TICK_COUNTS;           // Reload
         state = 1;                                  // Changing to state 1 initiates a pulse
      }

      switch(state)                                  // State machine handles delivery of trigger pulse
      {
        case 0:                                      // Normal state does nothing
            break;

        case 1:                                      // Initiate pulse
           digitalWrite(trigPin, HIGH);              // Set the trigger output high
           state = 2;                                // and set state to 2
           break;

        case 2:                                      // Complete the pulse
        default:
           digitalWrite(trigPin, LOW);               // Set the trigger output low
           state = 0;                                // and return state to normal 0
           break;
     }
}

// --------------------------
// echo_interrupt() External interrupt from HC-SR04 echo signal.
// Called every time the echo signal changes state.
//
// Note: this routine does not handle the case where the timer
//       counter overflows which will result in the occassional error.
// --------------------------
void echo_interrupt()
{
  switch (digitalRead(echoPin))                     // Test to see if the signal is high or low
  {
    case HIGH:                                      // High so must be the start of the echo pulse
      echo_end = 0;                                 // Clear the end time
      echo_start = micros();                        // Save the start time
      break;

    case LOW:                                       // Low so must be the end of hte echo pulse
      echo_end = micros();                          // Save the end time
      echo_duration = echo_end - echo_start;        // Calculate the pulse duration
      break;
  }
}

I tested my motors with this code one by one and they worked absolutely fine:
#include <Servo.h>

Servo myservo;  // create servo object to control a servo
// twelve servo objects can be created on most boards

int pos = 0;    // variable to store the servo position

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

void loop() {
  for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees
    // in steps of 1 degree
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
  for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
}

Your code is really hard to follow and the indention is all over the place. Also I don't understand the reason why you are using a timer interrupt and an external interrupt just for reading the ultrasonic sensor, but then using many long delay() calls. Can you please describe how exactly you want the code to behave?

I think the Servo library uses Timer1. Thus using both at the same time can lead to problems

The thing is that I am using both interrupts of Arduino Uno. One for the data from Ultrasonic and one for the other signal that I have to attach to pin3. The code works the way that one servo keeps sweeping to the angle between 30 and 150 until the distance from the ultrasonic is greater than 20cm ,as the distance gets less it has to follow the function "distance_checking"


text:
how to run 2 different servo (continuous rotation and regular servo) in parallel, not run one after other?
I need to control 2 servos in parallel, whereas one is of continuous rotation and another is of regular positioning control (angle) on arduino IDE. I tried but it works one after another, not parallel. How can I do that, please suggest. Thanks.

Please post the code that is not working as expected in a minimum example. Then I can try to help.

you can only control one at a time. You can switch between both servo after, so that, it seems to be happening in parallel

I am proposing one answer
https://wokwi.com/arduino/projects/297646292038844936
Here, we are not using the delay function. We are using the millis()
Based on your actual application, you can control individual servo accordingly.
Here is the Arduino simulation:
https://wokwi.com/arduino/projects/297646292038844936

/* Sweep
  by BARRAGAN <http://barraganstudio.com>
  This example code is in the public domain.

  modified 8 Nov 2013
  by Scott Fitzgerald
  http://www.arduino.cc/en/Tutorial/Sweep
*/

#include <Servo.h>

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

// twelve servo objects can be created on most boards
unsigned long previousMillis = 0;        // will store last time LED was updated
const long interval = 15;           // interval at which to blink (milliseconds)

int pos = 0;    // variable to store the servo position
int pos2 = 0;    // variable to store the servo position

void setup() {
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object
  myservo2.attach(10);  // attaches the servo on pin 9 to the servo object

}

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

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

    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    pos = pos + 1;
    if (pos > 180) {
      pos = 0;
    }                      // waits 15ms for the servo to reach the position

    myservo2.write(pos2);              // tell servo to go to position in variable 'pos'
    pos2 = pos2 + 1;
    if (pos2 > 90) {
      pos2 = 0;
    }

  }

}

As i know, there is no way for a single arduino or any other microcontrollers to command on pins in exactly same time and it's because of microcontrollers nature.
When you have to command 2 outputs
Microcontroller will be act like this :
Command 1 .... To pin number 9
Command 2 .... To pin number 10
and for example if your microcontroller, like arduino or others do each command in one complete clock cycle and your clock frequency will be 16 MHz, so each cycle's time period is 62.5 nano-seconds.
So your microcontroller will do your command in first clock cycle and do the second command in next clock cycle,
In the other words, command 2 will do 62.5 nano-second after command one (if each those commands takes just one clock cycle) but in normal 16 MHz arduino boards it takes much much more time to do commands like this and it was just an example to understand it's principle, and because of this reason i suggest you to connect both servomotors into same output PWM pin if you are using two standard servomotors;
But the main issue is different angle limitations of your servomotors and it's impossible to control them when you want one of them to rotate 360 deg. and the other must rotate 180 deg. .
If you connect those signal pin to a same output, you have two options with two issuse.
First, if you command to the output pin to turn 360 deg. , All things will be good but when your output pin command for angles more than 180 deg. , The little servo will stop.
Second, if you limit your rotation to 180 deg., You will not be able to rotate 360 deg. Your bigger servomotor.
I hope my description will be useful and face you by your complete pattern of what's going on in this project's issue

The angel of two Servomotors should be same ?
If yes,
Try this for 180 deg. Servos :
You can connect signal pin of ech servo to a specific PWM pin of Arduino like pin number '9' in this example
It's just for test but you can change this how you want to
I hope it will work you,
Good luck
#include <Servo.h>

Servo myservo;

int PWMpin = 9;  // change this for your circuit configuration

int a = 0;

void setup() {
  myservo.attach(9);
  myservo.write(0);  // set servo to mid-point
}
void loop() {
  for (int i = 0; i < 180; i++) {
   myservo.write(i);
    delay(10);
  If (i == 180) {
    analogWrite(PWMpin, a);
    }
  }
}

Please don't post code as a image.

Thanks @Hamid 'Smith' Salehi for your reply. well, the servos I am using are not the same, i mean one is of continuous rotation and one is regular, so what i wish to have it like the continuous rotation servos should be rotate with the regular servo which should run between 0~180 deg in parallel. ans these are connected to pin 9 and 10 respectively.

The only difference of servomotors is their rotation limitations? Both of them works by standard PWM ?


text:
Converting ESP32 SPI code to Arduino for MAX6921 IV-18 driver board
I purchased a IV-18 VFD tube driver module, which came with some example code for an ESP32 board. The driver module has a 20 output MAX6921 serial chip to drive the vacuum tube. I want to use this driver module with an Arduino Uno and then eventually a Raspberry Pi.
I think I have a very rough understanding of the electronics and demo code, but cannot seem to get my SPI calls to work. Rather than trying to translate the demo code in its entirety, my first goal is to just get one segment to light up.
Quick background
The IV18 tube has 9 grids. The first grid has only a dot and a dash, but the remaining 8 grid have 7 segments and a decimal point.

To light a segment, you provide power to the segment pins / decimal point and to the grid for that segment. To display several numbers, you have to quickly cycle through lighting each of the grid positions and the relevant segments for that position. If you cycle through this fast enough, the human eye sees the whole grid with numbers (persistence of vision).
What I have tried
So far, I have made the connections from the Arduino Uno to the driver board
Driver GND   - Uno GND
Driver 5V    - Uno +5V
Driver Din   - Uno digital pin 11 / MOSI
Driver CLK   - Uno digital pin 13 / SCK
Driver LOAD  - Uno digital pin 2
Driver BLANK - Uno digital pin 3
Driver Dout  - Not connected

The example code has hex codes which I believe are then translated to a 24 bit buffer (although only 17 bits are required) to send via SPI to set the MAX6921 outputs HIGH or LOW.
I think the bits required are as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

G7
G6
G5
G4
G3
G2
G1
G0
SEG_G
SEG_F
SEG_E
SEG_D
SEG_C
SEG_B
SEG_A
SIGN

DP

So to light the number 8 in the righthand most grid, I assumed I'd need the 8th bit high (grid) and bits 9,10,11,12,13,14 and 15 for the 7 semens for the "8".
In my setup function, I call SPI.begin and then SPI.transfer with what I assumed was the matching binary data (from right to left, I think because of the bit order LSB/MSB?):
SPI.transfer(0b000000000111111110000000);
This lights the first grid (the one after the degree and minus sign) but not what I want - I see some segments in the leftmost grid (the full grid, not the grid with the dot and minus) but these light in a different pattern each time  (varies each time I reset or re-upload which I think is to be expected as I'm pushing data to the MAX6921 each time).
This is my code so far
#include "SPI.h"

#define DISP_CLK 13   // White - SPI SCK
#define DISP_DATA 11  // Yellow - SPI MOSI
#define DISP_LOAD 2   // Blue
#define DISP_BLANK 3  // Green

void setup() {
  Serial.begin(9600);
  Serial.println("IV18 Test");

  SPI.begin();

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

  pinMode(DISP_LOAD, OUTPUT);
  digitalWrite(DISP_LOAD, HIGH);

  SPI.transfer(0b000000000111111110000000);
}

void loop() {

}

I'm pretty sure the two fundamental things I have wrong here are the bits of data to send and then the correct use of the SPI.
Can someone please help me to understand the ESP32 code properly, and ideally help me get the correct data to send via SPI so that I can light up the segments & grid positions that I expect to.

SPI.transfer() does only serve the clock and write/read MOSI/MISO. It does not bring the CS low to select the SPI slave.

So it turns out that I got a few things wrong.
UPDATE: Working code is now on my GitHub if anyone is interested.
Firstly, I misunderstood the example code and made a mess of the bits to send to the MAX6921. To work out the correct mapping, I went and probed each pin of the IV-18 and noted the connection to the pins / outputs of the MAX6921 which gave me this table:

BIT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

IV-18
G9
G8
G7
G6
G5
G4
G3
G2
G1
A
B
C
D
E
F
G
DP

MAX6921
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

Note that the MAX6921 value is the OUTPUT number and not the PIN number
This then gave me the correct order for each bit to send, as noted in the top row of the table.
The next mistake was trying to send all 24 bits in one go. Instead, I broke each byte into a separate SPI.transfer() call which finally let me display the segments in the grid position that I expected.
For example, to display "HELLO", my loop function has this:
void loop() {
  //             XXXXXXXDP                 GFEDCBA1                  23456789
  SPI.transfer(0b00000000); SPI.transfer(0b11101100); SPI.transfer(0b10000000); delay(1);
  SPI.transfer(0b00000000); SPI.transfer(0b11110010); SPI.transfer(0b01000000); delay(1);
  SPI.transfer(0b00000000); SPI.transfer(0b01110000); SPI.transfer(0b00100000); delay(1);
  SPI.transfer(0b00000000); SPI.transfer(0b01110000); SPI.transfer(0b00010000); delay(1);
  SPI.transfer(0b00000001); SPI.transfer(0b01111110); SPI.transfer(0b00001000); delay(1);
}

I have setup TIMER1 to use instead of the loop/delay code, so hopefully I can finish converting the rest of the example code to Arduino.


text:
How to show the distance in decimal use sensor TF-Luna Lidar or more specific value
I want to ask about TF-Lunar Lidar, I've written code to know the distance in cm by reading the array data, right now I need some help about how to read the data so it can be showing the more specific value (float or in decimal)
Or do you guys know what is the speed of the waves transmitted and captured by the lidar sensor, so that I can calculate it in a more specific form, such as using the method of calculating the distance on the Hc-srf04 sensor
I also have used this format to read the distance in mm, but It never works (image about array data)

it is unclear what you are trying to do ... you said that you are able to measure the distance in cm ... what is more specific value?

i'm sorry, what i mean is below cm, (mm or below) because the sensor only show it in cm like 1.00, 2.00 it wont show 1.01 or 1.02
sorry for my bad english

Re “the speed of the waves”: The “li” in “lidar” stands for “light”. Light waves travel at the speed of light.

so if i inputting the duration of the light travel from trigger to echo, i can find the distance?. will it work?

so if i inputting the duration of the light travel from trigger to echo, i can find the distance?. will it work?

That's the basic working principle, but you cannot do that with an Arduino. Light is too fast, resulting in incredibly small travel times. You need specialized hardware for that. And thats, what a Lidar sensor (or other Time Of Flight sensor) are.

The TF-Lunar Lidar sensor supports different output formats. The distance in cm is just the default. There is also the format, that you showed in your question (9 byte mm), which gives you the distance in mm. The manual of the TF-Lunar also explains how to change the used output format (look at page 22: "5.Output format setting ID_OUTPUT_FORMAT=0x05"). How exactly this is done depends on your actual code and the used communication interface (Serial or I2C).

Thank you for the answer sir, that's very helpful and informative.
But since I can't use the I2c because I can't find the address when I connect it to Arduino (search the address with the i2c scanner), so I need to research how to find it because I'm still learning to program Arduino without a library (.h file and .cpp file)


text:
Problem with ESP32 bluetooth
I am trying to connect ESP32 via bluetooth classic to my PC to transfer some data from a sensor.
As a first step, I am simply trying to send some random data over bluetooth serial. The code is at follows:
#include "BluetoothSerial.h"

#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
#error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
#endif

int myData[8];
BluetoothSerial SerialBT;

void setup() {
  Serial.begin(115200);
  Serial.println("Opening Serial Connection on COM4");
  SerialBT.begin("ESP32"); //Bluetooth device name
  SerialBT.println("Opening Serial Bluetooth Connection on COM6");

}

void loop() {

  for(int i = 0; i < 8; i++)
  {
    myData[i] = random(0,500);
  }
  if(Serial.available())
    {

     for(int i = 0; i < 8; i++)
  {
    SerialBT.write(myData[i]);
  }

    }
    delay(20);
}

In Windows bluetooth settings, I have paired the ESP32 with windows and connected it. I have set up incoming and outgoing COM ports for bluetooth where incoming port is  COM6 and outgoing port is COM5.
However, when I open arduino serial monitor for COM6, it is empty and no data is being printed. I am using arduino IDE. Furthermore, on COM4, there is nothing printed despite the Serial.println("Opening Serial Connection on COM4"); command which I think should work regardless of bluetooth.
I have tried everything I can think of. I would be grateful if anyone can help me solve this problem as I have been stuck for days


text:
Communication code between nrf24l01's suddenly not working. Hardware is fine
I specifically had saved code for the purpose of checking the connection, but it doesn't seem to work anymore.
All the examples from this simple tutorial work, so it can't be a hardware issue.
Maybe someone can find a reason why the code wouldn't work? It returns radio.available() as false
//Transmitter
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

RF24 radio(7, 8); // CE, CSN
const byte addresses[][6] = {"00001", "00002"};
float valueTransmit;
float valueRecieved;

void setup() {
  Serial.begin(9600);
  radio.begin();
  radio.openWritingPipe(addresses[1]); // 00002
  radio.openReadingPipe(1, addresses[0]); // 00001
  radio.setPALevel(RF24_PA_LOW);
  valueTransmit = 0
}
void loop() {
  radio.stopListening();
  radio.write(&valueTransmit, sizeof(valueTransmit));
  delay(5);

  radio.startListening();
  if (radio.available() ) {
      radio.read( &valueRecieved, sizeof(valueRecieved) );
  Serial.print(valueRecieved);
  valueTransmit = valueRecieved + 0.01;
  }
}

//Reciever
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

RF24 radio(7, 8); // CE, CSN
const byte addresses[][6] = {"00001", "00002"};
float valueTransmit;
float valueRecieved;

void setup() {
  Serial.begin(9600);
  radio.begin();
  radio.openWritingPipe(addresses[0]); // 00001
  radio.openReadingPipe(1, addresses[1]); // 00002
  radio.setPALevel(RF24_PA_LOW);
}
void loop() {
  radio.startListening();
  if (radio.available() ) {
    radio.read( &valueRecieved, sizeof(valueRecieved) );
    Serial.print(valueRecieved);
    valueTransmit = valueRecieved + 1;
  }

  radio.stopListening();
  radio.write(&valueTransmit, sizeof(valueTransmit));
  delay(5);

}

suddenly not working means that it was working and it failed without any changes ... is that what happened?

@jsotola Honestly it's been a while since I wrote that code, so can't be too sure. But I remember being happy to finally see it working and pasting it into a notepad. If I did any changes, it was just to make it flow/look better.

Also, I had tried to edit the tutorial example code to work with just integers and adding up numbers and made this to show what I changed. That also made it stop working and I couldn't figure out why. It's not like I changed anything critical, just the data that it sends.


text:
External Interrupts, Mega2560
I have a question for you guys. I have some code that triggers an ultra-sonic sensor to measure distance. My code uses the EICRB register and executes in interrupt when it sees a transition on the interrupt pin. The interrupt routine is supposed to calculate the time of the echo pulse that comes from the sensor. The width of the pin is proportional to the distance measured.
I'm not sure why I'm not getting great results. There seems to be a persistent error in my measurement and I'm not sure why. It's probably something stupid. Here's a screenshot of the code I have if anyone can lend some help. Thanks for reading.

Please, do not post a screenshot of your code, post the code itself. It's way easier to copy-paste (which is useful for testing).

What do you mean with "persistent error"? Please be more specific

Yea sorry, what I mean is the measurement seems to be off by a fixed amount. Whether the sensor is 10cm or 50cm away from an object, there's some error quantity that is fixed. the shorter the distance, the larger a proportion the error is. Longer distance gives smalled error.

How large of an error?


text:
Regulate Water Pumps flow by DC Stepper Motor Driver
I'm an Arduino beginner. I've got 2 x 12V DC water pumps
https://www.ebay.co.uk/itm/224461221015
plus 12V, 2A AC/DC adapter to feed them.
I would like to regulate the speed (flow) of the pumps programmatically by Arduino. My first idea was to use 2 channel Relay, however, it only supports two states - on/off. Then I discovered this DC Stepper Motor Driver:
https://www.ebay.co.uk/itm/274521887403
That seems to be a good fit in terms of specifications, but I'm not sure whether it will work with the pumps? It makes me think of whether the DC Stepper Motor Driver may work with only specific motors?
Thanks for any advice!

Even though they call that a "stepper motor driver" it's nothing more than a basic H-bridge that can drive any brushed DC motors (two per driver).

I would add that the L298N is a relatively inefficient driver--I might aim for a different driver, like a 6612 etc.

Yes, it will work.
You can control the speed of the water pumps with a PWM signal by using:
analogWrite(PWM_pin, value)

Or you can use a cheap transistor like a P2N2222A; here is a full tutorial.

Unfortunately after trying it does not work as expected. It has been mentioned that it must be a BRUSHED motor and most of these pumps on eBay are Brushless.


text:
Driver configuration not showing the right numbers on the Graphics Test example's serial monitor for Adafruit IlI9341 library
I have a 2.8" Color TFT Touchscreen from Adafruit, and I'm currently trying to set it up. I've been following this guide to set up the screen. The screen powers on when connected to power, but it's not displaying what the example says it should. I can't tell if it's the code of our the hardware that's the issue, but since the hardware setup is pretty straightforward on the site, my guess is it's the code.
The guide says to check the serial console, and that the configuration bytes should be similar. Here's the example's configuration bytes:

Versus what my serial console is displaying

I should note that I am using a Nano every instead of an Uno, but looking up the SPI pins for the Nano Every, I found that they should be the same as for the Uno. But if anyone can confirm that, much appreciated. That could definitely be the problem if I'm wrong.
Finally, I'm including the code that I am currently using below. There are no issues with uploading, and I've triple checked that I have the right libraries downloaded, and am using the correct board and port. I'm thinking the everything before the setup is what might be causing the issue, but I've included the entirety of the setup as well.
  This is our GFX example for the Adafruit ILI9341 Breakout and Shield
  ----> http://www.adafruit.com/products/1651

  Check out the links above for our tutorials and wiring diagrams
  These displays use SPI to communicate, 4 or 5 pins are required to
  interface (RST is optional)
  Adafruit invests time and resources providing this open source code,
  please support Adafruit and open-source hardware by purchasing
  products from Adafruit!

  Written by Limor Fried/Ladyada for Adafruit Industries.
  MIT license, all text above must be included in any redistribution
 ****************************************************/

#include "SPI.h"
#include "Adafruit_GFX.h"
#include "Adafruit_ILI9341.h"

// For the Adafruit shield, these are the default.
#define TFT_DC 9
#define TFT_CS 10
#define TFT_CLK 13
#define TFT_MISO 12
#define TFT_MOSI 11

// Use hardware SPI (on Uno, #13, #12, #11) and the above for CS/DC
// Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);
// If using the breakout, change pins as desired
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_CLK, TFT_MISO, TFT_MOSI);

void setup() {
  Serial.begin(9600);
  Serial.println("ILI9341 Test!");

  tft.begin();

  // read diagnostics (optional but can help debug problems)
  uint8_t x = tft.readcommand8(ILI9341_RDMODE);
  Serial.print("Display Power Mode: 0x"); Serial.println(x, HEX);
  x = tft.readcommand8(ILI9341_RDMADCTL);
  Serial.print("MADCTL Mode: 0x"); Serial.println(x, HEX);
  x = tft.readcommand8(ILI9341_RDPIXFMT);
  Serial.print("Pixel Format: 0x"); Serial.println(x, HEX);
  x = tft.readcommand8(ILI9341_RDIMGFMT);
  Serial.print("Image Format: 0x"); Serial.println(x, HEX);
  x = tft.readcommand8(ILI9341_RDSELFDIAG);
  Serial.print("Self Diagnostic: 0x"); Serial.println(x, HEX);

  Serial.println(F("Benchmark                Time (microseconds)"));
  delay(10);
  Serial.print(F("Screen fill              "));
  Serial.println(testFillScreen());
  delay(500);

  Serial.print(F("Text                     "));
  Serial.println(testText());
  delay(3000);

  Serial.print(F("Lines                    "));
  Serial.println(testLines(ILI9341_CYAN));
  delay(500);

  Serial.print(F("Horiz/Vert Lines         "));
  Serial.println(testFastLines(ILI9341_RED, ILI9341_BLUE));
  delay(500);

  Serial.print(F("Rectangles (outline)     "));
  Serial.println(testRects(ILI9341_GREEN));
  delay(500);

  Serial.print(F("Rectangles (filled)      "));
  Serial.println(testFilledRects(ILI9341_YELLOW, ILI9341_MAGENTA));
  delay(500);

  Serial.print(F("Circles (filled)         "));
  Serial.println(testFilledCircles(10, ILI9341_MAGENTA));

  Serial.print(F("Circles (outline)        "));
  Serial.println(testCircles(10, ILI9341_WHITE));
  delay(500);

  Serial.print(F("Triangles (outline)      "));
  Serial.println(testTriangles());
  delay(500);

  Serial.print(F("Triangles (filled)       "));
  Serial.println(testFilledTriangles());
  delay(500);

  Serial.print(F("Rounded rects (outline)  "));
  Serial.println(testRoundRects());
  delay(500);

  Serial.print(F("Rounded rects (filled)   "));
  Serial.println(testFilledRoundRects());
  delay(500);

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

}```

One difference between Uno and Nano Every is that the SPI on Nano Every could operate at higher SPI data rate. Do you use a level shifter between the display and the Nano Every? Some of the level shifter couldn't handle the higher SPI well. One thing you could try is to change the tft.begin() to tft.begin(3000000);, this set the hardware SPI to 3MHz, and should be able to be handed by the library and whatever level shifter you are using.


text:
Using External Power Supply Arduino Uno
I have an AA battery holder for 9V. Two wires come out of it, one for positive and another for negative. How can I wire it up to my Arduino Uno? It kind of looks like this.

I would suggest a barrel jack, you know, ones on eBay. For instance, those 2.1 x 5.5mm barrel jack connectors. Just solder the positive and negative wires respectively with barrel jack. Here is a link: eBay Barrel Jack
Make sure the red or the positive goes with the red on the Barrel Jack and that the black or negative goes with the black of the Barrel Jack. Like in the image.

(Making sure to match the polarity of the Arduino connector; which IIRC is center-positive.)


text:
Arduino Keypad: the following key does not respond
I was wondering, by the time I press the following key, it does not return to the main_screen() function. How can I fix my code?
void loop()
  {
    int exit = 0;
    char input = customKeypad.getKey();

    main_screen();
     if (input=='A')
        {
          delay(100);
          lcd.clear();

          do{

           lcd.setCursor(1,0);
           lcd.print("Enter minutes: ");

             if (input=='B')
               {
                break;
                lcd.clear();
               }
           }
           while(1);
       }

}

can you also share the complete code?

You need to read the input again after you get input == 'A'.  At the moment, when you enter the do ... while loop, the input is always 'A', so input == 'B' is never true, and the loop never exits.