text:
How to create large progmem arrays and not annoy the linker
I have a rather complex project (PlatformIO, but I've also had this happen in the vanilla IDE) with several nested includes.
Let's say that there are three files and a main sketch.
The main sketch includes #2 and #3.
File #3 includes file #1 and file #2.
If file #2 is a .h file containing something like a font, of the format:
const char foo[] PROGMEM = {0xDE,0xAD,0xBE,0xEF};

Then I get linker errors of multiple definitions of 'foo' in both #3 and main.
Weirdly, the default fonts included in my OLED library are placed in a header file, EXACTLY like how I did it, and yet multiple files including that library (or files that themselves included it) do not cause this issue with the library's header file.
Yes, I do have a working include guard. For some reason it doesn't ever seem to help.
I have been using extern to solve this issue, but it's annoying and I'm not sure that it's proper behavior, either...
Could it have something to do with #include <font.h> vs #include "font.h"? What is the difference? My reference said they mean the same thing, but now I'm not so sure.

the title of your post does not match what your question is about

What is the filename extension of file #3?

They are all .h files except for main. The issue is not really related to main, either--this happens any time #2 is included in multiple files. The other .h files have an associated .cpp file, except for #2.

Include Guards only protect against inclusion of a header file multiple times within the same translation unit.  This is important.  If you include a header file (1) in a source file, then include another header file (2) in the same source file, said header file also including the previous header file (1), then the include guard will perform its function.
If you have two source files and you include the same header in both, then the include guard will do nothing.
If you have a variable or function defined in a header file and you include that header into two different source files, when you link those source files together you will get a multiple definition error, since you have two translation units that have the same thing in them, and the linker doesn't like that.
The only time you should ever define variables or functions in a header file are if they are simple constant types, like a const int or a const char - something where the compiler can replace it verbatim in the code and optimize out the symbol completely (arrays of any kind are not simple), or if the symbol is declared "static", where it will be forced to remain "within" the translation unit and not get exported for linking.
Normally you will only declare your complex constants in the header file, and define them once and once only in a single source file. That way there is only one instance of the symbol in one translation unit.
For example, in the header file you would declare your constant:
extern const char foo[] PROGMEM;

And in your source file define the constant:
#include "foo.h"
const char foo[] PROGMEM = {0xDE,0xAD,0xBE,0xEF};

And in answer to the question "what's the difference between #include <...> and #include "..." - when it comes to Arduino, nothing whatsoever.
Officially it denotes a separation between "system" and "local" headers. That is, headers that are installed in the OS as part of the compiler, and headers that are contained within the project.  However there isn't that distinction with Arduino, and the two mean the same thing - just a header.
And finally a note on terminology - a glossary if you will:

Translation unit - One compilable source file (and any included headers) that forms a single file of object code to be linked.
Declaration (Declare) - The indicating of a symbol's type and any attributes, but not the content of that symbol
Definition (Define) - Associating a symbol, whilst declaring it, with the content of that symbol.
Symbol - the name of any variable, function, class, etc.

Okay, so extern IS the right way to do this. Any idea how the OLED library gets away with doing this, though? It defines AND declares that array in its own .h file and causes no errors. And that library gets included in one I use in multiple places (though it itself is only included once...?) so I think that should cause the error...

Can you point to this OLED library? There's no way I can predict what it's doing without being able to see it.

https://github.com/ThingPulse/esp8266-oled-ssd1306/blob/master/src/OLEDDisplayFonts.h
However it works, that file is included by the SSD1306Wire header, which is included by the SSD1306 header I use.

Maybe different versions of the compiler do things in different ways. I know that recently deduplication of static data (like these big arrays) was added, and that the ESP8266's compiler is new enough for that - maybe that has removed the need for it to complain about it being there more than once, since now it can know that they are all the same data anyway.

Strange that it wouldn't do...whatever it was...for mine, though. I'm still learning the intricacies of how files, headers, and placement of things in them affects where they show up, and then this happens, where at least part of the answer seems to be "because it wants to"... :D


text:
This code gives the wrong output. Why?
void setup()
{
  int calc(9,2);
  Serial.begin(9600);
}

void loop()
{}

int calc(int val1, int val2)
{
  Serial.print(val1 + val2);
}

It's not syntax error, i am getting output as 1, i should get 11.

what is int calc(9,2);? you print before Serial.begin()

There are two serious warnings, indicating that the compiler obviously does not understand your intentions. ( Neither do I :) )

A function's name should tell what it does.
Something called calc() should not mainly print (except for debug purposes))
void setup() {
  Serial.begin(9600);
  printSum(9,2);
}
void loop() {}

void printSum(int val1, int val2) {
  Serial.print(val1 + val2);
}

The other good approach is to really define a function returning a result.
int calc(int a, int b) {
   return a+b;
}
void setup() {
   Serial.begin(9600);
   Serial.println(calc(9,2));
}
void loop() {}

If your goal is to call your function with int calc(9,2);, you might want to change it to calc(9,2);, this is the way to call functions, no type declarator needed if you arent creating said function (or in a declaration, wich has nothing to do in the setup)
If you want to declare your functions, it must be done at the very top of your code, out of the setup function, and with arduino 1.8.9 on my end, this is not mandatory.
Also, you are calling your printing function before the Serial.begin(), one good practice may be to Serial.begin() at the very top of your setup, so you don't make mistakes on why your debug is not showing.
As on why you have a 1 printed, if that's all your code, i don't really know, i have no output when i try your code on my end
tl;dr;
void setup() {
  Serial.begin(9600);
  calc(9,2);
}

source: Stack Exchange

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

sort: votes


text:
How is this code working?? val3 is defined as constant
const int val3 = 7;
void setup(){
  Serial.begin(9600);
  int val3 = 8;
  int val4 = 4;
  Serial.print(calc(val3,val4));
}

void loop()
{}

int calc(int val1, int val2)
{
  return val1 + val2;
}

this code gives output as 12.

print val3 in loop()

I did not get you, can you explain again.

you use the second int val3 defined in setup(). it shadows the global val3

@Akash, add a Serial.print() statement into the loop() block ... print out the value of val3 ... what prints in the serial monitor?

In your code, the const int val3 = 7; definition, is outside of any functions so it defines a global constant/variable (available in every part of your code).
The int val3 = 8; definition is inside your setup () function, so it acts as a local variable only within that function. This overrides the val3 constant defined outside of the setup () function. I.e. the global val3 constant and the local val3 variable inside of setup () are not the same variable, which will inevitably lead to confusion (as in your case).
It’s valid syntax but I don’t consider it good coding practice. It’s good to know why it works that way though.

Thanx, i got it.

You have declared val3 two times: One time as constant int and another time as int (in setup loop). Replace the statement int val3=8 by val3 = 8. You will know the difference.
The first declaration is of no use in this case. As a try, you may first declare val3 as int and in the second declaration you may declare val3 as const int.
Just try and note the difference. Happy coding!

Thanx, i got it.

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


text:
How can I declare custom pins when using with ESP8266 in MPU9250 library
I want to declare SCL and SCK pins like   Wire.begin(sda_pin, scl_pin); to use with ESP8266 to integrate a MPU 9250/6500 sensor.
I can't figure out a way to declare that in this code exaample provided by https://github.com/bolderflight/MPU9250
in the example of the above it has just passed as Wire to and created object like MPU9250 IMU(Wire,0x68); which was meant to be used with UNO boards(as I think)
And in any case if any of you have seen a library that can be used with the ESP8266 for the MPU 9250/6500 point me on that direction please (I'm trying to get the roll, pitch, yaw)

You can use Wire.pins(sda, scl); before IMU.begin();.
IMU.begin() then calls Wire.begin() without parameters.


text:
MIDI Keyboard control
I am relatively new to Arduino and I am looking to implement a simple system that uses a MIDI keyboard to
(i) detect key presses (via MIDI messages) from the keyboard
(ii) store the information of the MIDI messages (note pressed, velocity)
(iii) Light up LEDS on the keyboard based on what key was pressed
I am currently in the planning stage and I am considering using an Arduino Mega. I have two issues I am not sure about:
(i) My keyboard only has a Male USB A to Male USB B connection with the former connecting to the computer and the latter to the keyboard. So far in my search, I have seen that all Arduino-MIDI projects require a 5 pin MIDI cable to interface with the Arduino using the circuit in this webpage (https://www.instructables.com/id/Send-and-Receive-MIDI-with-Arduino/). Is there any way to detect MIDI messages that does not require the additional circuit and just uses the USB cable?
(ii) Although in theory control of the LEDs should be easy in the program, I am concerned that the delays in the serial communication and hardware interrupts would make it difficult to simultaneously receive the MIDI messages and control the LEDs.
One way I thought of avoiding these problems is to use MATLAB MIDI package (https://uk.mathworks.com/help/audio/ug/midi-device-interface.html#mw_80dc54f4-867c-43c0-a159-e56ee62ec4ab) to interface with the MIDI device and use the MATLAB Arduino package to control the Arduino. I am not sure, however, if MATLAB is suboptimal compared to the standard Arduino IDE.
This is my first question in Arduino StackExchange (or any StackExchange site), so I appreciate the answers and feedback on my question.

Is there any way to detect MIDI messages that does not require the additional circuit and just uses the USB cable?

You could probably do it with a "USB Host Shield", though I have no experience of them and don't know if they can handle MIDI - you'll have to research this.

Although in theory control of the LEDs should be easy in the program, I am concerned that the delays in the serial communication and hardware interrupts would make it difficult to simultaneously receive the MIDI messages and control the LEDs.

Highly unlikely. You'd have to be doing something very wrong to make it so slow to respond that you'd see any delay.

I am not sure, however, if MATLAB is suboptimal compared to the standard Arduino IDE.

I cannot comment, I have never used MATLAB. If you don't use a USB Host Shield then you will certainly require something that runs on a PC to forward the MIDI information over serial.  Whether you create that in MATLAB or some other programming language is neither here nor there as far as the Arduino is concerned - you'll still need to program the Arduino itself, and that can be done in the IDE and still use MATLAB for the PC portion of your setup.

I don't have experience with USB MIDI, but I'm (almost) sure it should work with a shield (as Majenko already writes).
I have experience with the following library. I used it for normal (DIN5) MIDI, not via USB, but it seems to support USB too: https://github.com/FortySevenEffects/arduino_midi_library
This library is interrupt based, try to keep the interrupts as short as possible, you can do the processing of the MIDI messages in the main function, together with driving the LEDs.
I created a (temporary) USB merger which worked quite well, so yes, with a Mega it's easy to use 3 (or 4) MIDI channels, using DIN5. It's more than fast enough. MIDI is just 31.250 baud.
I found it was very annoying to use the only UART of an Arduino Uno to use for both MIDI and debugging/uploading, so it's easier to use 3 UARTs from the Mega, and when your program works, use the main RX/TX for MIDI too (make it flexible).
In case you think about use the software serial: forget about it, at least for reading MIDI.


text:
Detecting the stop of execution of a timer interrupt
This is my timer interrupt:
void setup() {
  attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), count_time_of_k_pulses, RISING);

  pinMode(OE_BAR_PIN, OUTPUT);
  pinMode(S0_PIN, OUTPUT);
  pinMode(S1_PIN, OUTPUT);
  pinMode(S2_PIN, OUTPUT);

  TIMER1_init();

  Serial.begin(BAUD_RATE);
  while (! Serial);
}

void count_time_of_k_pulses()
{
  if (interrupts_enabled)
  {
    pulse_counter++;

    if (pulse_counter == 1)
      TIMER1_start();

    if (pulse_counter == number_of_samples)
    {
      TIMER1_stop();

      measurement_finished = true;
      interrupts_enabled = false;
    }
  }
}

The logic behind this is that it will receive signals from a digital circuit on an arduino pin.
When it receives the first signal it will start a timer.
After it receives as many signals, as set by number_of_samples, it will stop.
This information will help my identify the resitance of a resistor.
There is a problem though.
Imagine that while the timer interrupt runs (signals are coming and the timer is running), i remove one pin from the resistor and the signal stops arriving at the arduino pin.
Then the program will lock, because it will be stuck inside the timer interrupt, constantly waiting for  if (pulse_counter == number_of_samples) to be satisfied.
So is there a way, while inside the timer interrupt, to detect when the timer interrupt is stuck, without using more timers?
EDIT: BELOW IS THE WHOLE CODE
/***** CONSTANTS *****/
const int BAUD_RATE = 9600;
const int INTERRUPT_PIN = 3;
const int S0_PIN = 4;
const int S1_PIN = 5;
const int S2_PIN = 6;
const int OE_BAR_PIN = 22;
const int NUM_OF_SENSORS = 8;

/***** ANALOG CIRCUIT CONSTANTS *****/
const double CAPACITOR_VALUE = 400; //pF
const double GAIN_VALUE = 3.5222672065;
const double R_BIAS_VALUE = 98.7; //kΩ

/***** GLOBAL VARIABLES *****/
int number_of_samples = 500;
int sensor_coord;
boolean full_mode = false;

unsigned long overflows = 0;
unsigned long ticks = 0;
double period = 0;

//variables for determining if a resistance cannot be measured
unsigned long timestamp = 0;
unsigned long measurement_timeout = 5000;  //5 seconds is the timeout time
boolean sensor_corruption[8]; //each element of the array is the sensor info. If false, resistance is working. If it's true, resistance is open.
boolean ISR_unavailable = false; //this flag is raised, when the ISR does not run, because no signal comes from the circuit, because resistance is open circuit

//variables that get changed inside the ISR
volatile int pulse_counter = 0;
volatile boolean interrupts_enabled = false;
volatile boolean measurement_finished = false;

void setup()
{
  attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), count_time_of_k_pulses, RISING);

  digitalWrite(OE_BAR_PIN, HIGH);
  pinMode(OE_BAR_PIN, OUTPUT);
  pinMode(S0_PIN, OUTPUT);
  pinMode(S1_PIN, OUTPUT);
  pinMode(S2_PIN, OUTPUT);

  TIMER1_init();

  Serial.begin(BAUD_RATE);
  while (! Serial);

  for (int i=0; i<=7; i++)
  {
    sensor_corruption[i] = false; // false means it's working ok. true means it's open-circuit (or cannot be read anyway)
  }
}

void loop()
{

  //CODE FOR SERIAL INTERFACE (RESISTANCE SELECTION)
  if (Serial.available())
  {
    /***** DEFINE MEASUREMENT MODE *****/
    String input = Serial.readString();
    if (input[0] == 'r' && interrupts_enabled == false)
    {
      if (input[1] == 'f')
      {
        full_mode = true;
        sensor_coord = 0;
      } else
        sensor_coord = input[2] - '0';  // r *SPACE* [0-7]

      select_sensor();

      pulse_counter = 0;
      TIMER1_clear();

      interrupts_enabled = true;
    }
  }

  //no_interrupts area-------
  // TIMEOUT CODE HERE. TO DETERMINE IF A RESISTANCE IS OPEN CIRCUITED
  if(interrupts_enabled && millis() - timestamp > measurement_timeout)
  {
    sensor_corruption[sensor_coord] = true; //label the resistance (indicated by sensor_coord) as true in the boolean array. this means it's open circuited (no signal from circuit)
    measurement_finished = true; ///we set this to true, so we can enter the next block of code
    ISR_unavailable = true; //small flag in order to not do calculations (some lines below) in case of an open circuit
  }
  //-------------------------

  if (measurement_finished)
  {

    if (!ISR_unavailable) //only make these calcs, if the ISR_unavailable is false. in other words if the ISR runs (so resistance is read)
    {
        ticks = (overflows * 65536) + TCNT1;
        period = (ticks * 0.0625) / (number_of_samples - 1);
    }

      TIMER1_print_results();
      ISR_unavailable = false;
      if (full_mode)
      {
        sensor_coord++;
        select_sensor();
        pulse_counter = 0;
        TIMER1_clear();
        interrupts_enabled = true;

        if (sensor_coord == NUM_OF_SENSORS)
        {
          full_mode = false;
          interrupts_enabled = false;

        }

        measurement_finished = false;
        timestamp = millis();

      }

       pulse_counter = 0;
       TIMER1_clear();
       interrupts_enabled = true; //NEW
       measurement_finished = false; // delete this bs
       timestamp = millis();

  }
 }

/***** INTERRUPT ROUTINES *****/

void count_time_of_k_pulses()
{
  if (interrupts_enabled)
  {
    pulse_counter++;

    if (pulse_counter == 1)
      TIMER1_start();

    if (pulse_counter == number_of_samples)
    {
      TIMER1_stop();

      measurement_finished = true;
      interrupts_enabled = false;
    }
  }
}

ISR (TIMER1_OVF_vect)
{
  overflows++;
}

/***** FUNCTION FOR SENSOR SELECTION *****/

void select_sensor()
{
  digitalWrite(OE_BAR_PIN, HIGH);
  digitalWrite(S2_PIN, ((sensor_coord & 4) == 4) ? HIGH : LOW );
  digitalWrite(S1_PIN, ((sensor_coord & 2) == 2) ? HIGH : LOW );
  digitalWrite(S0_PIN, ((sensor_coord & 1) == 1) ? HIGH : LOW );
  digitalWrite(OE_BAR_PIN, LOW);
}

/***** TIMER1 FUNCTIONS *****/

void TIMER1_init()
{
  TCCR1A  = 0;
  TCCR1B  = 0;
  TIMSK1 |= (1 << TOIE1);
}

void TIMER1_start()
{
   TCCR1B |= (0 << CS12) | (0 << CS11) | (1 << CS10);
}

void TIMER1_stop()
{
  TCCR1B  = 0;
}

void TIMER1_clear()
{
  TCNT1     = 0;
  overflows = 0;
}

void TIMER1_print_results()
{
  Serial.println("----------------------------------------");
  Serial.print("SENSOR COORDINATE         = ");
  Serial.println(sensor_coord);

  if (sensor_corruption[sensor_coord])
  {
    Serial.println("This resistance is open circuited!!!");
  }
  else
  {
    Serial.print("NUMBER OF PULSES MEASURED = ");
    Serial.println(pulse_counter);

    Serial.print("TIMER1 VALUE              = ");
    Serial.println(TCNT1);

    Serial.print("TIMER1 OVERFLOWS          = ");
    Serial.println(overflows);

    Serial.print("TICKS                     = ");
    Serial.println(ticks);

    Serial.print("MEASURED PERIOD           = ");
    Serial.print(period);
    Serial.println(" US");

    Serial.print("MEASURED RESISTANCE       = ");
    double resistanse = ((period * GAIN_VALUE * 1000) / (4 * CAPACITOR_VALUE)) - R_BIAS_VALUE; //kΩ
    Serial.print(resistanse);
    Serial.println(" kΩ");

    Serial.println("----------------------------------------");
  }
}

Is that your ISR? Then where should it get stuck? I don't see any while loops or similar. Also: What interrupts are you using here? I would assume that this ISR is used with an external interrupt pin. It starts a timer to measure the time of a pulse. Please provide a full working code. We need to see the whole code situation.

One moment, you already asked a question about that code some time ago: here. The problem seems quite similar, so I immediately thought about the same solution principle using millis(). Or do you need to use Timer0 somewhere else in your new code revision, so that you cannot use millis()?

Please, note that count_time_of_k_pulses() is not a timer interrupt. It's the handler of an external interrupt.

I updated the code. Yes, the code is the same from that thread. Although the problem is different. In that problem (which i solved thatnks to you guys) i wanted to detect when the timer interrupt does not run, because it does not get triggered. In this new problem, i am inside the interrupt, but for some reason the signal stops arriving, while inside (before i reach the number_of_samples). So the program is stuck inside the iterrupt, waiting for the signal to get equal the number_of_samples.

It won't be stuck inside any interrupt.  It will fire the interrupt and exit and then if the signal is gone it won't fire the interrupt again.  So the easiest method may be to just keep track in loop of how long it has been since the last interrupt.  If it has been a long time then the signal must be lost.  You just need one more unsigned long in the ISR to keep track of the millis time of the last interrupt.

I updated the post with the whole code. If you see in the comments labeled as "no interrupts area", is where i do calculations (as advised from my other post) in order to figure out when a timer interrupt does not run, thus there is no signal in the input pins, thus reistance is open circuited. But now when i do a continuous measurement of a working resistance and THEN i open circuit it, the program stops. This is why i assumed it stops inside the interrupt function. Could you modify the code with your one liner, to see your approach better please?

@Delta_G I don't think this is the case "if the signal is gone it won't fire the interrupt again", because if you see my whole code which i posted, i already do that (check the comments for 'no interrupts area'). If there is no signal then that resistance gets labeled and the appropriate print is shown. But when i measure continuously a resistance and then i open circuit it, nothing happens. The program stucks. If no signal arrived, then the 'no interrupts area' code should run again. But in my case, it doesn't happen.

Then you have a basic misunderstanding of how interrupts work.  The code can never ever become trapped in that interrupt.  Think about this, your timeout code in the no interrupts section, where does timestamp get a value?  That should tell you when the last interrupt fired, so it seems to me like it should get a value in the ISR.

So what seems to be the problem here?

I don't know.  Instead of giving us the symptoms of the problem you told us why you thought it was failing.  But your reasoning is not right.  The ISR will only be entered when there is a rising edge on the pin and then it runs very fast and exits.  It can never be hung up in the ISR.  Perhaps you should describe what the actual problem is.  To me it looks like you just need to take a time stamp from millis in the ISR and in your loop you can compare that to see how long it has been since the interrupt fired.  If it has been a long time then you have lost the signal and can act appropriately.

Mhh, I cannot see the code portion, where the code gets stuck. I agree with @Delta_G that it cannot get stuck in the ISR, since there are only if statements, which cannot block the code executing. You can test this by turning on an extra LED at the start of the ISR and turning it off at the end (with direct port manipulation to be fast enough). Please also add a simple blink code from the BlinkWithoutDelay example to the loop() function. That way we could prove, if the loop still runs

You can use the described LED principle to track down the problematic code part, if the code really gets stuck somewhere

I get the LED inside the ISR, but the BlinkWithoutDelay ses these lines:  if (currentMillis - previousMillis >= interval) {}. I have somethign similar in my code, so how do i combine those? Do i need new variables to store the currentMillis? If i use what i have, then the LED will only light up inside the 'No interrupts area' (as labeled in my comments inside the code).


text:
Function pointers that call one function
I'm reading a library file timer.h for STM core library that I just installed in Arduino hardware folder.
Of course, there has to be a lot of questions for me as a beginner about many approaches/stratgegies that programmers rule in writing the code.
One thing is that calling a function with a function pointer that only call one function, but the difference is that the function pointer is declared/defined as an inline function.

Edit: I deleted the code and posted a link for it in github.
stm32/timer header file
OK, the part that I started to think about starts from line 595.
It's functions declarations.
In line 598, it's a declaration for a function that receiver a pointer to a function.
In later lines, starting from line 634, these functions have only one line to execute. So my question is why to develop a function to only execute one line ?
Why they didn't just put that line directly instead of putting it inside function ?

Could you please post a link to the complete file?

Where exactly is the function pointer here, that is called? bb_perip is not a function pointer, I think, but a function, that returns a pointer to a variable. Though I cannot be sure from this snippet of code alone

...\Program_Files\Arduino\hardware\Arduino_STM32-master\STM32F1\system\libmaple\include\libmaple for example depending on the root file location on my computer.

I posted like most the inline functions. Couldn't post the complete code that is far more that the character limitations over 30000 character.

Again I don't see a function pointer being used here. Please point us, where exactly you are seeing the problem. Also can you please give a link to your used STM32 core, so that we can read this file on the web. I personally don't have a STM32-core installed, also we don't know, which core you used. Best case would be a github link to the file in question.

OK, I added the information in the main post. It's much easier for me, but I don't know which is better to add the required information here or edit the main post ?

@R1S8K - Please edit the question and add new information to it.

bb_perip is a function that returns a pointer to a bit from a register that is related to a specific timer peripheral (there's more than one).  That pointer is then dereferenced with the * operator to make *bb_perip(...).
What bb_perip returns is dependent on what timer you are using and what value you are interested in.
bb_perip is not a pointer to a function, it is a normal function that happens to return a pointer.

Something new to me is that there is an integer passed to this function ! It's my first time to encounter this feature. *bb_perip(&(dev->regs).bas->CR1, TIMER_CR1_CEN_BIT) = 0; there is a 0 passed to this function, how this is done ?

No, the integer is not being passed to the function. The integer is being assigned to the dereferenced pointer returned from the function.

oooh I'm sorry my mistake I wanted to say "assigned" not "passed" :) totally different approaches. Yeah, I meant it's a new feature to me to assign anything to a function.

Or because it's a function pointer, where the pointer is a variable basically, so I can assign a value for it. is that correct ?

You are not assigning anything to the function.  The function returns a pointer to somewhere in memory. You take that pointer, then use it to place a value into memory at that address.  Once the function has returned the pointer it has no further role to play.  You can just as well use (in pseudocode) *func() = 4 as you can pointer = func(); *pointer = 4; - all you're doing is leaving out the middleman.

Oh yeah I understand now they put 0 because the function role is to pause the timer. static inline void timer_pause(timer_dev *dev) {     *bb_perip(&(dev->regs).bas->CR1, TIMER_CR1_CEN_BIT) = 0; }


text:
Displaying multiple effects in Fast LED
I want to implement three effects which display every 5 seconds. I know that using delay() is not a good method so I want to use milis(). Duration times of the effects are different from each other. How can I assure "non-freezing" or displaying 2 or 3 effects at the same time? Should I measure the time of display of every effect and on its base adjust intervals or is there another solution? What do you think?
EDIT:
Here is my code:
void loop() {
   unsigned long currentMillis = millis();

   if(currentMillis - previousMillis >= interval) {
     previousMillis = currentMillis;
     i++;

    switch (i){
      case 1:
        meteorRain(0xff,0xff,0xff,10, 64, true, 30); // efekt spadającej gwiazdy
        Serial.print("meteorrain: ");
        Serial.print(previousMillis);
        Serial.print("\n");
        break;

      case 2:
         colorWipe(0x90,0x90,0x90, 50);
         colorWipe(0x00,0x00,0x00, 50);
         Serial.print("colorwipe: ");
        Serial.print(previousMillis);
        Serial.print("\n");
         break;

      case 3:
         MyEffect();
         Serial.print("My effect: ");
        Serial.print(previousMillis);
        Serial.print("\n");
         break;
    }
    if (i>3) i=0;
    }
}

I've ommited the code of effects (it doesn't matter, I think).

show us what you have tried so far, do you have some code working for one of the effect (or the 3 of them ?) so we can know what to expect ? also, if your 3 effects all trigger every 5 seconds, can't we call that one big effect with 3 different actions that triggers every 5 seconds ?

Are these effects executed on different LED strips at the same time or sequentially on the same LED strip?

Sequentially on the same LED strip.

So you don't want to have multiple effects at the same time, as you wrote in your question? Or do you divide the LED strip into different parts, which should display the corresponding effect simultaneously? I don't understand, what the end result should look like

If you intend to show every effect sequentially for a time interval (by looking on the code one can assume that) then, there is nothing wrong with the code, except the execution of an effect would last longer than the time interval. If that's not your intention, I do not understand your question for the same reasons @chrisl has mentioned.

I'd take a look at Mark Kriegsmans FastLED example "DemoReel100". This example shows how to delegate to multiple functions.
First, I'll explain that example a bit: You set up an array of function pointers plus a variable for the current index.
typedef void (*SimplePatternList[])();
SimplePatternList gPatterns = { rainbow, rainbowWithGlitter, confetti, sinelon, juggle, bpm };
uint8_t gCurrentPatternNumber = 0;

All the functions (rainbow, juggle, etc) just need to work on your leds[] array that you gave to FastLED.addLeds() in your setup() -- I assume that your functions already fulfill that requirement. But: All functions must have the same argument list (in this case: they must be defined like void rainbow() { leds[x] = CHSV(a,b,c); }), so you might need to wrap them in another function.
Then, in your loop, you call your effect functions like this while calling nextPattern() every 10 seconds:
void loop()
{
  // Call the current pattern function once, updating the 'leds' array
  gPatterns[gCurrentPatternNumber]();

  // send the 'leds' array out to the actual LED strip
  FastLED.show();
  // insert a delay to keep the framerate modest
  FastLED.delay(1000/FRAMES_PER_SECOND);

  // do some periodic updates
  EVERY_N_SECONDS( 10 ) { nextPattern(); } // change patterns periodically
}

#define ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0]))
void nextPattern()
{
  gCurrentPatternNumber = (gCurrentPatternNumber + 1) % ARRAY_SIZE( gPatterns);
}

EVERY_N_SECONDS is a macro defined in the FastLED library; it basically does what you did with currentMillis, previousMillis and interval (There's also EVERY_N_MILLISECONDS and some other related macros).
That's the example so far, now we need to work with differing "effect switch times".
The easiest method in code would be to find the greatest common factor of all switch times -- let's say you want the rainbow() effect to last for 10 seconds, the juggle() effect for 15 and the bpm() effect for 5 seconds. All those switch times are a multiple of 5, so we put that as the switch delay: EVERY_N_SECONDS(5). Now, to get higher runtimes, we just put those functions multiple times into the array:
SimplePatternList gPatterns = { rainbow, rainbow, juggle, juggle, juggle, bpm };

There's another way, which gives you the option of setting the effect durations directly. First, we need an array of durations of the same length than our effect function array and a variable to remember where we are in the durations:
SimplePatternList gPatterns = { rainbow, juggle, bpm };
int[] gPatternDurations = { 10, 13, 73 };
int effectDurationLeft = gPatternDurations[0];

Then, we reduce the "effect switch resolution" down to 1 second and put a bit of logic around the nextPattern() call:
  EVERY_N_SECONDS( 1 ) {
    if( effectDurationLeft == 0 ) {
      nextPattern();
      effectDurationLeft = gPatternDurations[gCurrentPatternNumber];
    } else {
      effectDurationLeft -= 1;
    }
  }

Now you could set your pattern durations by editing the gPatternDurations array.
Please be aware that I did not test the code above. Syntax Errors may occur :)


text:
Where to find the attribution name for a certain board?
I'm working on lcd128x64 spi library. And was working with my Arduino Atmega328p chip.
Now I want to run the code with my maple mini board too.
So I have to specify the name on the pins for each chip board.
But I want to learn the basics of how to write these statements.
Could you tell me where to find the attributions for each board ?
For now I want to define the pin names for the Atmega328p and maple mini. This is my intention:
#if defined(__AVR_ATmega328P__)
    #define CS_PIN                  10
    #define MOSI_PIN                11
    #define CLK_PIN                 13
#elif defined(STM32_SERIES_F1)
    #define CS_PIN                  PB12
    #define MOSI_PIN                PB15
    #define CLK_PIN                 PB13
#endif

I don't think that's %100 correct, but I'm pretty sure that it's not the correct names of boards.

The whole point of the Arduino API is that you don't need to know the names of pins. You just need the numbers that the API assigns to them.

the SPI libraries know the pin numbers. you don't need to spceify them in normal case. the pins 11, 12, 13. are valid for Uno and Nano, not for ATmega328p.

Yeah I know but in my lcd128x64 library, I'm using both atmega328p and stm32 which is using other pins names and also it has two spi modules. Like, in this init function void lcd128x64_init(void){  pinMode(CS_PIN, OUTPUT);  pinMode(CLK_PIN, OUTPUT);  pinMode(MOSI_PIN, OUTPUT);  digitalWrite(CS_PIN, LOW);       // disable CS_PIN  SPI.begin();  _delay_ms(100);          // initial delay  digitalWrite(CS_PIN, HIGH);       // enable CS_PIN ... } the pins names are different, so I want to unify them in the header file.

Also spi2 initialization for stm32 is different SPI_2.begin(); //Initialize the SPI_2 port.   SPI_2.setBitOrder(MSBFIRST); // Set the SPI_2 bit order   SPI_2.setDataMode(SPI_MODE0); //Set the  SPI_2 data mode 0   SPI_2.setClockDivider(SPI_CLOCK_DIV16);  // Use a different speed to SPI 1   pinMode(SPI2_NSS_PIN, OUTPUT); so I have put that in my lcd128x64 lib

When I try to compile the code for the maple mini I get this:
`Arduino: 1.8.12 (Windows 10), Board: "Maple Mini, Original (17k RAM,108k Flash), 72MHz (Normal), Smallest (default)"
H:\Programming\Program_Files\Arduino\libraries\lcd128x64_spi\lcd128x64_spi.cpp:14:20: fatal error: avr/io.h: No such file or directory
#include <avr/io.h>
                ^

compilation terminated.
exit status 1
Error compiling for board Maple Mini.
This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.`

The Arduino defines to identify a board are in form of ARDUINO_<board>, where <board> is the value from <x>.build.board from boards.txt for board <x>
For example for Arduino AVR boards, in the boards.txt file is uno.build.board=AVR_UNO so the define is ARDUINO_AVR_UNO.
And Arduino has 'architecture' identification define too. This has form of ARDUINO_ARCH_<arch.name>. The <arch.name> is the uppercase version of the folder name with the boards package version. For example AVR for packages/arduino/hardware/avr/1.6.21.

But I want the specific attribution that are like in this link. @https://www.microchip.com/webdoc/avrlibcreferencemanual/using_tools_1using_avr_gcc_mach_opt.html@ I want the same for the STM32 I couldn't find its attribution.

@R1S8K, use arduino board or architecture identification, not the chip identification.

OK but I get now fatal error that including the avr/io .. `Arduino: 1.8.12 (Windows 10), Board: "Maple Mini, Original (17k RAM,108k Flash), 72MHz (Normal), Smallest (default)"
H:\Programming\Program_Files\Arduino\libraries\lcd128x64_spi\lcd128x64_spi.cpp:14:20: fatal error: avr/io.h: No such file or directory
#include <avr/io.h>
                ^

compilation terminated.
exit status 1
Error compiling for board Maple Mini.
This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.` What to do now ?

@R1S8K, ask a new question

OK I'm trying to solve it before asking a new question.

How to use the board identification ?

@R1S8K, instead of __AVR_ATmega328P__ use ARDUINO_AVR_UNO for pin mapping defines

ok thanks I didn't care for the Arduino as it's already defined but I was searching for the stm32 attribution. I think I found it and it's basically working.

If you are working on Maple Mini, you may look in this folder, you will found the pin mapping between STM32 and Arduino nomenclature.

Yep, you're right. I didn't notice the rest of the name ! I thought they are just STM chips but I found the maple mini folder there, but also couldn't find the right attribution.

I don't get what you are looking for: is not enough this
{&gpiob,   NULL, NULL, 11, 0, ADCx}, /* D0/PB11 */ ?

Maybe the official repo is cleaner: look at this file

@fabuiz7 thank you so much for your help. I'm actually found part of the solution which is just to use what I put in the main post which is STM32_SERIES_F1 it worked, but I'm getting other errors that I'm trying now to solve them.

try this define, for me it worked ;) ARDUINO_MAPLEMINI_F103CB

Nope it got me this error list: `error: 'CS_PIN' was not declared in this scope
pinMode(CS_PIN, OUTPUT);
error: 'CLK_PIN' was not declared in this scope
pinMode(CLK_PIN, OUTPUT);
error: 'MOSI_PIN' was not declared in this scope
pinMode(MOSI_PIN, OUTPUT);
error: 'delay_ms' was not declared in this scope
delay_ms(100);          // trying initial delay`

Which Arduino Core are you using? I had installed this one

How to post a link ? Sorry I don't know how.

Let us continue this discussion in chat.


text:
How can I make my Arduino Esplora program start on the press of a button and then continue to run without me having to hold the button down?
I am trying to create a program where the main code starts on the press of a button.
I am using an Arduino Esplora, and I want to have the built-in LED be blue when I plug in the power until I press Switch 1 (or any of them), upon which the program starts.
I have had no problem in making the main part of my program, but I would like to find a way to have my program by just pressing the button once, as currently it only works while I am holding the button down continuously - something that is not possible in the situation I am using it for. I can't use any components apart from the Esplora itself, which rules out the option of using switches, etc. which probably would have made my life easier .
I would appreciate any suggestions. I'm pretty new to Arduino, so I'm sorry if I ask any dumb questions, or don't understand some of the concepts you are talking about, but I'll try my best. Thank you!

please show us your code

You could simulate the switch with the button by using a state variable that hold the state of the "switch". I don't know your code, so I can only give you an example on how to do that:
// the includes are here, if you need any

int flagActive = -1;

// ...

setup()
{
   // ... set the internal LED to blue
}

loop()
{
   if ( < switch pressed > )
   {
     flagActive = 1;
   }

   if ( flagActive > 0 )
   {
     // .... your program
   }
}

You could also toggle the flag if you intend to deactivate you program by pressing the button again.
   if ( < switch pressed > )
   {
     flagActive = flagActive * -1;
   }


text:
Arduino Won't Work With Sensors - Pulsates 1/HIGH when not plugged in, constant HIGH/1 when plugged in

simulate this circuit – Schematic created using CircuitLab
I tried to do a simple project where a 8x8 matrix lamp would display something different depending on whether or not a sensor outputted high/low.
There was no trouble getting the matrix lamp to work, as I wanted, but the sensor kept outputting 1, regardless if it was plugged in or not.
This is the code I used, but when I plugged in the sensor it would display 1/high continuously, and when I removed all wires from the sensor, the lamp would light occasionally and the monitor would display 1 as the movStat value.
The LED lamp is connected directly to the breadboard via. digital pin 4.
I am considering buying a new Arduino, but I would like to get a second hand opinion before I spend money on it.
I am using a PIR sensor model HC SR501:

int movSens = 3;
int ledPin = 4;
int movStat = 0;

void setup() {
    // put your setup code here, to run once:
    Serial.begin(9600);
    //Sensor Setup
    pinMode(movSens, INPUT);
    //LED Setup
    pinMode(ledPin, OUTPUT);
}

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

    Serial.println(movSens);

    movStat = digitalRead(movSens);

    if (movStat == HIGH) { //If motion is detected, activate LED
        digitalWrite(ledPin, HIGH);
    }
    else {
        digitalWrite(ledPin, LOW);
    }

    Serial.println(movStat);
}

Please show your schematic and code if you want any help.

Alternatively request that your existing SO question be migrated to here.

@Majenko I have added the original question now :)

Do you have a resistor with your LED?

@Majenko yes, but the LED isn't the problem.
The problem is, that the Arduino randomly outputs a value such that movSens becomes 1/HIGH, activating the LED, even though there is absolutely no sensor or anything connected to the Arduino.
And if I connect the sensor, even with 15 seconds of calibration, it will just remain on HIGH/1. This also happened with another sensor I had.

With no sensor you can expect a random value - you have a floating input. That tells you the Arduino is fine. It sounds more like the sensor is bad or not wired correctly.

@Majenko THat is good to hear. But, the sensor will still activate, and then remain at 1.
This has nothing to do with my code, but has something to do with the sensor itself? It is wired such, that looking at the pins, the right hand pin is wired to 5V, middle output and left GND, i.e according to the schmeatics.

Sounds likely. Can you show your actual wiring (photograph will do)?

@Majenko I have added schematics.

the documentation states that the output is 3.3 V when motion is detected and 0 V otherwise .... if you are using a 5 V arduino, then use the analog input for the sensor

@jsotola, Mega will read 3.3 V as HIGH

@jsotola Tried using A1, nothing changed.

use a voltmeter to verify the output of the sensor

Could it have something to do with the trigger or not trigger jumper setting.


text:
Serial.print array displays nothing
I tried Serial.print an array I had made, but the Arduino displays nothing in the monitor.
I tried doing Serial.print("Hehehe"); as a test, but it just displayed "h?h?h?".
The monitor works fine with other sketches than this one.
Anyone knows why?
int my_array[10];

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

  for (int i = 0; i < 10; i++){
    my_array[i] = i * 5;

  }
}

void loop() {
  // put your main code here, to run repeatedly:
    for (int i = 0; i < 10; i++){
      Serial.print(my_array[i]);
      Serial.print(" ");
    }
    Serial.println();
    delay(1000);
}

do you have 9600 baud set in Serial Monitor?

@Juraj I have set it to 9600.

In setup() you write to undefined memory my_array[10]. It's undefined if that hurts or not.

@DataFiddler I don't quite understand.
The sequence is filled in the function that takes i + 5.

i < 11 it should be 10

Test on my Arduino Uno, your code works fine with a simple copy-paste. Remember to set the proper baud rate.

Must be something faulty with my own Arduino then. Thank you for the answer though :)

Load a blink sketch and check if the blink speed is correct. (Should have accuracy of at least 1/1000).


text:
delayMicroseconds not working on STM32F103C8T6
Due to the fake STM32F103C8T6 module in the market, the delayMicroseconds function is working qucker than expected, when I expect a delay of 1000 us , I get a delay of 500 us. Is there a better method, like to create separate module for counting in microseconds using micros timer? Or there are other proper bootloaders than this one . I use Arduino IDE for programming STM32F103C8T6

Being off by a factor of 2 seems to be way too much. I have no experience with ARM processors, but I've seen such problems with AVR based microcontrollers, when the frequency set by the fuses was different, that what was set in the Arduino IDE. So the microcontroller ran on a different frequency. Are you sure, that you run on the right frequency?

Have you considered using a RTC? Something like a DS1307 breakout with I2C communications will provide you with accurate timing.
https://www.bobmixon.com/2020/03/real-time-clock-and-arduino/

How would you do a 1,000 µs delay with a DS1307?

Good point... the OP wrote "µs" and I read "ms". lol


text:
Display a Random Number to Display for T Seconds With Millis() for Dice Roller
I'm coding an electronic dice roller for a project. At the press of a push button (A2), the code must display a random number to the two digit seven segment display for 20 seconds, then display blank.
Currently, my code will display a random number every t seconds while the button is continuously held. I would like the user to be able to press the button and release to let the code do it's thing.
What type of examples should I look at to achieve this? I'm quite a beginner at arduino code.
    #include "SevSeg.h"
SevSeg sevseg; //Instantiate a seven segment object

int displayPeriod = 1000; //button press delay
unsigned long time_now = 0;

long randNumber;

void setup() {

  pinMode(A2,INPUT);
 randomSeed(analogRead(3));

  byte numDigits = 2;
  byte digitPins[] = {2, 3};
  byte segmentPins[] = {4,5,6,7,8,9,10};
  bool resistorsOnSegments = false; // 'false' means resistors are on digit pins
  byte hardwareConfig = COMMON_CATHODE; // See README.md for options
  bool updateWithDelays = false; // Default 'false' is Recommended
  bool leadingZeros = false; // Use 'true' if you'd like to keep the leading zeros
  bool disableDecPoint = true; // Use 'true' if your decimal point doesn't exist or isn't connected. Then, you only need to specify 7 segmentPins[]

  sevseg.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments,
  updateWithDelays, leadingZeros, disableDecPoint);

}

void loop() {

if(digitalRead(A2) == HIGH){

  rollD20();

}

else{

  sevseg.setChars("");
  sevseg.refreshDisplay();
}

}

void rollD20(){

if(millis() >= time_now + displayPeriod){
        time_now += displayPeriod;
        time_now = millis();
        randNumber = random(21);
        }
        sevseg.setNumber(randNumber);
  sevseg.refreshDisplay();
  }

void testInput(){
sevseg.setNumber(0);
sevseg.refreshDisplay();
}

Note that analogRead(3) is a very poor entropy source. Timing the button press with micros() would be way better.

Why is it a bad source? From the arduino reference for the random() function: "If it is important for a sequence of values generated by random() to differ, on subsequent executions of a sketch, use randomSeed() to initialize the random number generator with a fairly random input, such as analogRead() on an unconnected pin." Edit: Nvm I understand why it's bad.

your code handles a button press, but it does not do anything with the button release  ... do not code for a button pressed state because that state lasts as long as the button is held ... code for transition between button released and button pressed because the transition happens only once and can only repeat if you release the button

@jsotola Yes I am currently reading on how to do that. I would love to be able to have the function finish it's code completely before going back to the main loop. Since writing this post, the code now has a for loop which is meant to display 29 random numbers back to back, then display the 30th number on the display. I can't seem to get it. What type of example should I look for?

I would recommend to not reinvent the wheel, and proper button management may not be so trivial. I would suggest this library to address your problem.

The problem is that your rollD20 function is only called when the button is pressed.  So once you release the button, it never goes back to that routine to finish.  You need to separate the calling of the function from the detecting of the button.
bool rollingDice = false;

void loop() {

if(digitalRead(A2) == HIGH){
  rollingDice = true;
}
if(rollingDice){
  rollD20();
}
else{
  sevseg.setChars("");
  sevseg.refreshDisplay();
}

And then in your rollD20 method you need to set that back to false when it is time to stop:
void rollD20(){
  if(millis() >= time_now + displayPeriod){
        time_now += displayPeriod;
        time_now = millis();
        randNumber = random(21);
        rollingDice = false;
        }
  sevseg.setNumber(randNumber);
  sevseg.refreshDisplay();
  }


text:
Help reading orientation from gyroscope
I recently bought a L3GD20H Triple-Axis Gyro to use it to measure orientation, but found out it instead reports the rate of rotation in degrees per second. I was told this means that to detect the total degrees of rotation, I need to integrate the rate of rotation over time.
I was wondering if someone could help me with this since I'm having trouble wrapping my head around a formula to create. here is my code so far if it helps:
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_L3GD20_U.h>

/* Assign a unique ID to this sensor at the same time */
Adafruit_L3GD20_Unified gyro = Adafruit_L3GD20_Unified(20);

void displaySensorDetails(void)
{
  sensor_t sensor;
  gyro.getSensor(&sensor);
  Serial.println("------------------------------------");
  Serial.print  ("Sensor:       "); Serial.println(sensor.name);
  Serial.print  ("Driver Ver:   "); Serial.println(sensor.version);
  Serial.print  ("Unique ID:    "); Serial.println(sensor.sensor_id);
  Serial.print  ("Max Value:    "); Serial.print(sensor.max_value); Serial.println(" rad/s");
  Serial.print  ("Min Value:    "); Serial.print(sensor.min_value); Serial.println(" rad/s");
  Serial.print  ("Resolution:   "); Serial.print(sensor.resolution); Serial.println(" rad/s");
  Serial.println("------------------------------------");
  Serial.println("");
  delay(500);
}

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

  /* Enable auto-ranging */
  gyro.enableAutoRange(true);

  /* Initialise the sensor */
  if(!gyro.begin())
  {
    /* There was a problem detecting the L3GD20 ... check your connections */
    Serial.println("Ooops, no L3GD20 detected ... Check your wiring!");
    while(1);
  }

  /* Display some basic information on this sensor */
  displaySensorDetails();
}

void loop(void)
{
  /* Get a new sensor event */
  sensors_event_t event;
  gyro.getEvent(&event);

  /* Display the results (speed is measured in rad/s) */
  Serial.print("X: "); Serial.print(event.gyro.x); Serial.print("  ");
  Serial.print("Y: "); Serial.print(event.gyro.y); Serial.print("  ");
  Serial.print("Z: "); Serial.print(event.gyro.z); Serial.print("  ");
  Serial.println("rad/s ");
  delay(1);
}

So in summary, I need help creating the code/a formula that will use my Gyro to measure its orientation. Thank you for your time! I'm very lost.

To “integrate” is a slight oversimplification: you will have to compose many small rotations in order to get the current orientation. You should probably search for a library that does that for you, unless you are willing to dig into the heavy math.

Take a look at this example.
#include <Wire.h>

const int MPU = 0x68; // MPU6050 I2C address
float AccX, AccY, AccZ;
float GyroX, GyroY, GyroZ;
float accAngleX, accAngleY, gyroAngleX, gyroAngleY, gyroAngleZ;
float roll, pitch, yaw;
float AccErrorX, AccErrorY, GyroErrorX, GyroErrorY, GyroErrorZ;
float elapsedTime, currentTime, previousTime;
int c = 0;

void setup() {
  Serial.begin(19200);
  Wire.begin();                      // Initialize comunication
  Wire.beginTransmission(MPU);       // Start communication with MPU6050 // MPU=0x68
  Wire.write(0x6B);                  // Talk to the register 6B
  Wire.write(0x00);                  // Make reset - place a 0 into the 6B register
  Wire.endTransmission(true);        //end the transmission
  /*
  // Configure Accelerometer Sensitivity - Full Scale Range (default +/- 2g)
  Wire.beginTransmission(MPU);
  Wire.write(0x1C);                  //Talk to the ACCEL_CONFIG register (1C hex)
  Wire.write(0x10);                  //Set the register bits as 00010000 (+/- 8g full scale range)
  Wire.endTransmission(true);
  // Configure Gyro Sensitivity - Full Scale Range (default +/- 250deg/s)
  Wire.beginTransmission(MPU);
  Wire.write(0x1B);                   // Talk to the GYRO_CONFIG register (1B hex)
  Wire.write(0x10);                   // Set the register bits as 00010000 (1000deg/s full scale)
  Wire.endTransmission(true);
  delay(20);
  */
  // Call this function if you need to get the IMU error values for your module
  calculate_IMU_error();
  delay(20);

}

void loop() {
  // === Read acceleromter data === //
  Wire.beginTransmission(MPU);
  Wire.write(0x3B); // Start with register 0x3B (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(MPU, 6, true); // Read 6 registers total, each axis value is stored in 2 registers
  //For a range of +-2g, we need to divide the raw values by 16384, according to the datasheet
  AccX = (Wire.read() << 8 | Wire.read()) / 16384.0; // X-axis value
  AccY = (Wire.read() << 8 | Wire.read()) / 16384.0; // Y-axis value
  AccZ = (Wire.read() << 8 | Wire.read()) / 16384.0; // Z-axis value
  // Calculating Roll and Pitch from the accelerometer data
  accAngleX = (atan(AccY / sqrt(pow(AccX, 2) + pow(AccZ, 2))) * 180 / PI) - 0.58; // AccErrorX ~(0.58) See the calculate_IMU_error()custom function for more details
  accAngleY = (atan(-1 * AccX / sqrt(pow(AccY, 2) + pow(AccZ, 2))) * 180 / PI) + 1.58; // AccErrorY ~(-1.58)

  // === Read gyroscope data === //
  previousTime = currentTime;        // Previous time is stored before the actual time read
  currentTime = millis();            // Current time actual time read
  elapsedTime = (currentTime - previousTime) / 1000; // Divide by 1000 to get seconds
  Wire.beginTransmission(MPU);
  Wire.write(0x43); // Gyro data first register address 0x43
  Wire.endTransmission(false);
  Wire.requestFrom(MPU, 6, true); // Read 4 registers total, each axis value is stored in 2 registers
  GyroX = (Wire.read() << 8 | Wire.read()) / 131.0; // For a 250deg/s range we have to divide first the raw value by 131.0, according to the datasheet
  GyroY = (Wire.read() << 8 | Wire.read()) / 131.0;
  GyroZ = (Wire.read() << 8 | Wire.read()) / 131.0;
  // Correct the outputs with the calculated error values
  GyroX = GyroX + 0.56; // GyroErrorX ~(-0.56)
  GyroY = GyroY - 2; // GyroErrorY ~(2)
  GyroZ = GyroZ + 0.79; // GyroErrorZ ~ (-0.8)

  // Currently the raw values are in degrees per seconds, deg/s, so we need to multiply by sendonds (s) to get the angle in degrees
  gyroAngleX = gyroAngleX + GyroX * elapsedTime; // deg/s * s = deg
  gyroAngleY = gyroAngleY + GyroY * elapsedTime;
  yaw =  yaw + GyroZ * elapsedTime;

  // Complementary filter - combine acceleromter and gyro angle values
  roll = 0.96 * gyroAngleX + 0.04 * accAngleX;
  pitch = 0.96 * gyroAngleY + 0.04 * accAngleY;

  // Print the values on the serial monitor
  Serial.print(roll);
  Serial.print("/");
  Serial.print(pitch);
  Serial.print("/");
  Serial.println(yaw);
}

void calculate_IMU_error() {
  // We can call this funtion in the setup section to calculate the accelerometer and gyro data error. From here we will get the error values used in the above equations printed on the Serial Monitor.
  // Note that we should place the IMU flat in order to get the proper values, so that we then can the correct values
  // Read accelerometer values 200 times
  while (c < 200) {
    Wire.beginTransmission(MPU);
    Wire.write(0x3B);
    Wire.endTransmission(false);
    Wire.requestFrom(MPU, 6, true);
    AccX = (Wire.read() << 8 | Wire.read()) / 16384.0 ;
    AccY = (Wire.read() << 8 | Wire.read()) / 16384.0 ;
    AccZ = (Wire.read() << 8 | Wire.read()) / 16384.0 ;
    // Sum all readings
    AccErrorX = AccErrorX + ((atan((AccY) / sqrt(pow((AccX), 2) + pow((AccZ), 2))) * 180 / PI));
    AccErrorY = AccErrorY + ((atan(-1 * (AccX) / sqrt(pow((AccY), 2) + pow((AccZ), 2))) * 180 / PI));
    c++;
  }
  //Divide the sum by 200 to get the error value
  AccErrorX = AccErrorX / 200;
  AccErrorY = AccErrorY / 200;
  c = 0;
  // Read gyro values 200 times
  while (c < 200) {
    Wire.beginTransmission(MPU);
    Wire.write(0x43);
    Wire.endTransmission(false);
    Wire.requestFrom(MPU, 6, true);
    GyroX = Wire.read() << 8 | Wire.read();
    GyroY = Wire.read() << 8 | Wire.read();
    GyroZ = Wire.read() << 8 | Wire.read();
    // Sum all readings
    GyroErrorX = GyroErrorX + (GyroX / 131.0);
    GyroErrorY = GyroErrorY + (GyroY / 131.0);
    GyroErrorZ = GyroErrorZ + (GyroZ / 131.0);
    c++;
  }
  //Divide the sum by 200 to get the error value
  GyroErrorX = GyroErrorX / 200;
  GyroErrorY = GyroErrorY / 200;
  GyroErrorZ = GyroErrorZ / 200;
  // Print the error values on the Serial Monitor
  Serial.print("AccErrorX: ");
  Serial.println(AccErrorX);
  Serial.print("AccErrorY: ");
  Serial.println(AccErrorY);
  Serial.print("GyroErrorX: ");
  Serial.println(GyroErrorX);
  Serial.print("GyroErrorY: ");
  Serial.println(GyroErrorY);
  Serial.print("GyroErrorZ: ");
  Serial.println(GyroErrorZ);
}

https://howtomechatronics.com/tutorials/arduino/arduino-and-mpu6050-accelerometer-and-gyroscope-tutorial/

Do not do Wire.read()<<8|Wire.read(): the C++ language does not guarantee the order of evaluation of the two calls to Wire.read(). Do val=Wire.read()<<8;val|=Wire.read() instead. Also, this naive integration will only work if the roll and pitch angles remain small.


text:
Make phone call over 4G LTE
I have used the SIM800L module in the past, but with Ting shutting down their 2G network, I have been looking for alternatives. I have a SIM7000A, but I can't seem to find a microphone or speaker pin. Can this make calls, or will I have to find something else? I am using an Arduino Mega.

The SIM7000 doesn't have a microphone or speaker pin.  Instead it provides a PCM interface to connect to an external CODEC chip.
As it says in the Hardware Design Manual:

SIM7000 provides a PCM interface for external codec, which can be used in master mode with short sync and 16 bits linear format.

If you want to use it for phone calls then you will need a module that also incorporates said CODEC chip and all the associated circuitry to connect to a microphone and speaker.


text:
Scroll Left to Right on MAX7219 Display
For scrolling from left to right (Arabic letters) I need a function to print words/sentences on the MAX7219 display. [By setpixel(x, y) function]
I did a lot of searching and my efforts failed. I found the following example but I couldn't change it. By default this example scrolls from right to left. (I need scroll from left to right.)
#include <LEDMatrixDriver.hpp>
const uint8_t LEDMATRIX_CS_PIN = 9;

// Number of 8x8 segments you are connecting
const int LEDMATRIX_SEGMENTS = 4;
const int LEDMATRIX_WIDTH    = LEDMATRIX_SEGMENTS * 8;

// The LEDMatrixDriver class instance
LEDMatrixDriver lmd(LEDMATRIX_SEGMENTS, LEDMATRIX_CS_PIN);

// Marquee text
char text[] = "** LED MATRIX DEMO! ** (1234567890) ++ \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\" ++ <$%/=?'.@,> --";

// Marquee speed (lower nubmers = faster)
const int ANIM_DELAY = 30;

void setup() {
  // init the display
  lmd.setEnabled(true);
  lmd.setIntensity(2);   // 0 = low, 10 = high
}

int x=0, y=0;   // start top left

// This is the font definition. You can use http://gurgleapps.com/tools/matrix to create your own font or sprites.
// If you like the font feel free to use it. I created it myself and donate it to the public domain.
byte font[95][8] = { {0,0,0,0,0,0,0,0}, // SPACE
                     {0x10,0x18,0x18,0x18,0x18,0x00,0x18,0x18}, // EXCL
                     {0x28,0x28,0x08,0x00,0x00,0x00,0x00,0x00}, // QUOT
                     {0x00,0x0a,0x7f,0x14,0x28,0xfe,0x50,0x00}, // #
                     {0x10,0x38,0x54,0x70,0x1c,0x54,0x38,0x10}, // $
                     {0x00,0x60,0x66,0x08,0x10,0x66,0x06,0x00}, // %
                     {0,0,0,0,0,0,0,0}, // &
                     {0x00,0x10,0x18,0x18,0x08,0x00,0x00,0x00}, // '
                     {0x02,0x04,0x08,0x08,0x08,0x08,0x08,0x04}, // (
                     {0x40,0x20,0x10,0x10,0x10,0x10,0x10,0x20}, // )
                     {0x00,0x10,0x54,0x38,0x10,0x38,0x54,0x10}, // *
                     {0x00,0x08,0x08,0x08,0x7f,0x08,0x08,0x08}, // +
                     {0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x08}, // COMMA
                     {0x00,0x00,0x00,0x00,0x7e,0x00,0x00,0x00}, // -
                     {0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x06}, // DOT
                     {0x00,0x04,0x04,0x08,0x10,0x20,0x40,0x40}, // /
                     {0x00,0x38,0x44,0x4c,0x54,0x64,0x44,0x38}, // 0
                     {0x04,0x0c,0x14,0x24,0x04,0x04,0x04,0x04}, // 1
                     {0x00,0x30,0x48,0x04,0x04,0x38,0x40,0x7c}, // 2
                     {0x00,0x38,0x04,0x04,0x18,0x04,0x44,0x38}, // 3
                     {0x00,0x04,0x0c,0x14,0x24,0x7e,0x04,0x04}, // 4
                     {0x00,0x7c,0x40,0x40,0x78,0x04,0x04,0x38}, // 5
                     {0x00,0x38,0x40,0x40,0x78,0x44,0x44,0x38}, // 6
                     {0x00,0x7c,0x04,0x04,0x08,0x08,0x10,0x10}, // 7
                     {0x00,0x3c,0x44,0x44,0x38,0x44,0x44,0x78}, // 8
                     {0x00,0x38,0x44,0x44,0x3c,0x04,0x04,0x78}, // 9
                     {0x00,0x18,0x18,0x00,0x00,0x18,0x18,0x00}, // :
                     {0x00,0x18,0x18,0x00,0x00,0x18,0x18,0x08}, // ;
                     {0x00,0x10,0x20,0x40,0x80,0x40,0x20,0x10}, // <
                     {0x00,0x00,0x7e,0x00,0x00,0xfc,0x00,0x00}, // =
                     {0x00,0x08,0x04,0x02,0x01,0x02,0x04,0x08}, // >
                     {0x00,0x38,0x44,0x04,0x08,0x10,0x00,0x10}, // ?
                     {0x00,0x30,0x48,0xba,0xba,0x84,0x78,0x00}, // @
                     {0x00,0x1c,0x22,0x42,0x42,0x7e,0x42,0x42}, // A
                     {0x00,0x78,0x44,0x44,0x78,0x44,0x44,0x7c}, // B
                     {0x00,0x3c,0x44,0x40,0x40,0x40,0x44,0x7c}, // C
                     {0x00,0x7c,0x42,0x42,0x42,0x42,0x44,0x78}, // D
                     {0x00,0x78,0x40,0x40,0x70,0x40,0x40,0x7c}, // E
                     {0x00,0x7c,0x40,0x40,0x78,0x40,0x40,0x40}, // F
                     {0x00,0x3c,0x40,0x40,0x5c,0x44,0x44,0x78}, // G
                     {0x00,0x42,0x42,0x42,0x7e,0x42,0x42,0x42}, // H
                     {0x00,0x7c,0x10,0x10,0x10,0x10,0x10,0x7e}, // I
                     {0x00,0x7e,0x02,0x02,0x02,0x02,0x04,0x38}, // J
                     {0x00,0x44,0x48,0x50,0x60,0x50,0x48,0x44}, // K
                     {0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x7c}, // L
                     {0x00,0x82,0xc6,0xaa,0x92,0x82,0x82,0x82}, // M
                     {0x00,0x42,0x42,0x62,0x52,0x4a,0x46,0x42}, // N
                     {0x00,0x3c,0x42,0x42,0x42,0x42,0x44,0x38}, // O
                     {0x00,0x78,0x44,0x44,0x48,0x70,0x40,0x40}, // P
                     {0x00,0x3c,0x42,0x42,0x52,0x4a,0x44,0x3a}, // Q
                     {0x00,0x78,0x44,0x44,0x78,0x50,0x48,0x44}, // R
                     {0x00,0x38,0x40,0x40,0x38,0x04,0x04,0x78}, // S
                     {0x00,0x7e,0x90,0x10,0x10,0x10,0x10,0x10}, // T
                     {0x00,0x42,0x42,0x42,0x42,0x42,0x42,0x3e}, // U
                     {0x00,0x42,0x42,0x42,0x42,0x44,0x28,0x10}, // V
                     {0x80,0x82,0x82,0x92,0x92,0x92,0x94,0x78}, // W
                     {0x00,0x42,0x42,0x24,0x18,0x24,0x42,0x42}, // X
                     {0x00,0x44,0x44,0x28,0x10,0x10,0x10,0x10}, // Y
                     {0x00,0x7c,0x04,0x08,0x7c,0x20,0x40,0xfe}, // Z
                      // (the font does not contain any lower case letters. you can add your own.)
                  };    // {}, //

void loop()
{
    // Draw the text to the current position
    int len = strlen(text);
    drawString(text, len, x, 0);
    // In case you wonder why we don't have to call lmd.clear() in every loop: The font has a opaque (black) background...

    // Toggle display of the new framebuffer
    lmd.display();

    // Wait to let the human read the display
    delay(ANIM_DELAY);

    // Advance to next coordinate
    if( --x < len * -8 ) {
        x = LEDMATRIX_WIDTH;
    }
}

/**
 * This function draws a string of the given length to the given position.
 */
void drawString(char* text, int len, int x, int y )
{
  for( int idx = 0; idx < len; idx ++ )
  {
    int c = text[idx] - 32;

    // stop if char is outside visible area
    if( x + idx * 8  > LEDMATRIX_WIDTH )
      return;

    // only draw if char is visible
    if( 8 + x + idx * 8 > 0 )
      drawSprite( font[c], x + idx * 8, y, 8, 8 );
  }
}

/**
 * This draws a sprite to the given position using the width and height supplied (usually 8x8)
 */
void drawSprite( byte* sprite, int x, int y, int width, int height )
{
  // The mask is used to get the column bit from the sprite row
  byte mask = B10000000;

  for( int iy = 0; iy < height; iy++ )
  {
    for( int ix = 0; ix < width; ix++ )
    {
      lmd.setPixel(x + ix, y + iy, (bool)(sprite[iy] & mask ));

      // shift the mask by one pixel to the right
      mask = mask >> 1;
    }

    // reset column mask
    mask = B10000000;
  }

What exactly is your problem? The scrolling from left to right, the printing from right to left or printing arabic letters?

@chrisl Change example above and scroll from left to right.

To scroll in the opposite direction, change this if statement:
if( --x < len * -8 ) {
    x = LEDMATRIX_WIDTH;
}

to this:
if( ++x > LEDMATRIX_WIDTH+len*8 ){
    x = 0;
}

x (the start position of the text) is now incremented instead of decremented, until the whole text (consisting of len*8 pixels in x direction) is out of the display, where it then gets reset to zero.
This assumes, that the printing of the arabic letters is done from right to left (You might want to implement this, when working with arabic text). The function in the example prints always from left to right, so you need to use this code:
if( ++x > LEDMATRIX_WIDTH ){
    x = -len*8;
}

since in this case the text will not be visible in the moment, that the position is over the matrix width.

Thanks @chrisl, I modified the code as you said (if statement), But no text is displayed, Please see the video, In the first phase I want to scroll the same English text variable from left to right.

Ok, I corrected an error in the last code bit, that you need to use. Of course the text position needs to be reset to the corresponding negative value, so that the right end of the text will scroll into the display. Sorry for that error.

Thanks @chrisl, Everything is okay.

You can use the MD Parola library which has a setting to change the direction.
PA_SCROLL_RIGHT or PA_SCROLL_LEFT.

Thanks @tavis , I'll test. Of course, I need a library that has setpixel(x, y) function.


text:
analogReference(INTERNAL) configuration
I need some help because I did not understand the configuration analogReference(INTERNAL).
I would measure the intensity of a Laser beam passing through a filter. This is the circuit I would implement, using the 3.3 V power supply:

In order to rise up the resolution of the system, I would use the 1.1 V power supply (Arduino Uno) to feed the sensor, keeping the Laser power supply at 5 V. In the analogReference(EXTERNAL) configuration shown in the schematic, the sensor is powered by the 3V3 pin, which is connected to the AREF pin. How should I change the circuit in analogReference(INTERNAL) configuration?

What exactly is the sensor?

If you use the internal reference voltage, you must remove the wire from 3.3v to AREF. So it's not connected to anything.

Changing the analog reference does not change the resolution.  All it does is change the measurement range. It compresses the existing resolution into a smaller voltage range.
If you then compress the voltage range of your signal in the same way to fit into the now compressed analog reference voltage range (for example by reducing the supply voltage to 1.1V) you end up achieving absolutely nothing.
The only time you would use the 1.1V internal reference is if your incoming signal is already between 0V and 1.1V and you would otherwise be wasting the resolution above the highest voltage the sensor gives out.


text:
Pca9685 & WS2818B, 1 Nano
Arduino n00b here. I currently have an Arduino Nano set up to run 6 servos from a PCA9685 board. I'm looking to add 6 switches and 6 LED indicators to switch servo positions. What I'm curious about is how to connect the WS2818B. I know they can be run through I2C, but the Pca9685 is using those wires. Can I run both the pca9685 and the LEDs through I2C or just run each LED through a separate pin?

I was looking at WS2818B datasheet, they do not use i2c. It just needs a single ( dedicated) pin to receive the color/brightness commands.


text:
How to use I2S in ESP boards?
I have researched this a lot, but haven't found anything on which I can trust.
I want to use a particular ESP board to play audio. To play audio, I2S support is required. But, I know that not every ESP board break out the I2S pins from the chip. According to me, buying an ESP32 only to use the I2S would be a waste of money. So, my question is, if I just want to use I2S, which board is would be suitable? Please provide some references if you can.

Few months ago I tested successfully I2S with this library, I used the default pins:
bck_io_num = 26
ws_io_num = 25
data_out_num = 22

which are available on many boards such as Lolin D32.

Can we use any pin for the I2S?

I don't think so, those pins should be internally wired to the I2S peripheral (but I'm not sure)

You have to use the dedicated I2S pins.


text:
How to decrease a variable every second
I am trying to count down the variable "bankValue" with a certain costfactor
The code I tried will perfectly count down the bankValue..but..
#define INTERVAL_MESSAGE1 1000

unsigned long time_1 = 0;

const float CostFactor = 1.0;
float bankValue = 10.00;
const float CostButton1 = 0.004167;

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

void loop() {
    if(millis() >= time_1 + INTERVAL_MESSAGE1){
        bankValue = bankValue - (CostButton1 * CostFactor);
        time_1 +=INTERVAL_MESSAGE1;
        print_time(time_1);
        Serial.print("€");
        Serial.println(bankValue);
    }
   }

I want this the use in an if.
IF button1 is pressed then bankValue will be decreased by a costfactor every second.
I tried this in an if
  if(Pushed == HIGH){
    if(Pushed != StatePushed){
    Serial.println("Button1 OFF");
    }

    digitalWrite(relayPin, LOW);
  }else{
    if(Pushed != StatePushed){
    Serial.println("Button1 ON");
    }
                if(millis() >= time_1 + INTERVAL_MESSAGE1){
        bankValue = bankValue - (Button1Value * CostFactor);
        time_1 +=INTERVAL_MESSAGE1;
        print_time(time_1);
        Serial.print("€");
        Serial.println(bankValue);
        }
    digitalWrite(relayPin, HIGH);
     }

If the button is pressed, bankValue will decrease.
But when the button is not active....the millis timer keeps on running.
When switching on the button again, I see the bankValue decrease rapidly and not every second.
So the main question:
How can I decrease a variable every second when a button is active.

You are handling millis() wrong (should be if(millis() - time_1 >= INTERVAL_MESSAGE1) to avoid overflow issues), though that should not cause the seen behavior. Please show a full working sketch for the second code part

you may be attacking the problem from the wrong side ... you are checking the button state and then timing 1 second and decrementing the counter ... instead, you could continuously time 1 second intervals ... at each interval, check the button and act accordingly ..... you could also time 1/10 second intervals (ticks) and accumulate these when the button is pressed .... if 10 ticks have been counted, then decrement bankValue

Your basic main problem is that you don't know when the button was pressed.  Your timing algorithm always works from the "last time the value was decremented" - and that could be hours ago.  When you press the button the difference between millis() and time_1 could be massive, and it has to count up one second at a time until time_1 passes millis().
What you really need to do is separate out the button from the action. That makes it easier to manage.  You need to find the times when the button transitions from HIGH to LOW (pressed) and from LOW to HIGH (released). You're almost doing that right now, but not quite.  Then when you find the moment of being pressed you can say "From this moment forth you shall count."
For example you might change the first part of your code to be:
if (Pushed != StatePushed) {
    StatePushed = Pushed; // Remember the current state for the next time round
    if (StatePushed == HIGH) { // Released
        Serial.println("Button1 OFF");
    } else { // Pressed
        Serial.println("Button1 ON");
        time_1 = millis(); // Remember what the time is right now
    }
}

That then is a single atomic operation and you can now at any time examine StatePressed to see if the button is pressed or not, and also at the moment of pressing time_1 is set to the current millis() value, so you now know when the button was pressed.
Now you can add your second part using StatePressed as the trigger:
if (StatePressed == LOW) { // Button pressed
    if(millis() >= time_1 + INTERVAL_MESSAGE1){
        bankValue = bankValue - (Button1Value * CostFactor);
        time_1 +=INTERVAL_MESSAGE1;
        print_time(time_1);
        Serial.print("€");
        Serial.println(bankValue);
    }
}

However your method of comparing the time is not good. It doesn't handle the millis rollover problem.  Instead you should be using something more like:
if (millis() - time_1 >= INTERVAL_MESSAGE1) {
    time_1 = millis();
    ... etc ...
}

tried your solution. Nearly worked :-)

I tried to use the solution post by Majenko and came up with something like this:
  if(Pushed != StatePushed) {
    if(Pushed == HIGH){
      if(Pushed != StatePushed){
        Serial.println("LED OFF");
        }
        digitalWrite(ledPin, LOW);  // turn LED OFF
        }else{
        if(Pushed != StatePushed){
        Serial.println("LED ON");
        time_1 = millis();
        }
        digitalWrite(ledPin, HIGH);  // turn LED OFF
        }
  }
         StatePushed = Pushed;

  delay(100);

  if(Pushed == LOW){
    if(millis() >= time_1 + INTERVAL_MESSAGE1){
      time_1 = millis();
        bankValue = bankValue - (coinValueB * CostFactor);
        time_1 +=INTERVAL_MESSAGE1;
        Serial.print("€");
        Serial.println(bankValue);
                Serial.println(INTERVAL_MESSAGE1);
    }
  }

Pretty much how you suggested it...
but I realize I absolutely do not understand how millis() exactly works.
I have no idea what this does:
if(millis() >= time_1 + INTERVAL_MESSAGE1)

In a way, the loop works. But the timing is really off.
With my settings, every second subtracting 0.004167, should be 0,25 is one minute.
But it was only around half...0,13 or so

It is off because you are adding INTERVAL_MESSAGE1 with time_1. Just remove that line. And don't use delay.

This answer is in response to Niles's answer based on Majenko's answer (phew! that was a bit of a mouthful).
millis() returns how many milliseconds have passed since your program started.
And your timing is off because you are adding INTERVAL_MESSAGE1 with time_1 i.e. instead of waiting for one second you are actually subtracting after every two seconds. Hence, you got half the value you expected. Remove that line. (And also don't use delay).
I have isolated your substracting part of the code. Run this and you should see the result (button is connected to D4):
unsigned long PreviousTime = 0;
const unsigned long THRESHOLD = 1000;
const float CostFactor = 1.0;
float bankValue = 10.00;
const float CostButton1 = 0.004167;

void setup()
{
  Serial.begin(9600);
  pinMode(4, INPUT_PULLUP);
}

void loop()
{
  if(digitalRead(4) == 0)
  {
    if((unsigned long)(millis() - PreviousTime) >=  THRESHOLD) // You need to check time like this to avoid overflow
    {
      PreviousTime = millis();
      bankValue = bankValue - (CostButton1 * CostFactor);
      Serial.println(bankValue);
    }
  }
}

Note that millis() - PreviousTime is an unsigned long. No need to cast it.


text:
ESP32 Bluetooth SPP Max Speed
I am trying to understand the maximum BT SPP transmission speed that can be achieved using ESP32.
What my project requires is to send 2bytes of data every 200us (5kHz) AND additional 15bytes of data every 50ms(20Hz) via BT.
I am trying to achieve that using BT SPP, however, I could not understand the speed of BluetoothSerial::write AND BluetoothSerial::print.
Based on my testing for 5kHz, the BluetoothSerial::write freezes after 2-3 seconds of connection.
BluetoothSerial::println function doesn't seem to freeze, however, the time taken for the function to complete doesn't seem to be constant. Please refer to the code below on how I measure the time taken for the function to complete.
The picture below shows the time in microseconds each time the function (dataFormat()) takes place. If you look through, there are 2 instances where the time duration is more than an average 0f 80us.
I would like to know, ESP32 BT SPP can achieve such a speed or there is another way I could achieve this.
Thank you for your time and assistance in this matter.
I have asked the same question in ESP32 Forum as well here.
void dataFormat(record r){
  serialBtPrint_dur = micros();
  char msg[20];
  sprintf(msg,"%04d%05d%05d%05",r.e, r.r, r.p, r.y);
  SerialBT.println(msg);
  serialBtPrint_dur = micros() - serialBtPrint_dur;
  }
}

void loop() {
  char msg[20];
  uint8_t testMsg[20] = "abcdefghijklmnop\n";
  if(!structs.isEmpty()){
    dataset[local_rd_ptr].yawData);
    data::dataFormat(structs.shift());
    Serial.println(serialBtPrint_dur);
  }
}

This seems more like an overflow issue with something than an actual delay.  If you look at the time in the log, it seems you aren't skipping seconds in the log (aka, 19:12:32.234 in two sequential log entries when you claim a delay).  I think it's an error of working with larger than 8-bit data sizes.  I know this is an old question, but I was looking for info and came upon it and figured I'd ask.

Thanks actually for having a thought on this. It has not been solved which lead me to use a different mechanism. For this particular scenario, the overflow would only happen if the micros difference is bigger than 8bit data size, which in theory shouldn't happen.


text:
Blink not working
I have written this code to write and receive signals over i2c between two Uno's. I have a master and a slave code, this is working fine. Now I want the led to blink, for this I added the blink without delay example. Unfortunately I can't get it working at all...
// Wire Slave Receiver

#include <Wire.h> //include Library
// define Led Pins
#define LED1 3 //Pin 3
#define LED2 4 //Pin 4
#define LED3 5 //Pin 5

int ledState = LOW;             // ledState used to set the LED
unsigned long previousMillis = 0;        // will store last time LED was updated
const long interval = 500;           // interval at which to blink (milliseconds)

void setup()
{
  Wire.begin(4);                // join i2c bus with address #4
  Wire.onReceive(receiveEvent); // register event
  Serial.begin(9600);           // start serial for output

  //set Pin modes
  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
  pinMode(LED3, OUTPUT);
  //intern pulldown
  digitalWrite(LED1, LOW);
  digitalWrite(LED2, LOW);
  digitalWrite(LED3, LOW);

}

void loop()
{
  unsigned long currentMillis = millis();
  delay(100);
}

// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany)
{
  while (1 < Wire.available()) // loop through all but the last
  {

    char c = Wire.read(); // receive byte as a character
    Serial.print(c, BIN);     // print the character as Binary

  }
  int x = Wire.read();    // receive byte as an integer
  Serial.println(x, BIN); // print the integer as Binary

  if (x == 1) { //turn LED1 on
    digitalWrite(LED2, LOW);
    digitalWrite(LED3, LOW);
    digitalWrite(LED1, HIGH);
    Serial.println("LED1 on");
  }
  if (x == 2) { //blink LED1
    unsigned long currentMillis = millis();
    if (currentMillis - previousMillis >= interval) {
      previousMillis = currentMillis;
      if (ledState == LOW) {
        ledState = HIGH;
      } else {
        ledState = LOW;
      }
      digitalWrite(LED1, ledState);
    }
  }

  if (x == 3) { //turn LED2 on
    digitalWrite(LED1, LOW);
    digitalWrite(LED2, HIGH);
    delay(100);
  }
  if (x == 4) { //blink LED2
    unsigned long currentMillis = millis();
    if (currentMillis - previousMillis >= interval) {
      previousMillis = currentMillis;
      if (ledState == LOW) {
        ledState = HIGH;
      } else {
        ledState = LOW;
      }
      digitalWrite(LED2, ledState);
    }
  }
  if (x == 5) { //turn LED3 on
    digitalWrite(LED2, LOW);
    digitalWrite(LED3, HIGH);
  }
  if (x == 6) { //blink LED3
    unsigned long currentMillis = millis();
    if (currentMillis - previousMillis >= interval) {
      previousMillis = currentMillis;
      if (ledState == LOW) {
        ledState = HIGH;
      } else {
        ledState = LOW;
      }
      digitalWrite(LED3, ledState);
    }
  }
  if (x == 7) { //turn LED1 nad 2 on
    digitalWrite(LED3, LOW);
    digitalWrite(LED1, HIGH);
    digitalWrite(LED2, HIGH);
  }
  if (x == 8) { //Blink LED1 and 2
    digitalWrite(LED1, LOW);
    digitalWrite(LED2, LOW);
  }
  if (x == 9) { //turn LED2 and 3 on
    digitalWrite(LED1, LOW);
    digitalWrite(LED2, LOW);

    digitalWrite(LED2, HIGH);
    digitalWrite(LED3, HIGH);
  }

}

Thanks for your response. I tried to put all the of statements into the loop, but it's still not working. :P I have no idea how to put it into the loop so it works.
// Wire Slave Receiver

#include <Wire.h> //include Library
// define Led Pins
#define LED1 3 //Pin 3
#define LED2 4 //Pin 4
#define LED3 5 //Pin 5

int ledState = LOW;             // ledState used to set the LED
unsigned long previousMillis = 0;        // will store last time LED was updated
const long interval = 500;           // interval at which to blink (milliseconds)

void setup()
{
  Wire.begin(4);                // join i2c bus with address #4
  Wire.onReceive(receiveEvent); // register event
  Serial.begin(9600);           // start serial for output

  //set Pin modes
  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
  pinMode(LED3, OUTPUT);
  //intern pulldown
  digitalWrite(LED1, LOW);
  digitalWrite(LED2, LOW);
  digitalWrite(LED3, LOW);

}

void loop()
{
    if (x == 1) { //turn LED1 on
    digitalWrite(LED2, LOW);
    digitalWrite(LED3, LOW);
    digitalWrite(LED1, HIGH);
    Serial.println("LED1 on");
  }
  if (x == 2) { //blink LED1
    unsigned long currentMillis = millis();
    if (currentMillis - previousMillis >= interval) {
      previousMillis = currentMillis;
      if (ledState == LOW) {
        ledState = HIGH;
      } else {
        ledState = LOW;
      }
      digitalWrite(LED1, ledState);
    }
  }

  if (x == 3) { //turn LED2 on
    digitalWrite(LED1, LOW);
    digitalWrite(LED2, HIGH);
    delay(100);
  }
  if (x == 4) { //blink LED2
    unsigned long currentMillis = millis();
    if (currentMillis - previousMillis >= interval) {
      previousMillis = currentMillis;
      if (ledState == LOW) {
        ledState = HIGH;
      } else {
        ledState = LOW;
      }
      digitalWrite(LED2, ledState);
    }
  }
  if (x == 5) { //turn LED3 on
    digitalWrite(LED2, LOW);
    digitalWrite(LED3, HIGH);
  }
  if (x == 6) { //blink LED3
    unsigned long currentMillis = millis();
    if (currentMillis - previousMillis >= interval) {
      previousMillis = currentMillis;
      if (ledState == LOW) {
        ledState = HIGH;
      } else {
        ledState = LOW;
      }
      digitalWrite(LED3, ledState);
    }
  }
  if (x == 7) { //turn LED1 nad 2 on
    digitalWrite(LED3, LOW);
    digitalWrite(LED1, HIGH);
    digitalWrite(LED2, HIGH);
  }
  if (x == 8) { //Blink LED1 and 2
    digitalWrite(LED1, LOW);
    digitalWrite(LED2, LOW);
  }
  if (x == 9) { //turn LED2 and 3 on
    digitalWrite(LED1, LOW);
    digitalWrite(LED2, LOW);

    digitalWrite(LED2, HIGH);
    digitalWrite(LED3, HIGH);
  }
  unsigned long currentMillis = millis();
  delay(100);
}

// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany)
{
  while (1 < Wire.available()) // loop through all but the last
  {

    char c = Wire.read(); // receive byte as a character
    Serial.print(c, BIN);     // print the character as Binary

  }
  int x = Wire.read();    // receive byte as an integer
  Serial.println(x, BIN); // print the integer as Binary

}

You are misinterpreting how the onReceive callback works. The millis() code like in the BlinkWithoutDelay example relies on the fact, that it is run repeatedly very fast, so that effectively the time is checked regularily very fast.
The onReceive callback is only called once every time, that the Wire library received an I2C message, from an interrupt service routine. It is not called repeatedly. So the millis() code in there, will only be executed once. Since no time has passed (and millis() wouldn't increment inside an ISR either way) nothing happens there and the callback exits. After that the code is not executed further times.
You need to put the millis() code into the loop() function, so that it is executed repeatedly. In fact you can put all the if statements with x into the loop() function.

EDIT:
Your second version of the code should result in compilation errors (which you really should have included into your question). They will say, that x is not declared in this scope. You read the I2C data from the buffer in the onReceive callback and save it into a newly created variable x. Since x is declared inside the function, it will cease to exist right after the end of this function. The loop() function does not know about x. You need to define x globally outside of any function at the start of your sketch.
This results in this code:
// Wire Slave Receiver

#include <Wire.h> //include Library
// define Led Pins
#define LED1 3 //Pin 3
#define LED2 4 //Pin 4
#define LED3 5 //Pin 5

uint8_t x=0;                    // define x at global scope, so that it is available everywhere
int ledState = LOW;             // ledState used to set the LED
unsigned long previousMillis = 0;        // will store last time LED was updated
const long interval = 500;           // interval at which to blink (milliseconds)

void setup()
{
  Wire.begin(4);                // join i2c bus with address #4
  Wire.onReceive(receiveEvent); // register event
  Serial.begin(9600);           // start serial for output

  //set Pin modes
  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
  pinMode(LED3, OUTPUT);
  //intern pulldown
  digitalWrite(LED1, LOW);
  digitalWrite(LED2, LOW);
  digitalWrite(LED3, LOW);

}

void loop()
{
    if (x == 1) { //turn LED1 on
    digitalWrite(LED2, LOW);
    digitalWrite(LED3, LOW);
    digitalWrite(LED1, HIGH);
    Serial.println("LED1 on");
  }
  if (x == 2) { //blink LED1
    unsigned long currentMillis = millis();
    if (currentMillis - previousMillis >= interval) {
      previousMillis = currentMillis;
      if (ledState == LOW) {
        ledState = HIGH;
      } else {
        ledState = LOW;
      }
      digitalWrite(LED1, ledState);
    }
  }

  if (x == 3) { //turn LED2 on
    digitalWrite(LED1, LOW);
    digitalWrite(LED2, HIGH);
    delay(100);
  }
  if (x == 4) { //blink LED2
    unsigned long currentMillis = millis();
    if (currentMillis - previousMillis >= interval) {
      previousMillis = currentMillis;
      if (ledState == LOW) {
        ledState = HIGH;
      } else {
        ledState = LOW;
      }
      digitalWrite(LED2, ledState);
    }
  }
  if (x == 5) { //turn LED3 on
    digitalWrite(LED2, LOW);
    digitalWrite(LED3, HIGH);
  }
  if (x == 6) { //blink LED3
    unsigned long currentMillis = millis();
    if (currentMillis - previousMillis >= interval) {
      previousMillis = currentMillis;
      if (ledState == LOW) {
        ledState = HIGH;
      } else {
        ledState = LOW;
      }
      digitalWrite(LED3, ledState);
    }
  }
  if (x == 7) { //turn LED1 nad 2 on
    digitalWrite(LED3, LOW);
    digitalWrite(LED1, HIGH);
    digitalWrite(LED2, HIGH);
  }
  if (x == 8) { //Blink LED1 and 2
    digitalWrite(LED1, LOW);
    digitalWrite(LED2, LOW);
  }
  if (x == 9) { //turn LED2 and 3 on
    digitalWrite(LED1, LOW);
    digitalWrite(LED2, LOW);

    digitalWrite(LED2, HIGH);
    digitalWrite(LED3, HIGH);
  }
  unsigned long currentMillis = millis();
  delay(100);
}

// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany)
{
  while (1 < Wire.available()) // loop through all but the last
  {
    char c = Wire.read(); // receive byte as a character
    Serial.print(c, BIN);     // print the character as Binary
  }
  x = Wire.read();    // receive byte as an integer
  Serial.println(x, BIN); // print the integer as Binary
}

Note, that I changed the type of x to uint8_t, an unsigned int of 8 bits. Restricting x to 8 bits prevents problems with writing a variable inside an ISR. The Uno has an 8-bit microcontroller, so it handles 8 bits at a time. int has 16 bits and is thus handled in two steps. An interrupt can occur at any time, so the ISR might write x in the middle of a calculation, which results in a totally garbled value of x. Handling a 1 byte/8 bits variable cannot be interrupted (also called "atomic") and prevents this issue.

Thanks for your response. I tried to put all the of statements into the loop, but it's still not working. :P I have no idea how to put it into the loop so it works.

@Marvinm You can add your new code to your question by editing it. Then I can check it for errors

I'am sorry for beeing so pushy, but I really need this code in about one day. I will give you a little credit as well. If you can solve this problem.

Then add your new code to your question. Then I can help you

I don't understand.

You wrote, that you tried to put all the if statements in the loop, but it was not working. That means, that you actually have tried it and created a new version of your code, where you've put all the if statements into the loop function. You should add this code to your question by editing it

There it is. Hope that helps

@Marvinm I added an extra explanation.

Also I edited your question, so that both the old and the new code can be seen. That way others have the chance to also get help from this Q&A.

Thanks soo much, you are a legend, can u leave you mail for PayPal here. Thanks.

You are welcome :) Nope, I'm not doing this for money. You can upvote my answer, if you like


text:
Typedef struct not working
I made this simple code but I'm getting the following error
exit status 1
'RGB' does not name a type

typedef struct
RGB
{
        double r;
        double g;
        double b;
};

RGB led;

RGB func(){
  RGB temp;
  return RGB;
}

I am not getting the error on "RGB led" but just on the function.
Does anyone know a solution for this? Thanks!

The typedef syntax is "typedef [known type] [new name];" so RGB would go after the closing brace of the structure definition. Or see @edgarbonet's post for another alternative.

In plain C, structs are identified by "struc tags", which do not live in
the same namespace as type names. Thus, if you declare
struct RGB {
    ...
};

a variable of this type should be declared as
struct RGB led;

In order to avoid the inconvenience of repeatedly typing struct, a
common idiom is to define it as a type:
typedef struct {
    ...
} RGB;

RGB led;

The Arduino environment, however, is based on the C++ programming
language. In C++ struct tags are types, and you thus do not need the
typedef:
struct RGB {
    ...
};

RGB led;

This is the recommended idiom in C++: just remove the typedef.

There are 2 errors:
you are returning a class type, and not the temp object
  RGB func(){
    RGB temp;
    return RGB; --> return temp;
  }

To use your typedef you should put the struct "name" after the braced parenthesis:
typedef struct
{
    double r;
    double g;
    double b;
} RGB;

This works, thanks!


text:
Modifying smart watch or activity armband with further sensors
I want something like an activity armband where I would like to add an bend sensor or EMG sensor for simple hand gesture recognition tasks. I could probably build it from scratch with arduino-like parts, but it will be much more bulky then the ones on the market and I would rather not reinvent those things that already do what I want. This is the type of device I am thinking about.
Is there an feasible task to try to modify an existing activity armband or smart watch by adding one of these sensors? If so, do you have any suggestions of what should be considered? Should I try something completely different? I am open to ideas.
I have a background in Physics and Computer Science with an basic understanding of electronic devices but I am eager to learn.

there are a few DIY, open source armband or watch models like :
https://www.tindie.com/products/ttgo/t-wristband-diy-programmable-smart-bracelet/
which has the sources and tutorials on :
https://github.com/Xinyuan-LilyGO/LilyGO-T-Wristband
it's based on ESP32 and is Arduino ready.the space constraint may not allow for adding a new sensor, but it already comes with a few onboard sensors.
after getting along with ESP32 and the TTGO libraries (which are all provided by the manufacturer LilyGo) that wouldn't be too hard to design a custom band.


text:
Stm32 Blue Pill Internal ADC Voltage Reference Configuration
I am programming an STM32F103C8T6 Board in Arduino IDE. I want to change the value of the internal Voltage Reference for the ADC. How can I achieve this in Arduino ide?

What do you mean you want to change the value? The value is 1.2V. That's not something you can change. Do you mean you want to use the internal reference voltage? Or that you want to use some other external voltage as the reference voltage?

unlike AVRs, stm32 internal voltage reference can't be used as a measurement max reference. it's there just for application calibration. your reference only depends on the VDDA pin and  1) it has to be always connected to a supply and 2) must be between 2~3.6V

I want to change change the internal reference voltage, to something else other than the 1.2 v fixed reference. Like in avr microcontrollers, there is an external adc voltage reference pin for setting the reference voltage. Thats all.

Which Arduino? The IDE is an interface to lots of chips, and they will have different ways of setting the ADC reference voltage.


text:
Creating a router with ESP32 and SIM800c
I am trying to create a device which is a combination of ESP32 and Sim800c.
This device (Master) will start AP mode on ESP32, so that other devices (Nodes) will connect to this AP. The Sim800c will provide 2G internet connection to the ESP32.
The nodes will be executing a HTTPS request and via this device (Master) the http request will gets executed and the response will be received via the Master device and again forwarded to the Node.
Basically this device which i am trying to create will act as a WiFi router which provides internet connection to the Nodes.
Hence my question is, will this device work as expected.

yes, such a device should work

@jsotola : thanks for the quick response. i have a query here, you have written should work in your comment. Can u reply with the possible challenges you think will occur.

it is unknown if you have the skill to develop the necessary code

Sure you can write code that will receive a request over WiFi in some format that you specify, then make a HTTPS request over 2G, and send the response back over WiFi. It won't be simple code, and you have to remember that it's the "server" node that has to make the HTTPS request, not the "client" nodes.