body:
I'm relatively new to the world of Arduino, so don't be frustrated if I ask questions that could be silly. This project has a deadline, so any input is appreciated.

THE PROJECT:

I am planning to build a 2WD vehicle, with an arm using 2 servos, and a TCS3200 color sensor. The goal is to make the robot avoid obstacles while simultaneously searching for a GREEN colored object (using the color sensor). After finding the GREEN object, it would stop and use the robotic claw to grab the object. Finally, it would continue to avoid obstacles until you reach a RED colored area. It would drop the object and start again.

QUESTIONS:

That said, I have some questions about the use of different sensors to control a robot (do not hesitate to put any input that may be useful)

1) How would you connect it to the sensor shield considering the other components? Could you use analog pins or (converting digital to analog) or use fewer pins? (I just need Green and Red)

2) How would make it so that the Arduino receives data from both sensors at the same time? How can I make both sensors control the same two motors?

WIRING:
[![wiring exactly the same][1]][1]
[![bigger image][2]][2]

NOTE: in the second image the ultrasonic sensor should be connected to the bottom right pins

EDIT:
@Peter Paul Kiefer---Could you please elaborate on how I can achieve for both sensors to control the same motors at the same time? Link to website where it is explained?

@jsotola 1) what do you mean by output? 2) I know that, I just want for the Arduino Uno to receive data from both the Ultrasonic and color detection at the same time. Using the data, I want the Arduino to control the motors to avoid obstacles, while using the color sensor to detect the GREEN object(at the same time)

The sensor It is called a TCS3200 color sensor by the way, and seems to only use digital pins. I am connecting it to the sensor sensor shield along with other things. (refer to images in the first post)This is how it looks like:
[![enter image description here][3]][3]

  [1]: https://i.stack.imgur.com/C2PIP.png
  [2]: https://i.stack.imgur.com/P8R2d.jpg
  [3]: https://i.stack.imgur.com/Vt1Ak.jpg

title: Help Needed! How do I attach a color sensor to a 2WD robot and use it to control its movement?

Answers: 0


body:
When using a CIPSEND from an Arduino Uno to a ESP8266 connected to the Uno is there a way to associate the data packet sent with a pathway so it can be retrieved at said pathway from the browser?

For example ESP8266WebServer.h has a command like this:

    server.on(“/specificArgs”, handleSpecificArg);   //Associate the handler function to the path

where the first argument is the path/filename - what's the equivalent of this using using CIPSEND?

title: Multiple data packets with CIPSEND, associate each with pathway

Answers: 1

body:
Your "CIPSEND" is already associated with a path.

The sequence is generally:

1. You configure the ESP8266 as a server, including turning on multiple connections
2. You browse to the IP
3. The browser sends a HTTP request including a path. This has a "channel" number associated with it.
4. You generate a HTTP response and send it to the channel given in 3 using `AT+CIPSEND`.

The fact that you're sending the response to the browser through the channel that the request came in through "associates" the response with the request.

To do different things depending on the path it's up to you to recognise that path in the request and generate a different response accordingly.


body:
I am making a project for school where I have to send data from a sensor to a webpage. After doing some research I decided to use a Real-Time Firebase database. Security is not really important and I want to focus on other aspects of the project, so this seemed like an easy and quick option. I am using a d1 mini (esp8266) and a DHT11 humidity and temp sensor. For libraries I am using DHT, FirebaseArduino and ESP8266WiFi. The code is:
```
#include <ESP8266WiFi.h>                                                    // esp8266 library
#include <FirebaseArduino.h>                                                // firebase library
#include <DHT.h>                                                            // dht11 temperature and humidity sensor library

#define FIREBASE_HOST "xx"                   // the project name address from firebase id
#define FIREBASE_AUTH "xx"            // the secret key generated from firebase

#define WIFI_SSID "xx"                                             // input your home or public wifi name
#define WIFI_PASSWORD "xx"                                        //password of wifi ssid

#define DHTPIN D5                                                           // what digital pin we're connected to
#define DHTTYPE DHT11                                                       // select dht type as DHT 11 or DHT22
DHT dht(DHTPIN, DHTTYPE);

void setup() {
  Serial.begin(9600);
  delay(1000);
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);                                     //try to connect with wifi
  Serial.print("Connecting to ");
  Serial.print(WIFI_SSID);
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(500);
  }
  Serial.println();
  Serial.print("Connected to ");
  Serial.println(WIFI_SSID);
  Serial.print("IP Address is : ");
  Serial.println(WiFi.localIP());                                            //print local IP address
  Firebase.begin(FIREBASE_HOST, FIREBASE_AUTH);                              // connect to firebase
  dht.begin();                                                               //Start reading dht sensor
}

void loop() {
  float h = dht.readHumidity();                                              // Reading temperature or humidity takes about 250 milliseconds!
  float t = dht.readTemperature();                                           // Read temperature as Celsius (the default)

  if (isnan(h) || isnan(t)) {                                                // Check if any reads failed and exit early (to try again).
    Serial.println(F("Failed to read from DHT sensor!"));
    return;
  }

  Serial.print("Humidity: ");  Serial.print(h);
  String fireHumid = String(h) + String("%");                                         //convert integer humidity to string humidity
  Serial.print("%  Temperature: ");  Serial.print(t);  Serial.println("°C ");
  String fireTemp = String(t) + String("°C");                                                     //convert integer temperature to string temperature
  delay(4000);

  Firebase.pushString("Humidity/", fireHumid);                                       //setup path and send readings
  Firebase.pushString("Temperature/", fireTemp);                                //setup path and send readings

}
```

replaced some 'sensitive' information with "xx". When running this code, it connects to my wifi connection and shows data from the DHT11 in the serial monitor. However NOTHING changes in Firebase. After enabling the feature to display extensive feedback/errors in the serial monitor, I noticed it's displaying this:
```
[HTTP-Client][begin] host: https://testtesttest-bd679.firebaseio.com/ port: 443 url: /Temperature/.json?auth=xxxx httpsFingerprint: 03 D6 42 23 03 D1 0C 06 73 F7 E2 BD 29 47 13 C3 22 71 37 1B
[HTTP-Client][sendRequest] type: 'POST' redirCount: 0
[HTTP-Client] failed connect to https://xxx-xxx.firebaseio.com/:443
[HTTP-Client][returnError] error(-1): connection refused
[HTTP-Client][returnError] error(-4): not connected
[HTTP-Client][end] tcp is closed
Humidity: 43.00%  Temperature: 22.50°C
```

I have tried the following things:

* Using a different version of the FirebaseArduino library (5.13.x (still using this one))
* Manually updating the fingerprint of the FirebaseArduino library (see current fingerprint in 2nd code section above)
* Using different versions of the Arduino IDE, using 1.8.12 now

And some other minor changes like creating a new Firebase Database or using something different from pushString to add data to the database.

None of this helped and I am running out of time for my project, hope someone here knows what's wrong and can help me out! :)

title: Arduino Firebase connection refused error

Answers: 1

body:
You added a `/` to the end of the Humidity and Temperature collections.
e.g
    Firebase.pushString("Humidity/", fireHumid);
    Firebase.pushString("Temperature/", fireTemp);

The firebase API translates it to an address

    https://testtesttest-bd679.firebaseio.com/Temperature/.json?auth=xxxx`

as we can see in the output.

I'm pretty sure the correct address is `...Temperature.json...` and not `...Temperature/.json...`.

Please try to remove the slashes from the end of the collection names in the `pushString` statements..

    Firebase.pushString("Humidity", fireHumid);
    Firebase.pushString("Temperature", fireTemp);

If this does not help, it is possibly a problem with the auth string or the Host name. e.g trailing or leading space characters or something like that.


body:
I'm trying to play a tone (on an Arduino Mega through the tone library) and have the tone not be interrupted if an interrupt routine is called while the tone is playing. I'm not sure it's possible. The code block is below. Relevant functionality is:

-A while loop runs indefinitely until Button S1 is pressed. Pressing Button S1 triggers an interrupt routine in which interruptFlag_s1 is set to 1.

-This starts a tone playing for 300ms.

-There's a possibility that another button press interrupt is triggered during the 300ms tone. This interrupts the tone for about 0.5ms, enough to make a perceptible break in the tone that I'd like to avoid.

-Ideal scenario is that the audible tone isn't interrupted by the interrupt routine.

```
    while (restart == 0) {
      if (interruptFlag_s1 == 1 || interruptFlag_s2 == 1) {
        if (interruptFlag_s1 == 1) {
          primary_sensor = 1;
          interruptFlag_s1 = 0;
          rBot = false;
          gBot = true;
          bBot = false;
        } else if (interruptFlag_s2 == 1) {
          primary_sensor = 2;
          interruptFlag_s2 = 0;
          rBot = false;
          gBot = false;
          bBot = true;
        }

        interruptFlag_rtc = 0;
        finish_id = 0;
        button_flag = 0;
        time_diff = 0.00;
        alt_finish_time = 0.00;
        tone(speakerPin, 3000, 300); // Start tone
        restart = 1;
      }
    }
```

title: Continue playing sound during interrupt routine

Answers: 1

body:
The sound is itself generated by an interrupt routine. Since only one interrupt routine can happen at a time, if your own interrupt routine takes too long, then you will get interruption in the sound.

There is nothing you can do about that other than making your interrupt routine short enough that it doesn't cause any interruption in the sound.


body:
I have a motion sensor that triggers an LED and buzzer. That part works fine and it displays Motion detected in the serial monitor. I'm trying to get the LCD to print that as well but I can't get it to work. The LCD backlight turns on but that's it. At first I tried with the LCD16x2 I2C and now I'm trying with the regular LCD16x2. Here's my code:

    #include <LiquidCrystal.h>

    const int MOTION_SENSOR_PIN = 7;   // Arduino pin connected to the OUTPUT pin of motion sensor
    const int BUZZER_PIN        = 3;   // Arduino pin connected to Buzzer's pincon
    int motionStateCurrent      = LOW; // current  state of motion sensor's pin
    int motionStatePrevious     = LOW; // previous state of motion sensor's pin
    LiquidCrystal lcd(12, 11, 6, 5, 4, 2);

    void setup() {
      Serial.begin(9600);                // initialize serial
      pinMode(MOTION_SENSOR_PIN, INPUT); // set arduino pin to input mode
      pinMode(BUZZER_PIN, OUTPUT);          // set arduino pin to output mode
      lcd.begin(16, 2);
      lcd.setCursor(0, 0);
    }

    void loop() {
      motionStatePrevious = motionStateCurrent;            // store old state
      motionStateCurrent  = digitalRead(MOTION_SENSOR_PIN); // read new state

      if (motionStatePrevious == LOW && motionStateCurrent == HIGH) { // pin state change: LOW -> HIGH
        Serial.println("Motion detected!");
        if (Serial.available()) {
          delay(0);
          lcd.clear();
          while (Serial.available() >0) {
             lcd.print("Motion detected!");
          }
        }
        digitalWrite(BUZZER_PIN, HIGH); // turn on
      }
      else
      if (motionStatePrevious == HIGH && motionStateCurrent == LOW) { // pin state change: HIGH -> LOW
        Serial.println("Motion stopped!");
        if (Serial.available() > 0) {
          delay(0);
          lcd.clear();
          while (Serial.available()) {
             lcd.print("Motion stopped!");
          }
        }
        digitalWrite(BUZZER_PIN, LOW);  // turn off
      }
    }

title: Help printing Serial Monitor to LCD16x2

Answers: 0


body:
So I have a small problem with my Arduino Pro Mini here. May be worth noting that it is a clone, but otherwise this is still some weird functionality. I have done some experimenting so I'll just set the scene for you. I have everything that requires power connected to the + and - lines on my breadboard, that way I can avoid drawing more than about 20mA across any individual pins. I currently have my Arduino Pro Mini hooked up to the 5V power supply via the RAW and GND pins, but the supply is a regulated 5v wall supply. It actually is currently outputting 5.36V.

I have made sure all my pins I'm using for output are indeed set as output, the problem only arises when I attempt to power the device from something OTHER than USB power. I tested the output from my wall adapter connected to RAW and to a random VCC pin, both have the same effect.

When powering the device via USB (USB to Deek-Robot ASP, then to Pro Mini), if I set my digital output pin to HIGH, I get 5v. This is enough to turn on a 5v relay that then supplies power from the supply to a small water pump. However, if I use the regulated wall-power, I get about 3.7 to MAYBE 4.15v, which sadly is not enough to switch the relay to the NO position.

I have tested the voltage coming from the USB ASP as well, it is 4.95v.

EDIT: The wall-plug voltage drops from 5.36 with no load except the meter to 4.7v with the Arduino and a couple LEDs attached, if that means anything.

title: 5V on HIGH Digital Pins, Only While Using USB Power

Answers: 2

body: Power supply was dropping to 3.8 volts under basic load, once it turned on some LEDs it was just too low to activate the relay switch. Crappy Chinese parts.

body:
"Arduino Pro Mini hooked up to the 5V power supply via the RAW and GND pins, but the supply is a regulated 5v wall supply. "

That is the problem. RAW pin expects more like 6V to 6.5V for the regulator to output 5V.

If you are supplying 5V, connect to the 5V, or VCC and GND pins.

If you are connecting to USB via an  FTDI Basic or equivalent, and the 5V supply at the same time, then the computer may not like having the USB 5V line back driven from an external source (mine complains about a "power surge" and shuts down the USB port). Make up a breakout cable between the FTDI and the Promini and either disconnect the 5V line, or put a diode in series so the Promini can't supply 5V back thru the FTDI and into the USB port.  That way the FTDI chip is powered from USB, but the Promini is not, and all the hardware is happy.

Make sure to use series resistors with LEDs to avoid overcurrent from the Promini output pin, which will either damage the IO pin, possibly damaging the 328P, or damaging the LED from overheating from excess current.  (5.36V - 2.2V)/.02A = 156 ohm. A 180 ohm, 220, 270, 330, some value in that range will do. 1K will probably be fine, LEDs these days can be quite bright even at lower current; 20mA can be blindingly/annoyingly bright.


body:
I noticed that if I have two SSD1306 displays, the 128x32 display will lose every other row if written in x64 mode, and the 128x64 display will show blank horizontal lines if written in x32 mode. How does this physically work, and can I expect this to be a reliable feature?

I would have thought that half the screen would get cut off somehow, but it appears that it must interlace the data instead (which seems a lot more complicated). Yet there's also some sort of configuration to the driver chip to make it do this (It seems to be the 0xDA command, but I'm not clear how/why it has these options).

Can I expect that, at least if I use the same driver library, that using the wrong screen will always have this behavior? I was planning to use it to help the user detect what screen they have.

title: How does the ssd1306 handle different screen sizes?

Answers: 1

body:
The SSD1306 does not handle different sizes, it's ever only handling it's maximum size 128x64. But one can decide to only use less pins of the driver for a smaller display.

The SSD1306 has 128 segment pins, which activate the current column, so that the states of the 64 common signal pins will be used by the display for that column. For smaller display sizes there are just some pins of the SSD1306 left unconnected. They get set like all the other pins, but they are not connected to anything, thus the information gets lost.

For accommodating that, the library sets the pixel according to the size by not using every second row (aka common signal) for half size displays. That's why you get horizontal black lines, when using a 128x64 display with the library in 128x32 mode. The library thinks, that every second row is not connected either way and thus sets these pixels to black. The 128x32 display is loosing every second row when used with the library in 128x64 mode, because every second row is not connected.

Note, that nor the library neither the SSD1306 know about how the display is connected. You need to tell the library this, by setting the mode, and it will control the SSD1306 accordingly. So there is no feedback about the display, that you could use.

> Can I expect that, at least if I use the same driver library, that using the wrong screen will always have this behavior?

Yes and no. The library handles it this way, because it is the common way to leave out every second pin for displays of half size. But it comes down to the manufacturer to decide this. We cannot guarantee, that nobody will ever connect the SSD1306 in a different way to a display.

For most manufacturers you will be good. If you simply plan to provide the displays for your user, so that they can change them their selves, you can be sure. If the user should be able to use her/his own display, purchased anywhere else, you might run into problems (though rarely).


body:
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.

title: How to create large progmem arrays and not annoy the linker

Answers: 1

body:
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.


body:
    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.

title: This code gives the wrong output. Why?

Answers: 2

body:
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() {}

body:
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);
    }


body:
    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.

title: How is this code working?? val3 is defined as constant

Answers: 2

body:
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!

body:
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.


body:
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][1]

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)

  [1]: https://github.com/bolderflight/MPU9250

title: How can I declare custom pins when using with ESP8266 in MPU9250 library

Answers: 1

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


body:
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.

title: MIDI Keyboard control

Answers: 2

body:
> 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.

body:
- 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.


body:
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("----------------------------------------");
      }
    }

title: Detecting the stop of execution of a timer interrupt

Answers: 0


body:
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][1]

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 ?

  [1]: https://github.com/rogerclarkmelbourne/Arduino_STM32/blob/master/STM32F1/system/libmaple/include/libmaple/timer.h#L595

title: Function pointers that call one function

Answers: 1

body:
`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.


body:
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).

title: Displaying multiple effects in Fast LED

Answers: 1

body:
I'd take a look at [Mark Kriegsmans FastLED example "DemoReel100"][1]. 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 :)

  [1]: https://github.com/FastLED/FastLED/blob/master/examples/DemoReel100/DemoReel100.ino


body:
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 0 correct, but I'm pretty sure that it's not the correct names of boards.

title: Where to find the attribution name for a certain board?

Answers: 2

body:
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][1] 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.

  [1]: https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5:-Library-specification#working-with-multiple-architectures

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

  [1]: https://github.com/rogerclarkmelbourne/Arduino_STM32/tree/master/STM32F1/variants/maple_mini


body:
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!

title: 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?

Answers: 1

body:
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;
       }


body:
<!-- Begin schematic: In order to preserve an editable schematic, please
     don't edit this section directly.
     Click the "edit" link below the image in the preview instead. -->

![schematic](https://i.stack.imgur.com/pAHdO.png)

<!-- End schematic -->

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:
[![enter image description here][1]][1]

```c++
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);
}
```

  [1]: https://i.stack.imgur.com/a3rjW.png

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

Answers: 0


body:
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);
    }

title: Serial.print array displays nothing

Answers: 1

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


body: 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 <dan.drown.org/stm32duino/package_STM32duino_index.json>. I use Arduino IDE for programming STM32F103C8T6

title: delayMicroseconds not working on STM32F103C8T6

Answers: 1

body:
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/


body:
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();
    }

title: Display a Random Number to Display for T Seconds With Millis() for Dice Roller

Answers: 2

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

  [1]: https://github.com/JChristensen/JC_Button

body:
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();
      }


body:
I recently bought a [L3GD20H Triple-Axis Gyro][1] 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.

  [1]: https://www.adafruit.com/product/1032

title: Help reading orientation from gyroscope

Answers: 1

body:
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/


body: 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.

title: Make phone call over 4G LTE

Answers: 1

body:
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](http://mt-system.ru/sites/default/files/documents/sim7000_hardware_design_v1.05.pdf):

> 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.


body:
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][1] 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;
  }
```

  [1]: https://github.com/bartoszbielawski/LEDMatrixDriver/blob/master/examples/MarqueeText/MarqueeText.ino

title: Scroll Left to Right on MAX7219 Display

Answers: 1

body:
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.


body:
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:
[![figura][1]][1]
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?

  [1]: https://i.stack.imgur.com/t7Sak.png

title: analogReference(INTERNAL) configuration

Answers: 1

body:
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.


body: 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?

title: Pca9685 & WS2818B, 1 Nano

Answers: 1

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

  [1]: https://www.tme.eu/Document/ddc250a349c0084fadc3ded4c327f335/WS2818B.pdf


body:
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.

title: How to use I2S in ESP boards?

Answers: 1

body:
Few months ago I tested successfully I2S with [this library][1], 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.

  [1]: https://github.com/earlephilhower/ESP8266Audio


body:
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.

title: How to decrease a variable every second

Answers: 3

body:
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:

```c++
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:

```c++
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:

```c++
if (millis() - time_1 >= INTERVAL_MESSAGE1) {
    time_1 = millis();
    ... etc ...
}
```

body:
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

body:
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);
        }
      }
    }


body:
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](https://www.esp32.com/viewtopic.php?f=19&t=14682&sid=b2acf337a80e803849127e85a16bbe33  "ESP32 Arduino BluetoothSerial Max Speed").

```
void dataFormat(record r){
  serialBtPrint_dur = micros();
  char msg[20];
  sprintf(msg,"ddd",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);
  }
}

```
[![duration for each fuction call of dataFormat in us][1]][1]

  [1]: https://i.stack.imgur.com/o7mat.jpg

title: ESP32 Bluetooth SPP Max Speed

Answers: 1

body: 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.


body:
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

}

title: Blink not working

Answers: 1

body:
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.


body:
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!

title: Typedef struct not working

Answers: 2

body:
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;

body:
In plain C, structs are identified by "struc tags", which do not live in
the same namespace as type names. Thus, if you declare

```c++
struct RGB {
    ...
};
```

a variable of this type should be declared as

```c++
struct RGB led;
```

In order to avoid the inconvenience of repeatedly typing `struct`, a
common idiom is to define it as a type:

```c++
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:

```c++
struct RGB {
    ...
};

RGB led;
```

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


body:
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][1] 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.

  [1]: https://www.semanticscholar.org/paper/Exploring-the-Potential-of-Wrist-Worn-Gesture-Liu/17d44e5e303e78f261578e7ccb010048a2aaecad

title: Modifying smart watch or activity armband with further sensors

Answers: 1

body:
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.