# Question
Title: How can I declare custom pins when using with ESP8266 in MPU9250 library
I want to declare SCL and SCK pins like `Wire.begin(sda_pin, scl_pin);` to use with ESP8266 to integrate a MPU 9250/6500 sensor. I can't figure out a way to declare that in this code exaample provided by https://github.com/bolderflight/MPU9250

in the example of the above it has just passed as **Wire** to and created object like `MPU9250 IMU(Wire,0x68);` which was meant to be used with UNO boards(as I think)

And in any case if any of you have seen a library that can be used with the ESP8266 for the MPU 9250/6500 point me on that direction please (I'm trying to get the roll, pitch, yaw)

# Answer
You can use `Wire.pins(sda, scl);` before `IMU.begin();`. `IMU.begin()` then calls `Wire.begin()` without parameters.
> 2 votes

---
Tags: esp8266, i2c, imu
---


# Question
Title: Self made ATMega32U4 board first programming
I'm stepping into Arduino world and decided to build a small board to implement a gamepad. Prior designing the board I tested my firmware on a *Arduino Pro Micro USB* so I decided to make something similar. My board use an **ATMEGA32U4-AU** instead **ATMEGA32U4-MU** because it's simpler to solder. Connecting the board to my PC I noticed a new device named *ATmega32U4* appear between Windows devices this sounds like the board is working. Now the problem is how to program it with the correct bootloader (?) and make it a *real* **Arduino** board. I found some spurious articles about how to make it but I have not a clean idea. Someone can help me? I can share everything you need to focus on the board.

UPDATE ---------------------------------------------------------------------

Before installing Arduino bootloader I tried programming a sample firmware on the board trough Atmel FLIP (successfully). After that I never been able to program the board again (neither trough FLIP or other means)

I connected my board to Arduino ISP and since Windows seems unable to find the correct driver I had to install it manually, after that I tried to install the bootloader trough **Install bootloader** option of Arduino IDE (selecting Arduino ISP as programmer) but I had no success: This's the log:

```
avrdude: Version 6.3-20190619
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2014 Joerg Wunsch

         System wide configuration file is "C:\Users\tux\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino17/etc/avrdude.conf"

         Using Port                    : usb
         Using Programmer              : arduinoisp
avrdude: usbdev_open(): Found USBtinyISP, bus:device: bus-0:\\.\libusb0-0001--0x2341-0x0049
         AVR Part                      : ATmega32U4
         Chip Erase delay              : 9000 us
         PAGEL                         : PD7
         BS2                           : PA0
         RESET disposition             : dedicated
         RETRY pulse                   : SCK
         serial program mode           : yes
         parallel program mode         : yes
         Timeout                       : 200
         StabDelay                     : 100
         CmdexeDelay                   : 25
         SyncLoops                     : 32
         ByteDelay                     : 0
         PollIndex                     : 3
         PollValue                     : 0x53
         Memory Detail                 :

                                  Block Poll               Page                       Polled
           Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           eeprom        65    20     4    0 no       1024    4      0  9000  9000 0x00 0x00
           flash         65     6   128    0 yes     32768  128    256  4500  4500 0x00 0x00
           lfuse          0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
           hfuse          0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
           efuse          0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
           lock           0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
           calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00
           signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00

         Programmer Type : USBtiny
         Description     : Arduino ISP Programmer
avrdude: programmer operation not supported

avrdude: Using SCK period of 10 usec
avrdude: initialization failed, rc=-1
         Double check connections and try again, or use -F to override
         this check.

avrdude done.  Thank you.

Error during bootloader writing.

```

---

I can clearly see that my firmware is not running when I start the booloader process (probably because it reset the board). From the log it seems that everything is going correctly until: *programmer operation not supported*

What does it means? Is the programmer unable to program such chip? How can I fix this? If I reset my board prior trying to burn again a new firmware over it will it work or I just have to put a brand new micro on it?

Best regards, Mike

# Answer
> 0 votes
The problem was a wrong MISO connection given by a bugged ATMega32U4 footprint.

---
Tags: usb, bootloader, arduino-pro-micro, arduinoisp
---


title: MIDI Keyboard control

text:
# Question
Title: MIDI Keyboard control
I am relatively new to Arduino and I am looking to implement a simple system that uses a MIDI keyboard to

(i) detect key presses (via MIDI messages) from the keyboard

(ii) store the information of the MIDI messages (note pressed, velocity)

(iii) Light up LEDS on the keyboard based on what key was pressed

I am currently in the planning stage and I am considering using an Arduino Mega. I have two issues I am not sure about:

(i) My keyboard only has a Male USB A to Male USB B connection with the former connecting to the computer and the latter to the keyboard. So far in my search, I have seen that all Arduino-MIDI projects require a 5 pin MIDI cable to interface with the Arduino using the circuit in this webpage (https://www.instructables.com/id/Send-and-Receive-MIDI-with-Arduino/). Is there any way to detect MIDI messages that does not require the additional circuit and just uses the USB cable?

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

One way I thought of avoiding these problems is to use MATLAB MIDI package (https://uk.mathworks.com/help/audio/ug/midi-device-interface.html#mw\_80dc54f4-867c-43c0-a159-e56ee62ec4ab) to interface with the MIDI device and use the MATLAB Arduino package to control the Arduino. I am not sure, however, if MATLAB is suboptimal compared to the standard Arduino IDE.

This is my first question in Arduino StackExchange (or any StackExchange site), so I appreciate the answers and feedback on my question.

# Answer
> 0 votes
> 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.

# Answer
> 0 votes
* 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.

---
Tags: midi
---


# Question
Title: How does the ssd1306 handle different screen sizes?
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.

# Answer
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).
> 0 votes

---
Tags: display, ssd1306, oled
---


# Question
Title: Why does the serial monitor output show some unidentified symbols?
```
#define LED 13
#define BAUDRATE 9600
#define DEBUGOUTPUT 0
#define LED 13
#define powercontrol 10

// checksum variables
byte generatedChecksum = 0;
byte checksum = 0;
int payloadLength = 0;
byte payloadData[64] = {0};
byte poorQuality = 0;
byte attention = 0;
byte meditation = 0;

// system variables
long lastReceivedPacket = 0;
boolean bigPacket = false;

//////////////////////////
// Microprocessor Setup //
//////////////////////////
void setup() {
  pinMode(LED, OUTPUT);
  Serial.begin(BAUDRATE); // USB
}

////////////////////////////////
// Read data from Serial UART //
////////////////////////////////
byte ReadOneByte() {
  int ByteRead;
  while(!Serial.available());
  ByteRead = Serial.read();
  #if DEBUGOUTPUT
  Serial.print((char)ByteRead);
  // echo the same byte out the USB serial (for debug purposes)
  #endif
  return ByteRead;
}

/////////////
//MAIN LOOP//
/////////////
void loop() {
  // Look for sync bytes
  if(ReadOneByte() == 170) {
    if(ReadOneByte() == 170) {
      payloadLength = ReadOneByte();
      if(payloadLength > 169)
      //Payload length can not be greater than 169
        return;
      generatedChecksum = 0;
      for(int i = 0; i < payloadLength; i++) {
        payloadData[i] = ReadOneByte();
        //Read payload into memory
        generatedChecksum += payloadData[i];
      }
      checksum = ReadOneByte();
      //Read checksum byte from stream
      generatedChecksum = 255 - generatedChecksum;
      //Take one's complement of generated checksum
      if(checksum == generatedChecksum) {
        poorQuality = 200;
        attention = 0;
        meditation = 0;
        for(int i = 0; i < payloadLength; i++) {
          // Parse the payload
          switch (payloadData[i]) {
            case 2:
              i++;
              poorQuality = payloadData[i];
              bigPacket = true;
              break;
            case 4:
              i++;
              attention = payloadData[i];
              break;
            case 5:
              i++;
              meditation = payloadData[i];
              break;
            case 0x80:
              i = i + 3;
              break;
            case 0x83:
              i = i + 25;
              break;
            default:
              break;
          } // switch
        } // for loop

        #if !DEBUGOUTPUT
        // *** Add your code here ***
        if(bigPacket) {
          if(poorQuality == 0) digitalWrite(LED, HIGH);
          else digitalWrite(LED, LOW);
          Serial.print("PoorQuality: ");
          Serial.print(poorQuality, DEC);
          Serial.print(" Attention: ");
          Serial.print(attention, DEC);
          Serial.print(" Time since last packet: ");
          Serial.print(millis() - lastReceivedPacket, DEC);
          lastReceivedPacket = millis();
          Serial.print("\n");
          switch(attention / 10) {
            digitalWrite(LED, HIGH);
            digitalWrite(LED, LOW);
          }
        }
        #endif
        bigPacket = false;
      } else {
        // Checksum Error
      } // end if else for checksum
    } // end if read 0xAA byte
  } // end if read 0xAA byte
}

```

# Answer
> 2 votes
It time to start stroking our crystal balls, what symbols?

Actually it doesn't really matter, `ReadOneByte()` is the cause, you are printing `ByteRead` without checking that it is printable. Character greater than 127 will look strange when you print them out, only 32-126 are printable (127 is backspace) see http://www.asciitable.com/ for more details. In this case I would print the value as a hex number, `Serial.println(ByteRead, HEX);`

If you are still getting symbols after changing that there may be other prints that have the same problem

# Answer
> 0 votes
select the same serial **Baudrate** in the select which is in the bellow of the serial monitor window as you have put in the code.

---
Tags: serial
---


# Question
Title: Include Git tag (or SVN revision) in Arduino sketch?
Is there any way to get the current Git tag/commit identifier into an Arduino sketch binary?

For normal desktop program development, you can pull some tricks with the Makefile (as pointed out in this StackExchange answer). However, there is no Makefile for an Arduino sketch. Right?

I could make a batch file that I run before every compile, but there is the very real possibility I will forget to run it, and incorrect version information is worse than no version information.

At the moment, I am using the preprocessor macros `__DATE__` and `__TIME__` to try and identify what version is running on the board. This works, but tracking backwards from a compile date/time to a source control commit is more guesswork than anything.

# Answer
Inspired by Cellie's answer, I investigated further and found a similar method that can be implemented using the regular interface of the Arduino IDE.

It appears that GitHub user Wackerbarth, while facing the very same problem, opened an issue on the Arduino bug tracker:

> It would be very useful to be able to add a recipe to the platform specification that is executed at the start of the build process. (pre-build)
>
> In particular, my use case is to generate version strings which will be incorporated in the Rom image based on information extracted from a SCM repository.

He went on to submit a pull request for adding “hooks” to the build process, which made it to release 1.6.2. See the documentation on these Pre and post build hooks.

Here is how you can use this feature for including git commit information into your program (tested on Arduino 1.8.5 / Ubuntu 16.04):

1. Save the following file under the name `make-git-version`, somewhere in your `PATH`, and make it executable:

```
#!/bin/bash

# Go to the source directory.
[ -n "$1" ] && cd "$1" || exit 1

# Build a version string with git.
version=$(git describe --tags --always --dirty 2> /dev/null)

# If this is not a git repository, fallback to the compilation date.
[ -n "$version" ] || version=$(date -I)

# Save this in git-version.h.
echo "#define GIT_VERSION \"$version\"" > $2/sketch/git-version.h

```
2. Locate the file named `platform.txt` in the Arduino installation directory (currently in `arduino-1.8.5/hardware/arduino/avr` for the AVR boards). In the same directory, create a file named `platform.local.txt` with the following content:

```
recipe.hooks.sketch.prebuild.1.pattern=make-git-version "{build.source.path}" "{build.path}"

```
3. In your sketch, include `"git-version.h"` and use it like so:

```
#include "git-version.h"

void setup() {
  Serial.begin(9600);
  Serial.println("This is version " GIT_VERSION);
}

```
4. Create an empty file in your sketch directory named `git-version.h`.

Note that the `git-version.h` in the current directory is only needed for the first compilation. The real `git-version.h` will be in the temporary build directory.
> 2 votes

# Answer
I struggled with Arduino (ESP32) versioning also. To make it somewhat more practical and less error prone I made some scripts to assist this process.

Using these scripts is as easy as adding them to your sketch folder and adding

```
#include "gitTagVersion.h"
...
Serial.println( sketchVersion );

```

to your Arduino sketch. That is all that is needed.

The output in the example above will be something like v1.0.0-3-gab3fb04.
That breaks down to tag `v1.0.0`, we had `3` commits since that tag, at commit `ab3fb04`.

HOW TO INSTALL AND USE?

There are 2 scripts involved, the first script is a replacement for the Arduino Verify button. Save it as verify.sh:

```
echo "const char * sketchVersion = \"$(git describe --tags --always --dirty)\";" > gitTagVersion.h
~/arduino-1.8.5/arduino --verify test.ino
rm gitTagVersion.h

```

And the second script replaces the Upload button. Save it as upload.sh:

```
echo "const char * sketchVersion = \"$(git describe --tags --always --dirty)\";" > gitTagVersion.h
~/arduino-1.8.5/arduino --upload test.ino --pref custom_DebugLevel=esp32_none
rm gitTagVersion.h

```

Some things to note about these scripts:

* The scripts REPLACE the buttons. You won’t be able to use the buttons anymore, as these buttons don’t generate the necessary version info from git.

Using them will result in this error:

> fatal error: gitTagVersion.h: No such file or directory
* The scripts are hardcoded to use Arduino 1.8.5 and have to be updated if you update your Arduino IDE.
* These script only work in Linux with a vanilla Arduino install.
* If you use Windows, or are on a Mac the scripts will not work.
* To change the debug output (using the LOGx\_ESP macros) on ESP32 builds, change the custom\_DebugLevel in the Upload script to esp32\_xxxx, where xxxx is none, info, error, debug or verbose.

I posted this also on my blog and esp32.com
> 3 votes

# Answer
If you're using Platformio, add this in platformio.ini file

```
build_flags =
    !echo '-D GIT_VERSION=\\"'$(git rev-parse HEAD)'\\"'

```

And use it like this:

```
Serial.printf("Firmware version: %s\n", GIT_VERSION);

```

Check out relevant docs: http://docs.platformio.org/en/latest/projectconf/section\_env\_build.html#dynamic-build-flags
> 2 votes

# Answer
I met the same problem and based on the previous answers I wrote this script for Arduino IDE. I'm using it successfully on different OSs for many months to now. In the repository, you can find the instructions to install it.
> 2 votes

# Answer
I'm not sure what the commit ID would prove. I use git for source control for my Arduino sketches, but a particular upload might be halfway between the previous commit and the next one. That is, the code on the board might not match any particular commit.

The date/time would at least identify approximately where in the commit stream the code is.

A possibility would be to run a cron job that periodically (say, every minute) updates a .h file with the current commit ID from the branch, and include that in the sketch.
> 1 votes

# Answer
Inspired by Edgar's Bash script, I wrote a Windows **Batch** script do almost the same in adition to copying HEX file from the temp build directory to the project directory and insert commit hash, date, branch name and tag to it's name. I wrote a short article on how to use GIT to manage firmware versions.

```
:: How to use:
:: Add this file to you Arduino project directory and add the following line to platform.txt from Arduino core files
:: recipe.hooks.sketch.prebuild.1.pattern = {build.source.path}\fw_ver.bat GIT {build.path} {build.source.path}
:: recipe.hooks.objcopy.postobjcopy.2.pattern = {build.source.path}\fw_ver.bat SAVE {build.path} {build.source.path}

@echo off

:: arg1 -> "GIT" print version, commit number, brnach name and commit date , "SAVE" copy the .hex file from temp build directory to project directory
set arg1=%1
:: arg2 -> path to temp build directory
set arg2=%2
:: arg3 -> path to project source files
set arg3=%3

cd %arg3%

FOR /F "tokens=* USEBACKQ" %%F IN (`git describe --match^=NeVeRmAtCh --always --abbrev^=7`) DO (
SET commit=%%F
)

FOR /F "tokens=* USEBACKQ" %%F IN (`git show -s --format^=%%cd --date^=format:%%y_%%m_%%d %commit%`) DO (
SET date=%%F
)

FOR /F "tokens=* USEBACKQ" %%F IN (`git rev-parse --abbrev-ref HEAD`) DO (
SET branch=%%F
)

FOR /F "tokens=* USEBACKQ" %%F IN (`git describe --abbrev^=0`) DO (
SET ver=%%F
)
::Export to version.h
ECHO #define FW_VER "%ver%" > version.h
ECHO #define COMMIT_NUMBER "%commit%" >> version.h
ECHO #define COMMIT_DATE "%date%" >> version.h
ECHO #define COMMIT_BRANCH "%branch%" >> version.h

IF "%arg1%"=="GIT" (
@echo on
@echo version:%ver% Commit:%commit% Branch:%branch% Date:%date%
@echo off
)
IF "%arg1%"=="SAVE" (
@echo on
@echo Save fw_%ver%_%branch%_%date%_%commit%.hex to %arg3%
COPY "%arg2%\fw.ino.hex" "fw_%ver%_%branch%_%date%_%commit%.hex"
)

```
> 1 votes

# Answer
If you want to do Makefile-like tricks, one possibility is to use a Makefile-based workflow instead of the Arduino IDE. There are a few generic Arduino Makefiles floating around the Web. One quite popular is Sudar Muthu's Arduino Makefile. With it, you just write a small per-project Makefile that sets a few variables and then includes the generic Makefile. There is one limitation with this approach though: the Arduino IDE normally modifies your .ino file before submitting it to the compiler, in two ways:

1. It #includes \<Arduino.h\>
2. It writes prototypes near the beginning of the program for every function you define.

Sudar Muthu's Makefile does include Arduino.h (it does not touch your code, using instead the `-include` gcc option), but it does *not* write the function prototypes for you. It is thus not 100% compatible with the Arduino IDE.

Another possibility would be to completely write yourself a Makefile that calls Arduino Builder. This should be 100% compatible with the IDE.
> 0 votes

---
Tags: programming, sketch, version-control
---


title: This code gives the wrong output. Why?

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

void loop()
{}

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

```

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

# Answer
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() {}

```
> 2 votes

# Answer
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);
}

```
> 1 votes

---
Tags: arduino-uno
---


# Question
Title: Function pointers that call one function
I'm reading a library file `timer.h` for STM core library that I just installed in Arduino hardware folder.

Of course, there has to be a lot of questions for me as a beginner about many approaches/stratgegies that programmers rule in writing the code.

One thing is that calling a function with a function pointer that only call one function, but the difference is that the function pointer is declared/defined as an inline function.

---

Edit: I deleted the code and posted a link for it in github.

stm32/timer header file

OK, the part that I started to think about starts from line 595.

It's functions declarations.

In line 598, it's a declaration for a function that receiver a pointer to a function.

In later lines, starting from line 634, these functions have only one line to execute. So my question is why to develop a function to only execute one line ?

Why they didn't just put that line directly instead of putting it inside function ?

# Answer
> 2 votes
`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.

---
Tags: pointer, core-libraries, functions, stm32
---


title: Displaying multiple effects in Fast LED

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

EDIT:

Here is my code:

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

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

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

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

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

```

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

# Answer
I'd take a look at Mark Kriegsmans FastLED example "DemoReel100". This example shows how to delegate to multiple functions.

First, I'll explain that example a bit: You set up an array of function pointers plus a variable for the current index.

```
typedef void (*SimplePatternList[])();
SimplePatternList gPatterns = { rainbow, rainbowWithGlitter, confetti, sinelon, juggle, bpm };
uint8_t gCurrentPatternNumber = 0;

```

All the functions (`rainbow`, `juggle`, etc) just need to work on your `leds[]` array that you gave to `FastLED.addLeds()` in your `setup()` -- I assume that your functions already fulfill that requirement. But: All functions must have the same argument list (in this case: they must be defined like `void rainbow() { leds[x] = CHSV(a,b,c); }`), so you might need to wrap them in another function.

Then, in your loop, you call your effect functions like this while calling `nextPattern()` every 10 seconds:

```
void loop()
{
  // Call the current pattern function once, updating the 'leds' array
  gPatterns[gCurrentPatternNumber]();

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

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

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

```

`EVERY_N_SECONDS` is a macro defined in the FastLED library; it basically does what you did with `currentMillis`, `previousMillis` and `interval` (There's also `EVERY_N_MILLISECONDS` and some other related macros).

That's the example so far, now we need to work with differing "effect switch times".

The easiest method in code would be to find the greatest common factor of all switch times -- let's say you want the `rainbow()` effect to last for 10 seconds, the `juggle()` effect for 15 and the `bpm()` effect for 5 seconds. All those switch times are a multiple of 5, so we put that as the switch delay: `EVERY_N_SECONDS(5)`. Now, to get higher runtimes, we just put those functions multiple times into the array:

```
SimplePatternList gPatterns = { rainbow, rainbow, juggle, juggle, juggle, bpm };

```

There's another way, which gives you the option of setting the effect durations directly. First, we need an array of durations of the same length than our effect function array and a variable to remember where we are in the durations:

```
SimplePatternList gPatterns = { rainbow, juggle, bpm };
int[] gPatternDurations = { 10, 13, 73 };
int effectDurationLeft = gPatternDurations[0];

```

Then, we reduce the "effect switch resolution" down to 1 second and put a bit of logic around the `nextPattern()` call:

```
  EVERY_N_SECONDS( 1 ) {
    if( effectDurationLeft == 0 ) {
      nextPattern();
      effectDurationLeft = gPatternDurations[gCurrentPatternNumber];
    } else {
      effectDurationLeft -= 1;
    }
  }

```

Now you could set your pattern durations by editing the `gPatternDurations` array.

Please be aware that I did not test the code above. Syntax Errors may occur :)
> 1 votes

---
Tags: led
---


# Question
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?
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!

# Answer
> 2 votes
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;
   }

```

---
Tags: button, switch, arduino-esplora
---


# Question
Title: Where to find the attribution name for a certain board?
I'm working on lcd128x64 spi library. And was working with my Arduino Atmega328p chip.

Now I want to run the code with my maple mini board too. So I have to specify the name on the pins for each chip board. But I want to learn the basics of how to write these statements.

Could you tell me where to find the attributions for each board ?

For now I want to define the pin names for the Atmega328p and maple mini. This is my intention:

```
#if defined(__AVR_ATmega328P__)
    #define CS_PIN                  10
    #define MOSI_PIN                11
    #define CLK_PIN                 13
#elif defined(STM32_SERIES_F1)
    #define CS_PIN                  PB12
    #define MOSI_PIN                PB15
    #define CLK_PIN                 PB13
#endif

```

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

# Answer
The Arduino defines to identify a board are in form of `ARDUINO_<board>`, where `<board>` is the value from `<x>.build.board` from boards.txt for board `<x>`

For example for Arduino AVR boards, in the boards.txt file is `uno.build.board=AVR_UNO` so the define is `ARDUINO_AVR_UNO`.

And Arduino has 'architecture' identification define too. This has form of `ARDUINO_ARCH_<arch.name>`. The `<arch.name>` is the uppercase version of the folder name with the boards package version. For example AVR for packages/arduino/hardware/avr/1.6.21.
> 2 votes

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

---
Tags: arduino-uno, stm32
---


# Question
Title: How long should TinyMPU6050.h calibration run for?
I just found a lightweight library for the MPU6050 gyro. Example below. mpu.Calibrate() never seems to end. I'm keeping it very still. When I take this out, the rest of the code works fine.

https://github.com/gabriel-milan/TinyMPU6050/blob/master/examples/ArduinoIDE\_All\_Gets\_Example/ArduinoIDE\_All\_Gets\_Example.ino

# Answer
I feel so sorry about the previous releases of TinyMPU6050. I've just released v0.5.0 that shall soon be available at the Arduino Library Manager index.

The calibration method indeed was messy, so I decided to keep it simple. I also removed dependencies of String objects and Serial stuff and it seems to work pretty fine now.

If you keep having issues with that, please let me know!

The official link to release 0.5.0 follows: https://github.com/gabriel-milan/TinyMPU6050/releases/tag/0.5.0
> 1 votes

---
Tags: mpu6050
---


title: Serial.print array displays nothing

text:
# Question
Title: Serial.print array displays nothing
I tried Serial.print an array I had made, but the Arduino displays nothing in the monitor.

I tried doing Serial.print("Hehehe"); as a test, but it just displayed "h?h?h?".

The monitor works fine with other sketches than this one.

Anyone knows why?

```
int my_array[10];

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

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

  }
}

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

```

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

---
Tags: programming, debugging
---


title: Make phone call over 4G LTE

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

# Answer
> 0 votes
The SIM7000 doesn't have a microphone or speaker pin. Instead it provides a PCM interface to connect to an external CODEC chip.

As it says in the Hardware Design Manual:

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

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

---
Tags: gsm
---


title: Increasing ESP32 AP max connections

text:
# Question
Title: Increasing ESP32 AP max connections
It has already been asked how many clients can connect to an ESP32 AP, but the answer is far from clear; the best one is from a year and half ago (ESP32 AP max connections: 4 or 10?) :

> The answer is as clear as any other EspressIf configuration data, it is 4 or maybe 5, or 8, or 12, 16 or even 20 (the same as a ESP8266!)

As I'm trying to move a project from the ESP8266 because it does not have enough AP connections, two questions can be asked :

1. what is the maximum number of AP connections supported by the 4.0 ESP-IDF framework ?
2. can it be increased in any way ?

Thank you.

# Answer
> 2 votes
After some extensive testing with several modules (not just blindly trusting the documentation), here's what I found.

Short answer : **maximum 10 AP connections** for the ESP32 running ESP-IDF 4.0 (updated around 1st of march 2020), and **no, it can't be increased** (easily).

Details :

* The maximum number of AP connections is defined somewhere in libnet80211, and can't be modified since I have no access to the source code.
* when the 11th station tries to connect, libnet80211 prints `I (39682043) wifi: max connection, deauth!`, more or less like the ESP8266 for the 5th station
* Changine the `ESP_WIFI_MAX_CONN_NUM` (defined in esp\_wifi\_types.h:258) from 10 to anything else ends up in unpredictable behavior (I'm labelling this as unpredictable since without the libnet80211 code, it can't be reliably assessed).

I'm not giving up on increasing the number of stations yet, so maybe there'll be an update to this answer.

# Answer
> 0 votes
According to the documentation:

> `uint8_t max_connection`
>
> Max number of stations allowed to connect in, default 4, max 4

The WiFi interface and AP can support up to 10 connections in its internal structures, but that is only practical for WiFi Mesh usage (which doesn't use all 7 layers of the ISO model), and for actual WiFi station connections, which entails the allocation of far more resources (IP addresses, ARP tables, etc) only a maximum of 4 are supported.

If you need more connections I suggest you invest in a *real* access point / router which can deal with the network management for you (i.e., an access point or router which can do the DHCP and other networking housekeeping for you, leaving your ESP32 free to be a simple station).

---
Tags: esp32
---


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

# Answer
> -1 votes
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/

---
Tags: stm32
---


title: Scroll Left to Right on MAX7219 Display

text:
# Question
Title: Scroll Left to Right on MAX7219 Display
For scrolling from `left to right` (**Arabic** letters) I need a function to print **words/sentences** on the MAX7219 display. \[By `setpixel(x, y)` function\]

I did a lot of searching and my efforts failed. I found the following example but I couldn't change it. By default this example scrolls from `right to left`. (I need scroll from left to right.)

```
#include <LEDMatrixDriver.hpp>
const uint8_t LEDMATRIX_CS_PIN = 9;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    // reset column mask
    mask = B10000000;
  }

```

# Answer
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.
> 3 votes

---
Tags: arduino-uno, string, display, max7219
---


title: analogReference(INTERNAL) configuration

text:
# Question
Title: analogReference(INTERNAL) configuration
I need some help because I did not understand the configuration analogReference(INTERNAL). I would measure the intensity of a Laser beam passing through a filter. This is the circuit I would implement, using the 3.3 V power supply:  In order to rise up the resolution of the system, I would use the 1.1 V power supply (Arduino Uno) to feed the sensor, keeping the Laser power supply at 5 V. In the analogReference(EXTERNAL) configuration shown in the schematic, the sensor is powered by the 3V3 pin, which is connected to the AREF pin. How should I change the circuit in analogReference(INTERNAL) configuration?

# Answer
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.
> 3 votes

---
Tags: arduino-uno, analogreference
---


title: Help reading orientation from gyroscope

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

```
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_L3GD20_U.h>

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

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

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

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

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

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

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

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

```

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

# Answer
> 2 votes
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/

---
Tags: gyroscope
---


title: Pca9685 & WS2818B, 1 Nano

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

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

---
Tags: arduino-nano, i2c, servo, led-strip
---


title: How to use I2S in ESP boards?

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

# Answer
Few months ago I tested successfully I2S with this library, I used the default pins:

```
bck_io_num = 26
ws_io_num = 25
data_out_num = 22

```

which are available on many boards such as Lolin D32.
> 1 votes

---
Tags: esp32
---


# Question
Title: Not able to control DC motor speed with l298N & pwm pins
I am using arduino uno to control dc motor speed with L298N. But the problem is that the motor is only going at max speed. PWM pin doesn't work for some reason. I heard many people had some problem but haven't found the solution yet.

code:-

```
#include <L298N.h>

#define ENA 9
#define IN1 8
#define IN2 7

L298N motor(ENA, IN1, IN2);

void setup() {
// Setup pin mode

//used for display information
  Serial.begin(9600);

}

void loop() {
//Drive Motor Forward
  motor.setSpeed(10);
  motor.forward();
  delay(500);
  motor.setSpeed(100);
  motor.forward();
  delay(500);
  motor.setSpeed(255);
  motor.forward();
  delay(500);

}

```

I only see the motor move at full speed every time. I connected 5V of Arduino to +12V pin of motor driver and Arduino is powered with my laptop USB.

I am using 4.5V toy dc motor for test - DC motor

What could be wrong here?

# Answer
Modifying the library code file L298N.cpp. Insert 2 lines in setSpeed():

```
void L298N::setSpeed(unsigned short pwmVal)
{ _pwmVal = pwmVal;
  if (_ismoving == true)                   // +++
    analogWrite(_pinEnable, _pwmVal);      // +++
}

```

Problem solved!
> 1 votes

# Answer
Try to use this code, without the library, and be sure to connect every pin to the correct Arduino output. If everything is okay it should work. Check the tutorial here

```
int IN3 = 5;
int IN4 = 4;
int ENB = 3;
void setup()
{
 pinMode (ENB, OUTPUT);
 pinMode (IN3, OUTPUT);
 pinMode (IN4, OUTPUT);
}
void loop()
{

  digitalWrite (IN3, HIGH);
  digitalWrite (IN4, LOW);
  analogWrite(ENB,55);
  delay(2000);
  analogWrite(ENB,105);
  delay(2000);
  analogWrite(ENB,255);
  delay(2000);
  analogWrite(ENB,0);
  delay(5000);
}

```
> 1 votes

---
Tags: arduino-uno, pwm, l298n
---


title: Blink not working

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

```
// Wire Slave Receiver

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

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

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

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

}

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

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

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

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

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

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

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

}

```

---

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

```
// Wire Slave Receiver

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

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

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

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

}

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

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

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

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

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

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

}

```

# Answer
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.
> 0 votes

---
Tags: arduino-uno, led
---


title: Typedef struct not working

text:
# Question
Title: Typedef struct not working
I made this simple code but I'm getting the following error

```
exit status 1
'RGB' does not name a type

```

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

RGB led;

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

```

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

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

```
struct RGB {
    ...
};

```

a variable of this type should be declared as

```
struct RGB led;

```

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

```
typedef struct {
    ...
} RGB;

RGB led;

```

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

```
struct RGB {
    ...
};

RGB led;

```

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

# Answer
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;

```
> 1 votes

---
Tags: esp8266, struct, typedef
---


# Question
Title: Modifying smart watch or activity armband with further sensors
I want something like an activity armband where I would like to add an bend sensor or EMG sensor for simple hand gesture recognition tasks. I could probably build it from scratch with arduino-like parts, but it will be much more bulky then the ones on the market and I would rather not reinvent those things that already do what I want. This is the type of device I am thinking about.

Is there an feasible task to try to modify an existing activity armband or smart watch by adding one of these sensors? If so, do you have any suggestions of what should be considered? Should I try something completely different? I am open to ideas. I have a background in Physics and Computer Science with an basic understanding of electronic devices but I am eager to learn.

# Answer
> 3 votes
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.

---
Tags: sensors
---


title: PCF8575c changes address in I2C Scanner

text:
# Question
Title: PCF8575c changes address in I2C Scanner
I want to connect a PCF8575c pin extender to an ESP32, so that I can light 12 LEDs. The problem is that after the connection, when I try to use an I2C Scanner, it shows me a lot of different addresses, not a constant one. Could this happen from a pin fault? I am using this library: https://github.com/xreef/PCF8575\_library

Also, the I2C scanner can be found here: https://playground.arduino.cc/Main/I2cScanner/

And the pins that I use for the LEDs are defined this way:

```
  pcf8575.pinMode(P0, OUTPUT);
  pcf8575.pinMode(P1, OUTPUT);
  pcf8575.pinMode(P2, OUTPUT);
  pcf8575.pinMode(P3, OUTPUT);
  pcf8575.pinMode(P5, OUTPUT);
  pcf8575.pinMode(P6, OUTPUT);
  pcf8575.pinMode(P11, OUTPUT);
  pcf8575.pinMode(P12, OUTPUT);
  pcf8575.pinMode(P14, OUTPUT);
  pcf8575.pinMode(P15, OUTPUT);
  pcf8575.pinMode(P16, OUTPUT);
  pcf8575.pinMode(P17, OUTPUT);

```

The link to the exact PCF8575c: https://www.aliexpress.com/item/2038559527.html?spm=a2g0o.productlist.0.0.3f8331ebu0zuwr&algo\_pvid=5e9fc157-a422-4847-acf4-8618a2d365ea&algo\_expid=5e9fc157-a422-4847-acf4-8618a2d365ea-2&btsid=0ab6f82415840969999872503e3228&ws\_ab\_test=searchweb0\_0,searchweb201602\_,searchweb201603\_

# Answer
Look at the back of the module. There are 3 groups of 3 solder pads each, marked with A0, A1 and A2. With these pads you can set the 3 least significant bits of the address.

On the images in your product link these pads are unconnected. The middle pin is the address pin. The left pad (which is connected to a trace) is Vcc, the right pad (which is connected to the big trace area) is ground. By connecting the middle pad with ground, you set the address bit to zero. By connecting it to Vcc, you set it to 1.

As the pads are unconnected, the address pins are floating. In that state, the pin is reacting to random electrical noise, thus changing state randomly. So also the address changes randomly.

You need to connect every address pin to either ground or Vcc by adding a solder bridge to the pads.
> 1 votes

---
Tags: led, esp32
---


# Question
Title: Is it possible to connect a 36 pin 4 digit 7 segment display on an Arduino Uno R3?
First of all,here's the datasheet of the 4 digit 7 segment display that I'm using: http://www.kingbrightusa.com/images/catalog/SPEC/ca56-11ewa.pdf

How can I make a counter or a clock out of this particular led display,considering the fact that I don't have enough digital pins to manipulate led's pins?

# Answer
Only need 4, or 5 pins; SCK (D13), MOSI (D11), slave select (D10). Maybe PWM (D9) for brightness. D12 not used, but is tied up as part of SPI bus.

Connect the Anodes to +5.

Connect the cathodes, with a current limit resistor per cathode, to the outputs of 4 TPIC6C595, or TPIC6B595.

For the resistor, assume worst case voltage drop of 2V and 20mA current draw: (5V - 2V)/.02A = 150 phm.

Use a PWM output pin to drive the OE/ pin of the '595s for brightness control.

Then shift data into the daisychained shift registers as an update is needed.

```
byte dataMap[] = {
0b00111111, // 0 with bits representing DP,g,f,e,d,c,b,a
0b00000110, // 1
0b01011011, // 2
// etc
};

```

where segments are layed at as

```
   a
f     b
   g
e     c
   d      DP or colon

```

then call the array in loop(), make it a function if you want.

```
digitalWrite (ssPin, LOW); // D10 on Uno, used as Latch signal
for (x = 0; x <4; x=x+1){
SPI.transfer (mapArray[digit0]); // digit0 value mapped to segments
SPI.transfer (mapArray[digit1]);
SPI.transfer (mapArray[digit2]);
SPI.transfer (mapArray[digit3]);
}
digitalWrite (ssPin, LOW); // outputs update on this rising edge

```

I wonder where DP5, DP6, which make the colon, are? I don't see them in the pinout.
> 2 votes

# Answer
As Juraj mentioned, you can use shift registers, such as 74HC595 which uses the SPI protocol.

To elaborate slightly on this:

* You can cascade 4 shift registers, totaling 32 pins for output
* If you need 36, you can use the remaining 4 as normal pins (this is probably the easiest solution)
* Or you can use the Chip/Slave Select feature of SPI to control two chains of shift registers. So e.g. one chain is doing 4 * 8 = 32 pins, the other (single shift register) using 8 pins (from where 4 pins are used only).

To make a clock, use a RTC (Real time clock) module/IC, a counter (unless very high frequency) does not need an external IC.
> 0 votes

# Answer
You actually only need 12 pins for that display.

The display is made up of 4 separate common anode LED displays, and you can use that to your advantage.

Since the 4 anode clusters are separate you have the ability to switch an entire digit on or off. And as a result all the cathodes of the segments can be commoned together (that is, the cathodes of all the segment As can be commoned, and the cathodes of all the segment Bs, etc), which is then 8 clusters of 4 cathodes.

That means you can have 4 outputs controlling the for anodes (ideally through PNP transistors or P-channel MOSFETs to handle higher current), and 8 outputs to control all the cathodes (each through a resistor and ideally an NPN transistor or N-channel MOSFET to handle higher current).

The you rapidly switch between each digit displaying the right segment combination for that digit.

Here's a partial example showing 4 digits but just segments A and B. Youd expand this out for segments C through G. GPIO\_A1 to GPIO\_A4 are activated to select which digit is being displayed. GPIO\_CA through GPIO\_CG would be to select the arrangement of segments on that digit.

simulate this circuit – Schematic created using CircuitLab
> 0 votes

---
Tags: arduino-uno, atmega328
---


# Question
Title: Can I use 1-byte datatypes to store digital input?
I am reading the docs on DigitalRead() and wondering why it stores seemingly boolean `HIGH` and `LOW` inputs in `int` data type variable.

I have two issues with that:

1. `int` is 2-byte, while `bool` and `uint8_t` are 1-byte so it seems like a waste of memory for no benefit whatsoever.
2. It gets me confused when reading the code about whether the input came from digital or analog since `int` can have a wide range.

Is there any particular reason for storing digital inputs as `int`?

EDIT: `bool` and `uint8_t` are out of the question as per the answer below. **`int8_t`** still looks suitable for the purpose though.

# Answer
> 4 votes
You receive the data as `int`, but you store it as `byte`.

For example, when you call the serial library function to receive a data byte, the library will return either the data or a -1 if a problem has occurred.

The binary value of -1 is a byte 11111111 or int 1111111111111111.

The binary value of 255 is a byte 11111111 or int 0000000011111111.

I think that you can see the problem if you use `byte` data and the data is 255.

So, if you receive an `int` -1, then you do not process the data. Otherwise you `cast` the `int` to `uint8_t`.

You could receive `byte` data, but then the value of 255 would be undefined.

# Answer
> 2 votes
I did not check the internals a while, but in early days there was a

```
 #define HIGH 1

```

meaning that HIGH is a `const int`.

Perhaps someone did not want to disable some TRI-STATE digital logic in the beginning, and since then nobody wanted to change the basics.

But of course `bool` is a more appropriate data type for HIGH/LOW and of course you can always treat them this way, for example like

```
if (! digitalRead(pin) ) { // pin is LOW
   ...
}

```

---

jsotola's answer why Serial.read() returns an `int` is a different issue. And correct of course.

# Answer
> 1 votes
The smallest unit in most languages is a byte (8 bits), whether signed or unsigned. So returning a byte, even if it only returns three different values, is the smallest and most efficient unit available, that I'm aware of.

If you want to store later, you can assign each bit of a byte as a high or low, thus giving you 8 storage spots.

# Answer
> 0 votes
One could always store the value of digitalRead() as a bit in a variable, compacting the data from say 8 pins down into 1 byte

```
// read an input and store it, say the reads of D2 thru D9 are stored in byte bits9to2
// 9,8,7,6,5,4,3,2
// first clear the state for 2
bits9to2 = bits9to2 && 0b11111110; // two && for bit manipulation? Or just 1?
// then map in the new value
if (digitalRead(D2) == HIGH){
bits9to2 = bits9to2 || 0b00000001;// two || for bit manipulation? Or just 1?
}
else{
// leave it as 0
}

```

Then to use it later on:

```
if ((bits9to2 && 0b00000001) != 0){
// bit is set (HIGH), do whatever
}
else {
// bit is clear (LOW), do whatever, or maybe do nothing
}

```

Can use an unsigned int and store 16 bits compacted that way, or unsigned long for 32 bits.

---
Tags: data-type
---


# Question
Title: Scroll one line of text while another line is static on a SSD1306 OLED
I have an SSD1306 OLED that I have connected to a Wemos D1 Mini. It works like a charm, but I was wondering if it was possible to have two lines of code, where one line is static, and the other one scrolls? No example on the web as far as I have tried to find.

# Answer
> 1 votes
I just found the answer on the following site: https://lastminuteengineers.com/oled-display-arduino-tutorial/

Basically, the method `startscroll*` on the display takes some arguments. By passing the proper start page and stope page you can scroll parts of the screen.

Refer to OLED Memory Map for explanation of the pages on the screen. There are eight pages in the display from 0 to 7, so we can scroll a certain part of the screen by passing specific page numbers as parameters.

In this example, we pass both the parameters as 0x00. This will scoll the first page only (first 8 rows) of the display:

```
// Scroll part of the screen
display.setCursor(0,0);
display.setTextSize(1);
display.println("Scroll");
display.println("some part");
display.println("of the screen.");
display.display();
display.startscrollright(0x00, 0x00);

```

Source: https://lastminuteengineers.com/oled-display-arduino-tutorial/

---
Tags: esp8266, ssd1306
---


# Question
Title: How do I make a proper long string scanner to detect specific tags in a stream of characters?
Here's my code:

```
#include <SoftwareSerial.h>
SoftwareSerial BTserial(2, 3); // RX, TX

void setup() {
    Serial.begin(9600);
    BTserial.begin(9600);
    Serial.println("Communication with HC-05 successfully started.");
}

bool is_uploading_book = false;
char c = ' ';
String recv_scanner = "";
void loop(){
    if (BTserial.available()) {
        c = BTserial.read();
        recv_scanner += c;
        if(recv_scanner.length() >= 50) {
          recv_scanner.remove(0, 1);
        }
        // I believe there's something wrong with the recv_scanner.
        if(is_uploading_book) {
          Serial.write(c);
        } else {
          if(recv_scanner.indexOf("(__BOOK_UPLOAD_START__)") >= 0) {
            is_uploading_book = true;
          }
        }
        Serial.println("\n\n" + recv_scanner + "\n\n");
    }
}

```

I'm sending a book (long text) in the form of characters one by one from my phone to my HC-05 module (and the Arduino).
My goal is to spot the tag "(\_BOOK\_UPLOAD\_START\_)" in the incoming characters.
Arduino allows me to receive the characters of the book one by one on each loop.
I'm storing those characters in a string called *recv\_scanner* where I allow it's maximum size to be 50 characters and once it reaches those 50 characters, I start to remove the first character and add a new one on each loop (so it can only see 50 characters at a time because maximum String length is 200 and for my purposes, 50 is enough).
The thing is, it doesn't work properly.
When I Serial.println the *recv\_scanner* on every loop (so I see how it progresses) it starts to look like this:

```
⸮qsnieq⸮cn .laslvanm.⸮⸮⸮d⸮alvuv⸮⸮urosqiam tr⸮⸮⸮

```

(It starts normally and then slowly progresses into this)
I have no idea what that is.
As far as my predictions go, it should show 50 characters and they should be parts of the books.
Is there something fundamental about Strings that I don't know of?
I'm doing this so I'm able to detect a tag (\_BOOK\_UPLOAD\_END\_) at the end of the book and finish uploading.
Feel free to ask my questions if something is unclear.

# Answer
Another option is to not save the characters in buffer but instead check each one as they arrive to see if the character is the next in the tag sequence.

This has the advantage that you don't need a buffer to match the tag and you don't have to repeatedly search for the string in the buffer.

```
const char* TAG_STR="(__BOOK_UPLOAD_START__)";
int tag_pos = 0;
char c;
bool is_uploading_book = false;

void loop() {
  if (BTserial.available()) {
    c = BTserial.read();
    if (is_uploading_book) {
      //do book stuff
    } else {
      if (c == TAG_STR[tag_pos]) {
        // c matched the next character in the string
        tag_pos++;
      } else if (c == TAG_STR[0]) {
        // matched first char in the middle, restart
        tag_pos = 1;
      } else {
        // Did not match the next character so we should start over
        tag_pos = 0;
      }
      // The next character to match is the string terminator
      // so we must have matched the whole string.
      if (TAG_STR[tag_pos] == '\0') {
        is_uploading_book = true;
      }
    }
  }
}

```
> 5 votes

# Answer
I think your problem lies in the usage of the `String` class. Every time, that you concat a `String` variable, a new buffer for the result is allocated in the background via dynamic memory allocation. That can result in heap fragmentation, which eats up your memory pretty fast (especially on the smaller ones, like the Uno).

Instead you should use a `char` array as ring buffer. Let's define the buffer first and initialize it to zero:

```
#define BUFFER_SIZE    50
char buffer[BUFFER_SIZE] = {0};

```

Now we define position variables, where the valid data starts and ends in the buffer:

```
uint8_t buffer_start = 0;
uint8_t buffer_end = 0;

```

When `buffer_start == buffer_end`, the buffer is empty. When `buffer_end` is one position before `buffer_start`, the buffer is full. To put one character into the buffer we do the following (note, that `c` is the same variable, as in your code):

```
if( ((buffer_end + 1) % BUFFER_SIZE) == buffer_start)
{
    buffer_start = (buffer_start + 1) % BUFFER_SIZE;
}
buffer[buffer_end] = c;
buffer_end = (buffer_end+1) % BUFFER_SIZE;

```

What are we doing here? First we need to check, if our buffer is full. We are doing this by comparing `buffer_start` to the next position of your `buffer_end`. The calculation of the new position is where the magic happens. First we increment `buffer_end` by one and then we are taking the modulus with the buffer size. The modulus is the rest of an integer division. When the position is at the end of the `buffer` array, it will be `(49 + 1) % 50`, which is zero. That wraps the array end to the array end for us.

If our buffer is full, then we increment the start counter of the buffer. That means, that we are ditching one character at the start of our buffer to add one at the end (which is what you want to do). (Note, that normally with ring buffers you don't want to throw away data, so you refuse to put more data into the buffer, when it is full).

Then we store the received character into our buffer and increment `buffer_end` like described above.

The above principle is also called circular FIFO buffer (First In First Out), though there are missing some function to a real FIFO buffer, that you don't need here.

---

Now, that we have a ring buffer, which gets filled with the data, we also need to implement a function to find a string in the buffer, meaning an equivalent to the `String.indexOf()` method. It might look something like this:

```
int find_string(char str[], const char search[]){
    uint8_t start = buffer_start;
    uint8_t search_pos = 0;
    uint8_t result_pos = -1;
    while(start != buffer_end){
        if(str[start] == search[search_pos]){
            if(search_pos == 0) result_pos = start;
            search_pos++;
            if(search[search_pos] == '\0') return result_pos;
        } else {
            result_pos = -1;
            search_pos = 0;
        }
        start = (start + 1) % BUFFER_SIZE;
    }
    return -1;
}

```

Note, that this implementation is only roughly tested, not thoroughly.
> 1 votes

---
Tags: bluetooth, hc-05, signal-processing
---


title: Serial communication by bluetooth hc-05

text:
# Question
Title: Serial communication by bluetooth hc-05
i am making a ultrasonic radar using stepper motor and ultrasonic sensor , and displaying the output over a software(processing 3) which looks like a radar ppi on display ...is it possible ot replace the usb cable with a bluetooth connection to send data (serial) instead of using a usb cable i want the setup to be remote ..i am using a instructable https://www.instructables.com/id/Acoustic-Radar-Display/ for coding i just need to know how to make it wireless over bluetooth ...just changing the com over processing 3 works or i need to do some changes in command mode of bluetooth

# Answer
If you use a Bluetooth Module like this, that has an SSP profile, it will show up as COM port on your windows machine.

Now if you want to use the Arduino's Hardware Serial (i.e. keep using Serial.print() but for Bluetooth) then you will connect the module like this:

* Bluetooth HC06 TX to digital pin 0 (Arduino Rx)
* Bluetooth HC06 RX to digital pin 1 (Arduino Tx)

But remember, you load your code using these pins too. Arduino has a "USB-to-Serial" IC on board that uses those two pins. So now two entities trying to use those same pins (U2S and BT) i.e. you will have to disconnect U2S connections:

The above image is a snippet from the Arduino schematic. One way to disconnect those connections is to remove those two resistors. But then again, next time you want to load your code, you won't be able to use USB cable anymore.

So, I will suggest you to use **SoftwareSerial** and choose any other two pins for Bluetooth Module and change in the code wherever you were communicating with the Processing using Serial.println(). replace that with SoftwareSerial println().
> 1 votes

---
Tags: bluetooth, wireless
---