body:
I'm using a gyroscope, which returns angular velocity in floats. I'm trying to use this data with the [arduino mouse library][1]. The move function requires a signed character. I'm not what the best way is to convert the `float` data from the sensor into `signed char`.

In what way can I do this, losing the least in terms of precision?

I found out you can use `dtostrf` to transfer floats into an array of characters, but not sure what to do following this or if it's even the best way.

I would appreciate any guidance.

  [1]: https://www.arduino.cc/reference/en/language/functions/usb/mouse/

title: How to use float data from a sensor with the Arduino mouse library

Answers: 2

body:
The mouse library expects the movement coordinates to be provided as
8-bit signed integers, which corresponds to the `int8_t` data type. This
type is actually an alias to `signed char`, but calling it this way is
confusing, as the word `char` somehow implies a type meant to store
characters, which is definitely not the case here.

Converting a `float` to any integer type can be done by plain
assignment, with two caveats:

* If the float exceeds the range of the integer, the assignment will
  wrap around modulo 2^(integer size in bits). This is undesirable and
  can be prevented by first `constrain()`ing the float to the
  appropriate range.
* The assignment rounds towards zero, whereas rounding to the nearest
  integer is better if you want to minimize the errors. This can be
  achieved with the `round()` macro.

In summary:

```c++
// In global context:
const float scale = 0.4;  // scale factor for mouse moves

// Within loop():
float rotation = get_data_from_gyroscope();
int8_t mouse_move = round(constrain(rotation * scale, -128, +127));
```

Note that the optimal scale can only be determined experimentally: you
have to tweak it until your input device “feels” right.

body:
You are misunderstanding the type `char`. It is named character, because in ASCII representation you can use it to save one character. But internally it just is a number. The Arduino doesn't care, if you save characters in it or numbers, because characters are also numbers for it.

A `signed char`, like the `move()` function of the library uses` has 1 byte and is signed, thus can hold numbers from -128 to 127.

While the documentation is not clear about what the x and y parameters really represent the answer to [this question][1] is clear about it. Basically the whole range from -128 to +127 represents a whole inch (or what the computer thinks is an inch). So this results in a resolution of `1" / (127 - -128) = 1" / 255 = 0.0039"` (or about 0.1mm). I don't know, what values you are getting from the sensor, but you will have to scale it to somewhere in the -128 to 127 range (depends on how sensitive you want it to be). And you won't loose precision here. The sensor values most likely are more precise, than the range of the mouse `move()` function.

The calculation will then be as simple as

    signed char mouse_x = sensor_x * factor + offset;

The result of the calculation will implicitly converted to a 1 byte signed integer (this is what `signed char` is). If you want to make it clearer what happens here, you can also write:

    signed char mouse_x = (signed char)(sensor_x * factor + offset);

This is not needed, but you might wanna do it for clarity.

---

Seen in Edgar Bonets answer: You might wanna contrain the value of above calculation to the -128 to 127 range. If you get an unexpected high value from your sensor, the above calculation would overflow the `mouse_x` variable (not good for correct values). So capping the values to that range with the `constrain()` function is definitely good. Refer to Edgars answer and the documentation for this.

  [1]: https://arduino.stackexchange.com/questions/74757/mouse-move-values


body:
I am trying to create a clock using a ST7789 display and a DS3231 RTC. In this clock I want to use NTP to keep it synced and maybe use the WiFi to anything else.
My problem started when I have tried to use tasks to split the code into pieces, manage priorities and to keep the loop code as clean as possible. When I try to update the display text from a task the ESP32 just crash and reboots.
I have cleaned the code to see where is the problem and I have noticed that the problem comes when I connect to my Router and then I try to update the text in the display, but doesn't fail if the WiFi is not started or I update the text outside the task. The cleaned code I am using is this:

```
#include <WiFi.h>
#include <Adafruit_ST7789.h>

#if CONFIG_FREERTOS_UNICORE
#define ARDUINO_RUNNING_CORE_0 0
#define ARDUINO_RUNNING_CORE_1 0
#else
#define ARDUINO_RUNNING_CORE_0 0
#define ARDUINO_RUNNING_CORE_1 1
#endif

#define TFT_MOSI 23  // SDA Pin on ESP32
#define TFT_SCLK 18  // SCL Pin on ESP32
#define TFT_CS   15  // Chip select control pin
#define TFT_DC    2  // Data Command control pin
#define TFT_RST   4  // Reset pin (could connect to RST pin)

// Colors
#define COLOR_TOP_BG tft.color565(125, 125, 125)
#define COLOR_TL_BG tft.color565(3, 96, 7)
#define COLOR_BL_BG tft.color565(3, 96, 7)
#define COLOR_TR_BG tft.color565(117, 70, 2)
#define COLOR_BR_BG tft.color565(117, 109, 2)

#define COLOR_TOP_TEXT ST77XX_WHITE
#define COLOR_TL_TEXT ST77XX_BLACK
#define COLOR_TL_TEXT ST77XX_BLACK
#define COLOR_TL_TEXT ST77XX_BLACK
#define COLOR_TL_TEXT ST77XX_BLACK

static const char* ssid     = "WIFI_SSID";
static const char* password = "**REDACTED**";

// Initialize Adafruit ST7789 TFT library
Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);

// the setup function runs once when you press reset or power the board
void setup() {

  // initialize serial communication at 115200 bits per second:
  Serial.begin(115200);

  // Now set up two tasks to run independently.
  xTaskCreate(
    updateDateTime,
    "updateDateTime",   // A name just for humans
    1024,  // This stack size can be checked & adjusted by reading the Stack Highwater
    NULL,
    3,  // Priority, with 3 (configMAX_PRIORITIES - 1) being the highest, and 0 being the lowest.
    NULL
  );

  // Connecting to Wifi
   WiFi.begin(ssid, password);

  tft.init(240, 240, SPI_MODE2);    // Init ST7789 display 135x240 pixel
  tft.setRotation(3);
  drawBackground();
}

void loop() {

}

// Function to draw the display background
void drawBackground() {
  tft.fillScreen(0xFFFFFF);
  tft.fillRect(0, 0, 240, 24, COLOR_TOP_BG);
  tft.fillRect(0, 24, 120, 107, COLOR_TL_BG);
  tft.fillRect(0, 133, 120, 107, COLOR_BL_BG);
  tft.fillRect(120, 24, 120, 107, COLOR_TR_BG);
  tft.fillRect(120, 133, 120, 107, COLOR_BR_BG);

  tft.fillRect(0, 22, 240, 4, ST77XX_BLACK);
  tft.fillRect(0, 130, 240, 3, ST77XX_BLACK);
  tft.fillRect(118, 22, 4, 218, ST77XX_BLACK);
}

// Function to update the date/time
void updateDateTime( void * pvParameters ) {
  for( ;; ) {
    //tft.init(240, 240, SPI_MODE2);
    tft.setTextColor(COLOR_TOP_TEXT, COLOR_TOP_BG);
    tft.setCursor(6, 4);
    tft.println("MIE");

    delay(100);
  }
}
```

If I comment the WiFi.begin function or I call the function from loop without create a task or just move the three lines to loop function, it works perfectly.

```
#include <WiFi.h>
#include <Adafruit_ST7789.h>

#if CONFIG_FREERTOS_UNICORE
#define ARDUINO_RUNNING_CORE_0 0
#define ARDUINO_RUNNING_CORE_1 0
#else
#define ARDUINO_RUNNING_CORE_0 0
#define ARDUINO_RUNNING_CORE_1 1
#endif

#define TFT_MOSI 23  // SDA Pin on ESP32
#define TFT_SCLK 18  // SCL Pin on ESP32
#define TFT_CS   15  // Chip select control pin
#define TFT_DC    2  // Data Command control pin
#define TFT_RST   4  // Reset pin (could connect to RST pin)

// Colors
#define COLOR_TOP_BG tft.color565(125, 125, 125)
#define COLOR_TL_BG tft.color565(3, 96, 7)
#define COLOR_BL_BG tft.color565(3, 96, 7)
#define COLOR_TR_BG tft.color565(117, 70, 2)
#define COLOR_BR_BG tft.color565(117, 109, 2)

#define COLOR_TOP_TEXT ST77XX_WHITE
#define COLOR_TL_TEXT ST77XX_BLACK
#define COLOR_TL_TEXT ST77XX_BLACK
#define COLOR_TL_TEXT ST77XX_BLACK
#define COLOR_TL_TEXT ST77XX_BLACK

static const char* ssid     = "WIFI_SSID";
static const char* password = "**REDACTED**";

// Initialize Adafruit ST7789 TFT library
Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);

// the setup function runs once when you press reset or power the board
void setup() {

  // initialize serial communication at 115200 bits per second:
  Serial.begin(115200);

  // Connecting to Wifi
   WiFi.begin(ssid, password);

  tft.init(240, 240, SPI_MODE2);    // Init ST7789 display 135x240 pixel
  tft.setRotation(3);
  drawBackground();
}

void loop() {
  void * test;
  updateDateTime(test);
}

// Function to draw the display background
void drawBackground() {
  tft.fillScreen(0xFFFFFF);
  tft.fillRect(0, 0, 240, 24, COLOR_TOP_BG);
  tft.fillRect(0, 24, 120, 107, COLOR_TL_BG);
  tft.fillRect(0, 133, 120, 107, COLOR_BL_BG);
  tft.fillRect(120, 24, 120, 107, COLOR_TR_BG);
  tft.fillRect(120, 133, 120, 107, COLOR_BR_BG);

  tft.fillRect(0, 22, 240, 4, ST77XX_BLACK);
  tft.fillRect(0, 130, 240, 3, ST77XX_BLACK);
  tft.fillRect(118, 22, 4, 218, ST77XX_BLACK);
}

// Function to update the date/time
void updateDateTime( void * pvParameters ) {
  for( ;; ) {
    //tft.init(240, 240, SPI_MODE2);
    tft.setTextColor(COLOR_TOP_TEXT, COLOR_TOP_BG);
    tft.setCursor(6, 4);
    tft.println("MIE");

    delay(100);
  }
}
```

I am starting with FREERTOS and ESP32, and I am not sure what I am doing wrong... I have thougth that the problem was the RTC but after remove the RTC code and see that was the WiFi, I am not sure what can be the problem.

Best regards and thanks.

title: ESP32 FREERTOS crash using Adafruit ST7789 in tasks with the Wifi enabled

Answers: 1

body:
To pin the function to a core was not working for me surely because the init code is outside the function, so I have moved the init code to inside the function, out of the loop:

```
#include <WiFi.h>
#include <Adafruit_ST7789.h>

#if CONFIG_FREERTOS_UNICORE
#define ARDUINO_RUNNING_CORE_0 0
#define ARDUINO_RUNNING_CORE_1 0
#else
#define ARDUINO_RUNNING_CORE_0 0
#define ARDUINO_RUNNING_CORE_1 1
#endif

#define TFT_MOSI 23  // SDA Pin on ESP32
#define TFT_SCLK 18  // SCL Pin on ESP32
#define TFT_CS   15  // Chip select control pin
#define TFT_DC    2  // Data Command control pin
#define TFT_RST   4  // Reset pin (could connect to RST pin)

// Colors
#define COLOR_TOP_BG tft.color565(125, 125, 125)
#define COLOR_TL_BG tft.color565(3, 96, 7)
#define COLOR_BL_BG tft.color565(3, 96, 7)
#define COLOR_TR_BG tft.color565(117, 70, 2)
#define COLOR_BR_BG tft.color565(117, 109, 2)

#define COLOR_TOP_TEXT ST77XX_WHITE
#define COLOR_TL_TEXT ST77XX_BLACK
#define COLOR_TL_TEXT ST77XX_BLACK
#define COLOR_TL_TEXT ST77XX_BLACK
#define COLOR_TL_TEXT ST77XX_BLACK

static const char* ssid     = "MOVISTAR_F6112";
static const char* password = "C89qlqMifsjDMWhbdsJQ";

// Initialize Adafruit ST7789 TFT library
Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);

// the setup function runs once when you press reset or power the board
void setup() {

  // initialize serial communication at 115200 bits per second:
  Serial.begin(115200);

  xTaskCreatePinnedToCore(
    updateDateTime,   /* Function to implement the task */
    "updateDateTime", /* Name of the task */
    1024,      /* Stack size in words */
    NULL,       /* Task input parameter */
    3,          /* Priority of the task */
    NULL,       /* Task handle. */
    0
  );

  // Connecting to Wifi
   WiFi.begin(ssid, password);

  //tft.init(240, 240, SPI_MODE2);    // Init ST7789 display 135x240 pixel
//  tft.setRotation(3);
//  drawBackground();
}

void loop() {
}

// Function to draw the display background
void drawBackground() {
  tft.fillScreen(0xFFFFFF);
  tft.fillRect(0, 0, 240, 24, COLOR_TOP_BG);
  tft.fillRect(0, 24, 120, 107, COLOR_TL_BG);
  tft.fillRect(0, 133, 120, 107, COLOR_BL_BG);
  tft.fillRect(120, 24, 120, 107, COLOR_TR_BG);
  tft.fillRect(120, 133, 120, 107, COLOR_BR_BG);

  tft.fillRect(0, 22, 240, 4, ST77XX_BLACK);
  tft.fillRect(0, 130, 240, 3, ST77XX_BLACK);
  tft.fillRect(118, 22, 4, 218, ST77XX_BLACK);
}

// Function to update the date/time
void updateDateTime( void * pvParameters ) {
  tft.init(240, 240, SPI_MODE2);
  tft.setRotation(3);
  drawBackground();

  for( ;; ) {
    //tft.init(240, 240, SPI_MODE2);
    tft.setTextColor(COLOR_TOP_TEXT, COLOR_TOP_BG);
    tft.setCursor(6, 4);
    tft.println("MIE");

    delay(100);
  }
}
```

I have kept the function pinned to a core to avoid problems if RTOS decides to run the function on another core later. I have to do more tests, but seems to works.

Best regards.


body: so im using the sabertooth speed controller to control the two motors on my lawn mower and im trying to use the MPU6050 to keep the lawn mower straight. The problem im facing is that im trying to use the sabertooth and the MPU6050 on a single Arduino and the sabertooth uses the baud rate of 9600 but the MPU6050 uses 115200 and im trying to use a single .ino file to control everything. I want to receive the data from the MPU6050 and based of that make a program to move the motor so that the mower will go in a straight line and such.

title: connecting a MPU6050 and sabertooth 2x12 to a single Arduino Uno

Answers: 0


body:
I have tried to burn bootloader onto an atmega 328p chip onto a breadboard using another arduino uno , I am not using an external clock but I am doing all the steps to make this thing which are given on this site - https://create.arduino.cc/projecthub/techmirtz/arduino-without-external-clock-crystal-on-atmega328-d4fcc4
the error code I am receiving is this :

```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\DELL\Desktop\arduino ide\arduino-nightly\hardware\tools\avr/etc/avrdude.conf"

         Using Port                    : COM4
         Using Programmer              : stk500v1
         Overriding Baud Rate          : 19200
         AVR Part                      : ATmega328P
         Chip Erase delay              : 9000 us
         PAGEL                         : PD7
         BS2                           : PC2
         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  3600  3600 0xff 0xff
           flash         65     6   128    0 yes     32768  128    256  4500  4500 0xff 0xff
           lfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           hfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           efuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           lock           0     0     0    0 no          1    0      0  4500  4500 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 : STK500
         Description     : Atmel STK500 Version 1.x firmware
         Hardware Version: 2
         Firmware Version: 1.18
         Topcard         : Unknown
         Vtarget         : 0.0 V
         Varef           : 0.0 V
         Oscillator      : Off
         SCK period      : 0.1 us

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.03s

avrdude: Device signature = 0x000000 (retrying)

Reading | ################################################## | 100% 0.03s

avrdude: Device signature = 0x000000 (retrying)

Error while burning bootloader.
Reading | ################################################## | 100% 0.02s

avrdude: Device signature = 0x000000
avrdude: Yikes!  Invalid device signature.
         Double check connections and try again, or use -F to override
         this check.

avrdude done.  Thank you.```

title: Error message while trying to burn bootloader onto atmega 328p

Answers: 0


body:
Several months ago I developed a device able to detect water flood in a closed space and do some operations in case (closing valves, issuing an acoustic and Bluetooth alarm etc.).

After 8 hours it tries to reopen the valves and restart the normal cycle. Arduino UNO is always in sleeping mode (this device remains active 7/24). It wakes up every minute (@ sec.00) to detect presence of water, checks for 4 cycles (4 minutes) the presence of water -if the sensors are on- and then, after have issued the alarms and closed the valves, it wakes up after 8 hours, in order to reopen the valves and come back in its normal check-mode.

It worked and works flawlessly, when left working on my table. I tried it for almost a month.  The problem raised when I installed it in place, because there is a water pump (an autoclave, of some 1,5Hp, 1 phase), connected on the same power supply line, that -of course- starts whenever somebody opens a water valve at home.

Whenever it starts, Arduino wakes up immediately and the 1 minute (or 8 hours waiting cycle) stops.

* I tried to use several caps on the 12V power supply line (some 3000uF, 50Vl in total) and a EMI filter between the power supply line and my device, but nothing changed.

* I made some mods on the software, checking if the wakeup hour and minute is compatible with the correctly wakeup time calculated and setted on Arduino, and storing an alarm flag with wakeup hour and minute in EEPROM, in order to manage the same check if Arduino undergoes a hardware reset or is turned off/on.

I suspect that the problem raises for the fact that the RTC interrupt is activated when the IRQ pin is lowered from the HIGH state.
There is a way to set the DS3231 to remain in LOW state always, and issue a HIGH level just for the interrupts?

Does anybody have any electrical suggestion? I use this [12V chinese switching UPS/power supply][1] connected to a 12V-7Ah lead battery that assures no interruptions.

  [1]: https://www.amazon.co.uk/CADANIA-SC-120W-12V10A-Switching-Monitor-Battery/dp/B07TDJ1BLF/ref=cm_cr_arp_d_product_top?ie=UTF8

title: Issues with interrupts coming from RTC DS3231 and power supply interference

Answers: 0


body:
I have a 12V 20A Solar Charge Controller (which is part of my existing Solar Panel System Setup connected to a 12V Sealed Lead Acid Battery) that I will use to power up some pumps with the help of relays and some sensors. And because its a solar charge controller, the output varies depending on the sun, from 12.1v to 13.8v (I set the Load Reconnect, Load Disconnect, Float Charge etc which technically 12V to 13.8V)

How do I power my Arduino Mega safely in this case?

I am planning on using a separate buck converter that will give my Arduino a fixed 9V from the Solar Charge Controller.

Should I power the Arduino with the buck converter parallel to the same PSU (the 12V 20A Solar Charge Controller) I'm using for the pumps and is it safe that way?

or

Should I use a 9V battery to separately power the Arduino Mega?  and what is the explanation behind the concept of using an external PSU for the Arduino Mega when the total Amperes all in all is not exceeding the limit 20A at all?

title: Best way to add external power supply when main PSU is a solar charge controller?

Answers: 2

body:
> Should I power the Arduino with the buck converter parallel to the same PSU (the 12V 20A Solar Charge Controller) I'm using for the pumps

Yes. However I wouldn't use a 9V buck regulator, but a 5V one and feed it to the 5V pin. That way you bypass the wasteful LDO on the Arduino, and when running from solar every bit of power saving you can muster helps.

> and is it safe that way?

Yes, it's safe. As long as the buck regulator you are using is rated for the voltages in question.

body:
Ok first, you need a battery for all this to work.  The solar charge controller won't drive into nothin', that is not what they are designed to do.

 Its full name is "solar *battery* charge controller".   Size the battery any way you like, just make sure the charge controller knows what kind it is, so it sets the proper charge curves and doesn't overcharge it/boil it dry/make it catch fire (lithium).

Once you have a battery in the system, paralleling in another battery charger is not a problem, be it wind, AC mains, or another solar CC.

- - -

Now, you will need to manage the case where the Arduino calls for the pump to turn on, but the solar panel is not making enough power to successfully power the pump.  This will not magically sort itself out.

- If you did not have a battery, it'll "crow bar".  The pump would effectively pull the solar voltage to near zero, which would cause the Arduino to shut down, turning off the pump and causing solar voltage to recover.  The Arduino would reboot, try again, and fail again.  Repeating.  So a crow-bar condition.

- If you do have a battery, then the Arduino will successfully spin up the pump, *but*, the solar won't be enough and this will be depleting the battery.  If your usage runs the battery flat, see crow-bar above.

- If you have a battery and the Arduino monitors battery voltage, it can defer operation until the Arduino knows the battery is sufficiently charged for the work needed.  At this point you don't need to care if the solar is up, the battery will carry the "buffer".    Make sure to shut the load off before the battery is depleted enough to create a crow-bar condition.

Note that if the battery is lead-acid, it should be managed to stay within 60-100% state of charge.  Depleting a lead-acid below 60% of max will rapidly age the battery.  It probably will be, since they are a happy intersection of "cheap" and "well-supported by every charge controller ever made".

Power to the Arduino itself should be taken as close as possible to the energy source (e.g. battery) — *even if that means a long, redundant cable, **especially** in that case actually*.  Do not share a supply cable with motors or pumps or other heavy loads!!!  I have seen many installations where the startup current of the motor causes enough *voltage drop* down the shared supply cable to cause the Arduino to lose power and reboot.   That is quickly cured by running a redundant V+ and V- power cable just for the Arduino.


body:
I have recently followed the instructions in the answer to this question:
https://arduino.stackexchange.com/questions/52909/reading-several-rotary-encoders/52926
posted by [maximilian-gerhardt](https://github.com/maxgerhardt)

I've wired everything up, and am using the interrupts example that can be found here:
https://github.com/maxgerhardt/rotary-encoder-over-mcp23017/tree/master/examples/Interrupt

Everything seems to work as expected, except that my assumption was that since this was an interrupt-based solution, that I wouldn't be missing any steps of any of the encoders. There are a total of 5 that will move at the same time, and it is clear that while it *almost* works, there are many steps that are missed.

I'm guessing that is because while one interrupt is being handled, all other interrupts are disabled?

Is there any way where I can ensure that every single motion (step CW or CCW) is registered on all 5 encoders?

Thanks!
Brian

title: Using MCP23017 with 5 rotary encoders, WITHOUT missing a single step from any of them?

Answers: 2

body:
Interrupts don't mean that you can do lots of things at the same time. All they mean is that something can be responded to rapidly, as long as nothing else is being responded to of an equal or higher priority.

And coupling that with an IO expander which will inevitably slow things down means that you really can't do what you are trying to do.

If you want to respond instantly to every single pulse of every single encoder then each encoder has to be attached to something that can itself respond to those pulses.

I would be inclined to have a small microcontroller attached to each individual encoder (or maybe two encoders if you have enough interrupt pins) and deal with each separately - that way one encoder *cannot* interfere with any other. The small MCU can then keep track of position or count (depending on what it is you are trying to do) and you communicate that to a "master" controller (the Arduino for example) over some other bus, asynchronously to the encoder's pulses.

If you want more rapid response to the encoder movements then it could be possible to implement your own interrupt signal from the small MCU to the Arduino to say "My encoder has been moved", at which point the Arduino can collect the data. It won't matter how long that takes to happen as the small MCU will be keeping track of any other changes. The ATTiny85 using Pin Change Interrupts could be a good low-cost choice for this.

body: I would use a different approach. Consider setting a flag when an interrupt occurs, a different flag for each interrupt then processing that in the main loop rather then the ISR (Interrupt Service Routine). Connecting with the SPI  in the 1.7 MHz mode will allow you to get in check the interrupt set the flag and leave the ISR. This will be a bit difficult to write but I think it would work very well. Taking a quick scan of the data sheet the MCP23917 should be the correct part to accomplish this. Also do the debouncing externally, will save a lot of code and speed up the process.


body:
```

#include "Keypad.h"

char Incoming_value = 0;
String password = "123456";
String input = "";
const byte ROWS = 4; //four rows
const byte COLS = 4; //three columns
char keys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};

byte rowPins[ROWS] = {2, 3, 4, 5}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {6,7,8,9}; //connect to the column pinouts of the keypad

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

void setup()
{
  Serial.begin(9600);
  pinMode(13, OUTPUT);
}

void loop()
{
  if (Serial.available() > 0)
  {
    Incoming_value = Serial.read();
    Serial.print(Incoming_value);
    Serial.print("enter value");
    if (Incoming_value == '1') {
      digitalWrite(13, HIGH);
      Serial.print("ON");
    }
    else if (Incoming_value == '0') {
      Serial.print("OFF");
      digitalWrite(13, LOW);
    }
  }
  // Read the pushed button
  char key = keypad.getKey();
  input = input + key;
  // just print the pressed key
  if (key) {
    Serial.println(key);
  }
  if(key == '*' ){
    Serial.println(input);
    if( input == password){
      digitalWrite(13, HIGH);
    }
  }
  if(key == '#'){
    digitalWrite(13, LOW);
    input = "";
  }

/*
  // this checkes if 4 is pressed, then do something. Here  we print the text but you can control something.
  if (key == '4') {
    Serial.println("Key 4 is pressed");
          digitalWrite(13, HIGH);
      Serial.print("ON");
  }
    if (key == '5') {
    Serial.println("Key 5 is pressed");
          digitalWrite(13, LOW);
      Serial.print("ON");
  }
  */
}
```

when print input variable i get strange text like
>⸮⸮⸮⸮⸮⸮⸮;⸮⸮ߵ⸮⸮⸮⸮u⸮⸮⸮⸮⸮⸮?/}⸮⸮⸮⸮⸮⸮~⸮⸮⸮⸮⸮-d

what i can do ?

title: strange strings

Answers: 2

body:
**PS**: @lurker's suggestion in the comments - check the baud rate setting in your serial monitor as well.

**EDIT**: I admit that the code in the previous version of this answer was foolishly typed out by me due to lack of patience, so I'll make up for my mistake(not in code, but as a full answer).

First of all, I didn't understand what you wanted to do with the `Incoming_value` variable in your sketch, so I'm not gonna talk about it; I'd suggest adding a sufficiently small delay at the end of the code in the loop. This should provide the serial port some time to handle the incoming data and stop printing the confusing output (perhaps; just because delays make your microcontroller wait for a while to get things done elsewhere , especially where the reception of data is slow and thus avoid collisions)

Also note that I am not a CS student or an electronics geek, but I am speaking from my guesswork. Any correction is accepted.

body:
First of all you have to make sure, that you select the same baudrate in the Serial Monitor, that you used in your sketch with `Serial.begin()`. This error is very common and garbage values is the symptom of this.

But your code also has problems. You have the `input` variable of type `String`, which should hold the user input for comparison with the password. Directly after getting the key, you are appending this key to the string. You are assuming here, that `keypad.getKey()` is waiting for the user to actually press a key and then return that. But this is not the case. `keypad.getKey()` will return `NO_KEY`, when the user currently isn't pressing a key. This is defined in the `Keypad` library as `'\0'` (the null character), which marks the end of a string. Your code runs very fast, so you are adding more and more null characters to your string. Your strings gets bigger and bigger, filling your RAM very fast.

**How to solve this:** You should only use the return value of `keypad.getKey()`, if a key was actually pressed. Put all the code after it in an if statement, checking for `NO_KEY`:

    // Read the pushed button
    char key = keypad.getKey();
    if(key != NO_KEY){
        input = input + key;
        // just print the pressed key
        if (key) {
            Serial.println(key);
        }
        if(key == '*' ){
            Serial.println(input);
            if( input == password){
                digitalWrite(13, HIGH);
            }
        }
        if(key == '#'){
            digitalWrite(13, LOW);
            input = "";
        }
    }


body:
tl;dr: trying to receive DMX512 (via a RS485 module) on a STM32 and not going well.

I am trying to modify the firmware of a commercial lighting fixture with a STM32F103C8 clone as it's MCU. It basically receives DMX and converts it into a single axis of motion and a lighting fixture with ~24 WS2812B LEDs. Unfortunately, all of the DMX libraries available (DMXSimple2, Conceptinetics) only support avr, and I don't have very much experience with the lower level hardware/library interactions.

I am looking at [this tutorial][1] because it seems easier to modify to work with the STM32, but the tutorial says

> Now just do a search for "ISR(USARTn_RX_vect)" in HardwareSerial.cpp

which I can't find in the [Arduino STM32 core][2].

Can someone help or point me towards resources about how to modify the existing libraries to work for my application?

  [1]: https://playground.arduino.cc/DMX/Ardmx/
  [2]: https://github.com/stm32duino/Arduino_Core_STM32

title: Receiving DMX512 on STM32F103C8

Answers: 0


body:
I have an Arduino setup with a pro-mini, a MSGEQ7, and a auto-gain mic. Even if I remove the audio input to the MSGEQ7 remains the same in the 890s (out of 1024). It's the same on each of two new MSGEQ7. I've checked the schematics, https://www.instructables.com/Music-Sync-Flashing-LEDs-Arduino-MSGEQ7/, multiple times and everything seems in order including components.

I'm using the ```#include <MD_MSGEQ7.h>```, but I've tried it without.

Any ideas?

```
#include <Adafruit_NeoPixel.h>
#include <MD_MSGEQ7.h>

int LEDPIN = 12;
int MODEPIN = 10;

int mode = 0;
int lastState = LOW;

int NUMPIXELS = 50;

int DATA_PIN = 1; // read from multiplexer using Analog Pin 1, MSGEQ7 pin 3
int STROBE_PIN = 2; // MSGEQ7 pin 4
int RESET_PIN = 3; // MSGEQ7 pin 7

int spectrumValue[7];

Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, LEDPIN, NEO_GRB + NEO_KHZ800);
MD_MSGEQ7 MSGEQ7(RESET_PIN, STROBE_PIN, DATA_PIN);

void setup() {

  Serial.begin(9600);
  pinMode(MODEPIN, INPUT);
  pixels.begin();
  MSGEQ7.begin();
}

void loop() {
  int currentState = digitalRead(MODEPIN);

  if (currentState == LOW && lastState == HIGH) {
    mode++;
    if (mode > 2) {
      mode = 0;
    }
  }
  lastState = currentState;

  MSGEQ7.read();

  for (int i = 0; i < 7; i++) {
    Serial.println(MSGEQ7.get(i));
  }
  if (mode == 0) {
    for (int i = 0; i < NUMPIXELS - 1; i++) {
      pixels.setPixelColor(i, pixels.Color(30, 60, 60)); // RGB
    }
  } else if (mode == 1) {/////////////////////////////////////////////////////////
    int height = (NUMPIXELS - 1) * MSGEQ7.get(1) / 1024;
    for (int i = 0; i < NUMPIXELS - 1; i++) {
      if (i < height) {
        pixels.setPixelColor(i, pixels.Color(60, 60, 0)); // RGB
      } else {
        pixels.setPixelColor(i, pixels.Color(0, 0, 0)); // RGB
      }
    }
  } else if (mode == 2) { /////////////////////////////////////////////////////////
    pixels.setPixelColor(0, pixels.Color(120 * MSGEQ7.get(5) / 1024, 0, 0)); // RGB
  }
  pixels.show();
}
```

title: My LED display fails with MSGEQ7 output stuck

Answers: 0


body:
I'm makeing two modules,
module2 gets sensor signal, and send wireless message to module1, with HC-12. Then module1 is going to do some work it is supposed to do. Circuit configuration is in the picture.

I tested HC-12 communication, and they send, receive well. But my problem is that,
when module1 gets turned ON, Interrupt gets activated (LOW) and module2 sends signal that's not supposed to send. It seems it is because of electromagnetic wave noise, from HC-12.

How can I filter this noise, using code ? Now I'm stuck for the last 3 days.

[![enter image description here][1]][1]

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

```code```
Module1

    #include <SimpleTimer.h>

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

    // #define IDlen 4
    #define maxID 5

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        delay(200);
      }
      return;
    }

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

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

```code```Module2

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

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

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

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

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

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

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

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

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

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

      detachInterrupt(0);
      return;
    }

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

title: Dealing with noise in arduino interrupt

Answers: 1

body:
I know, it is not exactly what you asked for, but I recommend hardware filtering. I had problems with noise on interrupts and I was able to solve that with this component: https://www.st.com/content/st_com/en/products/emi-filtering-and-signal-conditioning/integrated-emi-filtering-and-esd-protection/computer-legacy-port-ipad/kbmf.html#overview

It is not expensive and saves you a lot of headache.
If you can't use SMD components, you can rebuild the circuit of that filter with capacitors and resistors, just be sure, that you put the filter as close as possible to the interrupt pin.


body:
I'm basically trying to combine my servo code and my LED code but whenever I add my servo code the LED refuses to turn on at all.
I am super new to arduino sorry if this doesn't make any sense!

``` #include <Servo.h>

Servo myservo;

const int pushbutton_PIN = 2;
const int POT_PIN = A0;
const int LED_PIN = 3;

int pos = 0;
int buttonState = 0;
int lastbuttonState = 0;
int analogValue = 0;
int lightState = false;
int brightness = 0;

void setup() {
  myservo.attach(9);
  pinMode(pushbutton_PIN, INPUT);
  pinMode(POT_PIN, INPUT);
  pinMode(LED_PIN, OUTPUT);
  Serial.begin(9600);
}

void loop(){
  light();
  servo();
  }

void servo(){
        for (pos = 0; pos <= 180; pos += 1) {
    // in steps of 1 degree
    myservo.write(pos);
    delay(15);
  }
  for (pos = 180; pos >= 0; pos -= 1) {
    myservo.write(pos);
    delay(15);
  }
}

void light() {
      buttonState = digitalRead(pushbutton_PIN);
  if (buttonState != lastbuttonState) {
    if (buttonState == HIGH) {
      delay(300);
      lightState = true;
      light_on();
    }
  }
  lastbuttonState = buttonState;
}

void light_on() {
  while (lightState == true) {
    analogValue = analogRead(POT_PIN);
    brightness = map(analogValue, 0, 1023, 0, 255);
    analogWrite(LED_PIN, brightness);
    buttonState = digitalRead(pushbutton_PIN);
    if (buttonState != lastbuttonState) {
      if (buttonState == HIGH) {
        lightState = false;
        delay(300);
        analogWrite(LED_PIN, LOW);
        loop();
      }
    }
    lastbuttonState = buttonState;
  }
}

title: Servo wont work with LED code!

Answers: 0


body:
Code for Master
--------
```c++
#include <Wire.h>

void setup()
{
  Wire.begin();

  Serial.begin(9600);
}

void loop()
{
    Wire.beginTransmission(9);

    Wire.write('c');
    Serial.println('c');
    Wire.write('a');
    Serial.println('a');
    Wire.endTransmission();
}
```

---

In my case `Wire.write('c')` is performing the task which is assigned to `'c'` in slave board.
Then its printing `'c'` in serial monitor as intended.
But, `Wire.write('a')` line is being neglected and nothing happens on slave board.  But again, it's printing `'a'` in serial monitor as per code.
Why is that `Wire.write('a');` is neglected? Both boards are Arduino Nano.

Code for Slave
--------------
```c++
#include <Wire.h>
#define RED 8
#define GREEN 10
int x = 0;

void setup() {
  pinMode (RED, OUTPUT);
  pinMode (GREEN, OUTPUT);
  Wire.begin(9);
  Wire.onReceive(receiveEvent);
}

void receiveEvent(int bytes) {
  x = Wire.read();    // read one character from the I2C
}

void loop() {
    if (x == 'a') {
        digitalWrite(RED, HIGH);
        digitalWrite(GREEN, LOW);
    }
    if (x == 'b') {
        digitalWrite(RED, LOW);
        digitalWrite(GREEN, HIGH);
    }
    if (x == 'c') {
        digitalWrite(RED, HIGH);
        digitalWrite(GREEN, HIGH);
    }
    if (x == 'd') {
        digitalWrite(RED, LOW);
        digitalWrite(GREEN, LOW);
    }
}
```

title: Multiple Wire.write() not working for Arduino Nano I2C

Answers: 1

body:
**Important information:** `Wire.write()` does NOT send anything over the I2C lines. It just puts the data into the libraries internal buffer. The actual transmission is then done by `Wire.endTransmission()`.

I2C is packaged transmission protocol. That means, that the transmission is done in confined data packages. In your master code you are calling `Wire.write()` two times before `Wire.endTransmission()`. That means you are sending 1 package with 2 data bytes in it.

Now for your slave code: You are using a callback function for the `onReceive` event. This callback function is called once per transmission. In there you can read all the data of that transmission. After that the data is thrown away (I think actually it gets deleted, when a new transmission is received). You are only reading once with `Wire.read()`. So you only ever read the first byte of every transmission, which is always the letter `'c'`.

**What to do know?** This depends on how you want the code to behave. Since you are setting 2 LEDs based on the received byte it would be better to only send 1 byte transmissions. For that, you can change your master code. For example like this:

    #include <Wire.h>

    void setup()
    {
      Wire.begin();

      Serial.begin(9600);
    }

    void loop()
    {
        // Send the command c
        Wire.beginTransmission(9);
        Wire.write('c');
        Wire.endTransmission();

        // Wait 1s, so that we can see the LEDs state accordingly
        delay(1000);

        // Send command a
        Wire.beginTransmission(9);
        Wire.write('a');
        Wire.endTransmission();

        // Wait 1s, so that we can see the LEDs state accordingly
        delay(1000);
    }

This code will change between `'c'` and `'a'` every second. You need a delay there to actually see the LEDs light up. Otherwise they would change too fast for you to see it.

**Note:** Actually you need to declare the variable `x` as `volatile`, because the onReceive callback is called from an ISR. With that keyword you are telling the compiler, that `x` can change at any time (by the ISR of the corresponding I2C interrupt). It might be, that your current code works, because the compiler was smart enough to see that, but in general you should always use `volatile` with every variable, that can change in an ISR. Declaration then looks like this:

    volatile int x = 0;

And to handle the ISR data really correct, you would need to make the usage atomic, because the ISR can happen in the middle of the comparison for the if statements. An `int` is two bytes, so the first byte might be updated and the second byte not. That would corrupt your data. There are two ways to handle that in your case:

- **Make the reading of `x` atomic:** Normally one would turn of the interrupts, read the volatile variables into local variables (as a copy) and then turn the interrupts on again. That way the interrupt cannot corrupt the data in the variable during reading. The further calculation/comparison would then be done with the local variable.

- **Use a single byte as volatile data**: The described problem does not apply to variables, which only use 1 byte (since on the 8bit Arduinos like the Nano the reading of a single byte cannot be interrupted). So just make `x` of type `char` (or `uint8_t` or `byte`).

You should use the second option.


body:
I'm working with the following circuit using a NodeMCU: [![schematic][1]][1]

I have the solder jumper bridged between RST and BTN. In addition to what's in the schematic, pins 2, 3, and 4 of J1 are connected to the cathodes of 3 LEDs powered via pin 1 on the same connector.

I'm using the following code to test waking up from deep sleep:

    #include <Arduino.h>

    void setup() {
      delay(1000);
      Serial.begin(9600);
      Serial.println("start");
      ESP.deepSleep(0);
      while (1);
    }

    void loop() {
    }

I build the code with `-DDEBUG_ESP_PORT=Serial -DDEBUG_ESP_CORE` and observe the following behaviour on the serial port after startup:

    SDK:2.2.2-dev(38a443e)/Core:2.7.3-3-g2843a5ac=20703003/lwIP:STABLE-2_1_2_RELEASE/glue:1.2-30-g92add50/BearSSL:5c771be
    start
    bcn 0
    del if1
    usl
    enter deep sleep␀

This looks as expected to me (except maybe for the trailing ␀?). The current consumption is as low as I'd expect from deep sleep. I now pull RST low by pressing the push button once and see a few bits of garbage (different every time) being output in the device monitor - nothing else happens:

    SDK:2.2.2-dev(38a443e)/Core:2.7.3-3-g2843a5ac=20703003/lwIP:STABLE-2_1_2_RELEASE/glue:1.2-30-g92add50/BearSSL:5c771be
    start
    bcn 0
    del if1
    usl
    enter deep sleep␀␀�

At this point current consumption increases from single-digit milliamps to a few tens of milliamps. However, a full reset doesn't seem to happen and my program doesn't appear to execute again from the beginning.

If I now pull RST low again with a second press of the push button I see a bit more garbage being output before a proper reset seems to finally happen:

    SDK:2.2.2-dev(38a443e)/Core:2.7.3-3-g2843a5ac=20703003/lwIP:STABLE-2_1_2_RELEASE/glue:1.2-30-g92add50/BearSSL:5c771be
    start
    bcn 0
    del if1
    usl
    enter deep sleep␀␀�␕{��1S�
    SDK:2.2.2-dev(38a443e)/Core:2.7.3-3-g2843a5ac=20703003/lwIP:STABLE-2_1_2_RELEASE/glue:1.2-30-g92add50/BearSSL:5c771be
    start
    bcn 0
    del if1
    usl
    enter deep sleep␀

This cycle then repeats, always requiring two button presses for a reset.

Similarly, if I try to upload a new program to the ESP8266 after it entered deep sleep initially, the upload will fail with:

    A fatal error occurred: Timed out waiting for packet header
    *** [upload] Error 2

Trying the upload again right after that does succeed. The next upload after that will fail again, and so on.

Based on those observations it looks to me like the ESP8266 doesn't get fully reset on the first button push, or it does get reset but enters some state in which it's not executing my application for some reason.

What could be the reasons for that? Is it something I can work around either in hardware or code?

Thanks!

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

title: ESP8266 requires two resets to wake up from deep sleep

Answers: 0


body:
I'm new to NodeMCU and ESP. I've created a basic web server on my NodeMCU.

The server works fine for the first few minutes after resetting the board or re-uploading code. But after about half an hour, the server just stops responding and becomes unreachable. Funny thing is, after sending a few failed requests, server starts to respond normally again.

The code i'm using:

    #include <ESP8266WiFi.h>
    #include <ESP8266WebServer.h>

    String wifiName = "blablabla";
    String password = "blablabla";

    ESP8266WebServer server(9090);

    void setup() {
      Serial.begin(115200);
      pinMode(5, OUTPUT);
      digitalWrite(5,LOW);

      connectToWifi();
      server.on("/", handleHomepage);
      server.on("/action", handleAction);
      server.begin();
    }

    void loop() {
      server.handleClient();
    }

    void handleHomepage() {
      server.send(200, "text/plain", "Welcome to esp8266 homepage!");
    }

    void handleAction() {
      String parameter = server.arg("value");

      if (parameter == "") {
        server.send(200, "text/plain", "No parameter supplied.");
        return;
      } else {
          if (parameter == "on") {
            digitalWrite(5,HIGH);
          } else if (parameter == "off") {
            digitalWrite(5,LOW);
          }
        server.send(200, "text/plain", "Action received successfully.");
      }
    }

    void connectToWifi() {
      WiFi.mode(WIFI_STA);
      WiFi.begin(wifiName, password);

      // Wait for connection
      while (WiFi.status() != WL_CONNECTED) {
        delay(500);
      }
    }
What should I do to keep the server always active? Thanks in advance.

title: NodeMCU server stops responding after a while

Answers: 0


body:
I'm trying the Android Hce example in this PN532 library. The serial monitor gives me "Didn't find PN53x board". Can someone help me?
```cpp
#if 1
  #include <SPI.h>
  #include <PN532_SPI.h>
  #include "PN532.h"

  // SPI connections
  //GPIO 12   MISO
  //GPIO 13    MOSI
  //GPIO 14    SCK
  //GPIO 15 SS

  PN532_SPI pn532spi(SPI, 15);
  PN532 nfc(pn532spi);
#elif 0
  #include <PN532_HSU.h>
  #include <PN532.h>

  PN532_HSU pn532hsu(Serial1);
  PN532 nfc(pn532hsu);
#else
  #include <Wire.h>
  #include <PN532_I2C.h>
  #include <PN532.h>
#endif

void setup()
{
  Serial.begin(115200);
  Serial.println("-------Peer to Peer HCE--------");

  nfc.begin();

  uint32_t versiondata = nfc.getFirmwareVersion();
  if (! versiondata) {
    Serial.print("Didn't find PN53x board");
    while (1); // halt
  }

        // Got ok data, print it out!
  Serial.print("Found chip PN5"); Serial.println((versiondata>>24) & 0xFF, HEX);
```

title: Pn532 and Node MCU SPI

Answers: 0


body:
Is it possible to kill arduino nano with overload?

I wanted to drive a relay with arduino, and I used a BC547 to switch 12V for the relay.
But in the relay there was a diode, which sorted out the circuit (thats why I drawed in the wrong orientation)

I know it was a mistake to not use current limiting resistor on Base of the transistor.

Is it possible that this shorted circuit made too much current on the transistor base which killed my arduino?

I made this circuit:
[![Schematic][1]][1]

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

title: Arduino nano digital I/O overload

Answers: 1

body:
Short answer is probably.  There is a voltage drop from base to emitter that is about .7 volts.  But something still has to contend with the rest of the energy.  You might try a different Arduino digital output on the chance that the balance of the processor is working as expected.

I say probably because several things might have happened if the transistor actually turned on.  For instance the forward biased (backwards) diode may have allowed so much current to flow through the relay and transistor that the transistor failed first.  Or, if the power supply had a low current rating, it may not have had the capacity to burn anything out.  As you can see, it is difficult to say what exactly happened with out testing each part individually.


body: I am using sim 900a module for the first time(sim900a). Initially when i powered it with the arduino 5v supply, the power led of the board glow but the network status led never glow. After searching online for answers they showed to use external power supply with 5v 2A, then i used the specified power supply. It worked actually now the status led started to glow but it does not blink for ever 1sec or 3sec instead it glows continuously. I connected the module with the tx and rx of arduino and called the inserted sim the serial monitor detected the call and gave the output, but i cannot make a call or send sms from the module to other numbers. Pls help me out.

title: sim 900a mini status led glowing constantly instead of blinking

Answers: 0


body:
I have written a code with interrupts to control the servo but my servos are not working. One is meant to work with interrupt but the other one has to simply move but it is also not working. Even the serial window shows that the code is working properly ut the servos aren't moving I have checked both my servos with same connections and Sweep example of Arduino and both work fine.

    #include <TimerOne.h>                                 // Header file for TimerOne library
    #include <Servo.h>
    #define trigPin 12                                    // Pin 12 trigger output
    #define echoPin 2                                     // Pin 2 Echo input

    #define echo_int 0                                    // Interrupt id for echo pulse

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

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

    int sound = 250;

    Servo servo1; //Servos
    Servo servo2;

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

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

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

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

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

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

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

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

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

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

    }

    void distance_checking()
    {

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

    else {
    servo1.write(0);
    }

    delay(500);
    }

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

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

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

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

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

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

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

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

        case LOW:                                       // Low so must be the end of hte echo pulse
          echo_end = micros();                          // Save the end time
          echo_duration = echo_end - echo_start;        // Calculate the pulse duration
          break;
      }
    }
I tested my motors with this code one by one and they worked absolutely fine:

    #include <Servo.h>

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

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

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

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

title: Servo motor won't work for a specific code

Answers: 0


body:
So, I managed to fry my cheap servo/ESC (electronic speed controller) and decided to make my own using an ATTiny13A on some perfboard. But, I have run into some issues getting the servo to respond.  I'm assuming the servo.h library is not compatible with the ATTiny13A because of incompatible internal clock speeds not creating the right PWM signals. And I haven't found a solution for this.

I have messed around with the Servo8Bit.h library, but this also doesn't seem to work (as its designed for the ATTiny45 and the ATTiny85 ). Is the ATTiny13A even able to produce the needed PWM signals?

Any help/links to documentation would be appreciated!

Thanks in advance.

Code:
```c++
#include <Servo.h>

Servo myservo;
int potpin = A3;
int val;    // variable
int Toggle = 2;

void setup() {
  Serial.begin(9600);
  pinMode(Toggle, INPUT);
  myservo.attach(1);  // Servo/ESC is attached to pb1
}

void loop() {
  int ToggleState = digitalRead(Toggle);
  Serial.println(ToggleState);
    val = analogRead(potpin);

  if (ToggleState == 0) {
  val = map(val, 0, 1023, 0, 180);  //Servo motor
   myservo.write(val);
  delay(15);
}
else {
  val= map(val, 0, 1023,1000,2000); //ESC
  myservo.write(val);
  delay(15);
 }
}
```
[![Circuit][1]][1]
[![Project][2]][2]

  [1]: https://i.stack.imgur.com/JFHF9.png
  [2]: https://i.stack.imgur.com/cQx4n.jpg

title: Driving a servo with an ATTiny13A

Answers: 1

body:
Servo8Bit and ATTiny13(A)
-------------------------

I had a look at the Servo8Bit and had pretty much the same thoughts on this as [Edgar Bonet][1] in his comment:

> Servo8Bit relies on an 8-bit timer, and the ATtiny13A does have an
> 8-bit timer. It should not be too hard to port this library to that
> micro. Study the source code, then study the datasheet of the tiny13A
> (mostly the chapter dedicated to the timer). You should then be able
> to easily see what changes are needed.

Ignoring the timing differences between the ATTinyx5 and ATTiny13(A), I just went ahead and saw if I could get it to compile.  And yeah, it's pretty easy to compile.  This mostly consists of adding `0` to some hardware register names.  The bad news is:

> Sketch **uses 1486 bytes (145%)** of program storage space. **Maximum is 1024 bytes.**
> Global variables use 31 bytes (48%) of dynamic memory, leaving 33 bytes for
> local variables. Maximum is 64 bytes.
>
> Sketch too big; see http://www.arduino.cc/en/Guide/Troubleshooting#size for tips on reducing it.
>
> Error during build: text section exceeds available space in board

So, yeah, that was a bit much to hope for, I guess.  The library does use ISRs to support a number of servos kind of like the more common servo library that you'd use on an UNO.  I haven't looked into chopping it down to size; I expect that will be impractical.

PWM... sort of.
--------------

Prior to considering modifying Servo8Bit, I kind of thought it made sense to just use the timer counter directly to produce a waveform.  The problem is the conventional servo signal is 20ms long, and does all of its control in a 1ms window.  If you try to fit the whole 20ms frame into a single 8bit timing interval, what you end up with is pretty crappy angular control.  So, doing it is a bit painful without a 16-bit timer counter.  But, I guess that's the game.

So, the below is a crude and barely tested attempt at it.  The code that follows is state machine inside the OCR0B overflow vector that schedules the rising an falling edges is "normal" mode.  Just to warn you, I don't actually have an ATTiny13(A) on hand.  And in fact I don't happen to have a servo hand either.  But I do have an ancient storage scope and an ATTiny85 and the ability to compile for ATTiny13(A), and a calculator for working out the 8 MHz vs 9.6 MHz difference.

So here's what I came up with, which I *think* (but don't know) will work if you compile and upload using [MCUDude MicroCore][2], ATTiny13(A) with the 9.6 MHz internal oscillator chosen.

It's only designed to operate 1 servo.  Extending it to two should be easily doable.  Going beyond that you're likely run into problems.

Code:

```c++
// +---------------------------------------------------------------------------------------+
// |                                                                                |
// |                                 +-------------+                                       |
// |                                 |             |                                       |
// |                                 |      A      |                                       |
// |  PCINT5 ADC0 dW  /RESET  PB5 *--|-1    T    8-|--* VCC                                |
// |                                 |      T      |                                       |
// |  PCINT3 ADC3      CLKI   PB3 *--|-2    I    7-|--* PB2  SCK   ADC1 T0         PCINT2  |
// |                                 |      N      |                                       |
// |  PCINT4 ADC2             PB4 *--|-3    Y    6-|--* PB1  MISO  AIN1 OC0B  INT0 PCINT1  |
// |                                 |      1      |                                       |
// |                          GND *--|-4    3    5-|--* PB0  MOSI  AIN0 OC0A       PCINT0  |
// |                                 |      A      |                                       |
// |                                 |             |                                       |
// |                                 +-------------+                                       |
// |                                                                                |
// +---------------------------------------------------------------------------------------+

#if !defined(__AVR_ATtiny13__) && !defined(__AVR_ATtiny13A__)
#error This code is written specifically for ATTiny13(A) devices.
#endif

#if F_CPU != 9600000
#error  This code is written specifically for 9.6 MHz
#endif

//
//
//
#include <avr/io.h>
#include <avr/interrupt.h>

//
//
//
constexpr uint8_t TCCR0A_config(
  int com0b // two bits
) {
  return
      (    0 << COM0A1) // normal
    | (    0 << COM0A0) //   port operation
    | (com0b << COM0B0) // bits 5 AND 4
    | (    0 <<      3) // reserved
    | (    0 <<      2) // reserved
    | (    0 <<  WGM01) //  lower two bits
    | (    0 <<  WGM00);//     of Normal (mode 0);
}

//
//
//
constexpr uint8_t TCCR0A_config_for_go_low()  {return TCCR0A_config(0x2);}
constexpr uint8_t TCCR0A_config_for_go_high() {return TCCR0A_config(0x3);}

//
// 50 Hz (hobby servo frame frequency); period 20 ms
//
// In the below you'll see the numbers 150 and 300 and 3000.
// The reason for these numbers is that I've chosen to to use a /64
// timer prescaler.  At 9.6 MHz, with a /64 prescaler, 1 millisecond
// is 150 timer timer counts.  There's as fixed 1 MS high in the servo,
// followed by 0 to 1ms variable portion.  The number 150 helpfully
// fits within the 8-bit timer registers and also gives a reasonable
// number of increments to the servo control.  For 180 degrees, 150 increments
// is 1.2 degrees.
//
// The maximum high time is the fixed 1ms high time and the maximum
// variable high time, totalling 2 MS, or 300 timer ticks, that's what that
// number is about.
//
// 3000 is the number of timer ticks for a full 20ms signal frame,
// that is 20 * 150 = 3000.
//
//
// Deriving the 150 figure:
//
//  At 9.6 MHz and /64 prescaler
//
//        1 second         64 mcu_cycles   A_MS_DURATION timer_counts
//  -------------------- X ------------- X ---------------
//  9_600_000 mcu_cycles   1 timer_count    0.001 seconds
//
//
//       1      64    A_MS_DURATION
//  --------- X -- X  -----
//  9_600_000   1     0.001
//
//
//     64       A_MS_DURATION
//  --------- X -----------
//  9_600_000      0.001
//
//
//     64 x A_MS_DURATION
//  --------------------
//        9_600
//
//
//  A_MS_DURATION
//  -------------
//      150
//

static constexpr uint8_t  ONE_MS_WORTH_OF_TICKS    = 150;
static constexpr uint8_t  MAXIMUM_HIGH_PERIOD      = ONE_MS_WORTH_OF_TICKS * 2;
static constexpr uint16_t TWENTY_MS_WORTH_OF_TICKS = 3000;
static constexpr uint16_t MAX_WASTE_CYCLES         = 0x80;

static volatile uint8_t g_pulse_width = ONE_MS_WORTH_OF_TICKS / 2;  // default to mid-range.

ISR(TIM0_COMPB_vect) {
  static uint8_t l_pulse_width; // this caches g_pulse_width
                                // and is updated from g_pulse_width
                                // only between frames

  //
  // The ISR is a state machine with four macro states.
  //
  enum class t_signal_generator_state : uint8_t {
    timing_to_variable_high_period,
    timing_to_set_pulse_width,
    calculate_time_to_start_of_next_pulse_and_waste_a_bit,
    timing_to_start_of_pulse
  };

  //
  // Macro state variable
  //
  static t_signal_generator_state g_signal_generator_state =
    t_signal_generator_state::timing_to_variable_high_period;

  // low_time_remaining is an extended state variable
  // for the timing_to_start_of_pulse state
  static uint16_t low_time_remaining;

  switch (g_signal_generator_state) {
    case t_signal_generator_state::timing_to_variable_high_period:
      // We just went high at the OCR0B value that triggered this interrupt
      // and we need to retrigger ((MAXIMUM_HIGH_PERIOD==300) - 256 == 44)
      // timing cycles later such that there are 256 timing cycles left of the
      // 2ms (maximum) high part of the frame.
      OCR0B += (MAXIMUM_HIGH_PERIOD - 256);  // 2ms worth of timer nicks minus the resolution of our timer

      // We're remaining HIGH as we head into the variable portion of the HIGH period.
      g_signal_generator_state = t_signal_generator_state::timing_to_set_pulse_width;
      break;
    case t_signal_generator_state::timing_to_set_pulse_width:
      // We're retrieving the global variable which holds a (potentially new) value from 0 to 150
      // representing a span of 0ms to  1ms (the full range of the servo), but
      // we're starting out the variable pulse a head of time, part way through the always-on first ms.
      // There are (150 - 44) timer cycles, that's 1 ms worth of timer cycles
      // where the timer remains high to finish out first millisecond of HIGH.
      // So we add this to the requested variale pulse width time.
      l_pulse_width = g_pulse_width + (ONE_MS_WORTH_OF_TICKS - 44);

      // Set adjust pulse width
      OCR0B += l_pulse_width;

      // We'll be going low and the end of the variable high period.
      TCCR0A = TCCR0A_config_for_go_low();

      g_signal_generator_state = t_signal_generator_state::calculate_time_to_start_of_next_pulse_and_waste_a_bit;
      break;

    case t_signal_generator_state::calculate_time_to_start_of_next_pulse_and_waste_a_bit:
      // We just went low at the OCR0B value.

      // Calculate remaining timer cycles to the beginning of the next pulse
      // accounting for the MAX_WASTE_CYCLES we're about to waste in this state.
      low_time_remaining = (TWENTY_MS_WORTH_OF_TICKS - 44 - MAX_WASTE_CYCLES) - l_pulse_width;
      OCR0B += MAX_WASTE_CYCLES;

      // We will remain LOW since the pulse is done and we've not finished out the 20ms period
      g_signal_generator_state = t_signal_generator_state::timing_to_start_of_pulse;
      break;

  case t_signal_generator_state::timing_to_start_of_pulse:
      // Continue retriggering the timer until we've used up 20ms total,
      // in increments of not more than MAX_WASTE_CYCLES.

      if (low_time_remaining > MAX_WASTE_CYCLES) {
        low_time_remaining -= MAX_WASTE_CYCLES;
        OCR0B += MAX_WASTE_CYCLES;
        // We'll need to wast more, so we're remaining LOW.
      } else {
        OCR0B += low_time_remaining;
        low_time_remaining = 0;

        // This is out last round through this state to finish out the 20ms
        // window, so we'll be returning to HIGH.
        TCCR0A = TCCR0A_config_for_go_high();

        g_signal_generator_state = t_signal_generator_state::timing_to_variable_high_period;
      }
      break;
  }
}

//
//
//
void servo_init() {
  const auto SREG_saved = SREG; cli();

  DDRB |= 1U << 1;  // Servo data pin attached on Attiny PB1 aka (OCR0B)

  // select no clock source / stop counter
  TCCR0B &= ~(
      (1U << CS02)
    | (1U << CS01)
    | (1U << CS00)
  );

  // reset counter
  TCNT0 = 0x00;
  OCR0B = 0x80;

  TIMSK0 =
      (0 <<      7) // reserved
    | (0 <<      6) // reserved
    | (0 <<      5) // reserved
    | (0 <<      4) // reserved
    | (1 << OCIE0B) // we *ARE*  using output-compare B interrupt
    | (0 << OCIE0A) // we aren't using output compare A interrupt
    | (0 <<  TOIE0) //             nor overflow interrupt
    | (0 <<      0);// reserved

  TIFR0 = 1U << OCF0A;

  TCCR0A = TCCR0A_config_for_go_high();

  TCCR0B =
      (0 << FOC0A) // We're not doing any
    | (0 << FOC0B) //   output compare forcing.
    | (0 <<     5) // Reserved.
    | (0 <<     4) // Reserved.
    | (0 << WGM02) // High order bit of Normal mode (0)
    | (0 <<  CS02) // Clock source
    | (1 <<  CS01) //    prescaled
    | (1 <<  CS00);//      by 64.

  SREG = SREG_saved;
}

//
//
//
void setup() {
  servo_init();
}

//
//
//
void loop() {
  for (g_pulse_width = 0; g_pulse_width < 150; ++g_pulse_width) {
    __builtin_avr_delay_cycles(F_CPU >> 5);
  }
  for (; g_pulse_width > 0; --g_pulse_width) {
    __builtin_avr_delay_cycles(F_CPU >> 5);
  }
}

//  vim:sw=2:ts=2:et:nowrap:ft=cpp:
```

On the scope, this produces servo signal that should sweep a servo on pin OCR0B (PB1).  Something like 4 to 5 seconds going one way and same going back.

If I put an ATTiny13A on an order sometime and manage to dig out a servo myself, I'll actually test it.  It may be a very long time before I can do that though.  But the results on the scope look good.  Admittedly everything is scaled by 9.6/8.0.  It should be accurate on a ATTiny13(A).  I verified that it compiles for it.  The workings of the thing are explained in the code as I can.

For comparison:

>Sketch uses **490 bytes (47%)** of program storage space. Maximum is 1024 bytes.
>Global variables use 10 bytes (15%) of dynamic memory, leaving 54 bytes for local variables. Maximum is 64 bytes.

That's still a good chunk of what little code space you have, but it should be enough to read a switch and potentiometer.  This is using the timer the device has, so `millis()`/`delay()` usage are kind of out-the-window, I think, I didn't try to see what happen when you call them or study their code in MicroCore.  You *could* recreate your own `millis()` by making a timer overflow interrupt and it would overflow at about 1.7 ms intervals.  As you can see, I just used `__builtin_avr_delay_cycles` to keep things simple.

If you, or anyone else, gets it working on at ATTiny13 before I try it myself, I'm curious to know that it worked (or didn't).

  [1]: https://arduino.stackexchange.com/users/7508/edgar-bonet
  [2]: https://github.com/MCUdude/MicroCore


body:
I am having some trouble getting my board to perform the function I want it to perform. This is a project I have due in a few days, and I have hit a wall I just can't seem to get past. Now, I will say the issue is definitely in the way I coded the program, but I don't really know enough about Arduino (and coding) to understand why it is not working. My board is properly hooked up to use 3LEDs, a speaker, a photoresistor, and an ultrasonic sensor (detects distances). My Arduino program takes serial input from a GUI that I created in MATLAB. I have verified the MATLAB code is good, and the serial port is communicating properly. I have made an alarm that goes off when light or motion is detected. It has 3 basic functions:

1) Set the alarm
2) Turn off the alarm
3) "snooze" which just delays for 5 minutes and then the alarm goes off

The snooze and turn off alarm parts of my code are working great, but the set alarm is where I am having trouble. The snooze option sets off the yellow LED to verify it is on "snooze". The red LED comes on when the alarm is currently going off. The green LED comes on when the alarm is set. When I try to activate the "Set Alarm" function, which is case 'O' in a switch case, the light does come on, but the sensors are not picking up any input as far as I can tell. Again I have verified the pins and everything are set up correctly as I have isolated those and verified they work. I have a suspicion that the problem is because I have the sensors initialed within the switch case of the "Set Alarm" (case 'O', not 0). I don't really know how to get the sensors to run continually within that switch case until the "turn alarm off" case is activated. I need the sensors to be activated/reset by "Set Alarm" case.

**I am also new to this forum so please let me know if I am missing anything!

here is my code:
<!-- language-all: lang-C++ -->

```
void setup()
{
  Serial.begin(115200);
  pinMode(12,OUTPUT); //RED
  pinMode(13,OUTPUT); //GREEN
  pinMode(14,OUTPUT); //YELLOW
  pinMode(16,OUTPUT); //SPEAKER
  pinMode(4,INPUT); //Echo
  pinMode(2,OUTPUT); //Trig
}

void loop()
{
 if(Serial.available() >0)
 {
 char b = Serial.read();

  switch(b)
  {
    //Turn Alarm off
    case 'A' :
    {
    digitalWrite(12,LOW);//red off
    digitalWrite(13,LOW); // green off
    digitalWrite(14,LOW); //yellow off
    noTone(16);
    delay(500);
    }
    break;

    // Set alarm
    case 'O' :
    {
      int light;
  light = analogRead(0);
  unsigned long distance;
    digitalWrite(2,LOW);
  delayMicroseconds(2);
  digitalWrite(2,HIGH);
  delayMicroseconds(10);
  digitalWrite(2,LOW);
  distance = pulseIn(4,HIGH);
  distance = distance/58; //centimeters
  delay(500);

    digitalWrite(12,LOW); //red off
    digitalWrite(14,LOW); //yellow off
    digitalWrite(13,HIGH); //green on

  if (light < 400)
    {
     digitalWrite(12,HIGH);//red on
    digitalWrite(13,LOW); // green off
    digitalWrite(14,LOW); //yellow off
    tone(16,832);
    delay(500);
    }

  if (distance < 50)
    {
     digitalWrite(12,HIGH);//red on
    digitalWrite(13,LOW); // green off
    digitalWrite(14,LOW); //yellow off
    tone(16,832);
    delay(500);
    }

    }
    break;

    // snooze option
    case 'Z' :
    {
    digitalWrite(14,HIGH); //yellow on
    digitalWrite(12,LOW); //red off
    digitalWrite(13,LOW); // green off
    noTone(16);
    delay(300000UL);
    digitalWrite(12,HIGH); //red on
    digitalWrite(13,LOW); // green off
    digitalWrite(14,LOW); //yellow off
    tone(16,832);
    delay(500);
    }
    break;
   }

  }
}

```
Any help would be very much appreciated!

title: Arduino code not working properly (Please Help)

Answers: 2

body:
The problem is that, if you enter 'O', you go thorugh the set alarm case only once. If no alarm was triggered, it just falls through the if statements and is then back in the main loop. In that main loop, you only check for your sensors, if something was entered to the serial console. That means if you do not enter anything during a loop, nothing happens.

The solution to this would be to implement a finite state machine.
That means you use a state variable for the switch case. You then update your state based on the state and the external conditions. In your case you can just update the state using user input.

I changed your code a bit for a possible (but bad) implementation. I did not verify or check for errors. I recommend using a more solid implementation, if you plan to build upon this code for more complex behavior.

```
char state = 'A'; //initialize state in Off state
char b;          // make user input variable global
void setup()
{
  Serial.begin(115200);
  pinMode(12, OUTPUT); //RED
  pinMode(13, OUTPUT); //GREEN
  pinMode(14, OUTPUT); //YELLOW
  pinMode(16, OUTPUT); //SPEAKER
  pinMode(4, INPUT); //Echo
  pinMode(2, OUTPUT); //Trig
}

void loop()
{
  if (Serial.available() > 0)
  {
    b = Serial.read();
  }
  // close user input section

  switch (state) // run switch case every loop
  {
    //Turn Alarm off
    case 'A' :
      {
        digitalWrite(12, LOW); //red off
        digitalWrite(13, LOW); // green off
        digitalWrite(14, LOW); //yellow off
        noTone(16);

        delay(500);
      }
      break;

    // Set alarm
    case 'O' :
      {
        int light;
        light = analogRead(0);
        unsigned long distance;
        digitalWrite(2, LOW);
        delayMicroseconds(2);
        digitalWrite(2, HIGH);
        delayMicroseconds(10);
        digitalWrite(2, LOW);
        distance = pulseIn(4, HIGH);
        distance = distance / 58; //centimeters
        delay(500);

        digitalWrite(12, LOW); //red off
        digitalWrite(14, LOW); //yellow off
        digitalWrite(13, HIGH); //green on

        if (light < 400)
        {
          digitalWrite(12, HIGH); //red on
          digitalWrite(13, LOW); // green off
          digitalWrite(14, LOW); //yellow off
          tone(16, 832);
          delay(500);
        }

        if (distance < 50)
        {
          digitalWrite(12, HIGH); //red on
          digitalWrite(13, LOW); // green off
          digitalWrite(14, LOW); //yellow off
          tone(16, 832);
          delay(500);
        }

      }
      break;

    // snooze option
    case 'Z' :
      {
        digitalWrite(14, HIGH); //yellow on
        digitalWrite(12, LOW); //red off
        digitalWrite(13, LOW); // green off
        noTone(16);
        delay(300000UL);
        digitalWrite(12, HIGH); //red on
        digitalWrite(13, LOW); // green off
        digitalWrite(14, LOW); //yellow off
        tone(16, 832);
        delay(500);
      }
      break;
  }

  state = b; // update state based on input

}
```

body:
<!-- language-all: lang-C++ -->
The most simplest way to troubleshoot a program is to add `Serial.println();` statements everywhere. For example you could add `Serial.println("Setting Alarm");` in the first line of the case for setting the alarm.

You will notice that the set alarm code only runs once through, instead of continously. You should use the case to set a mode or a state in where the sensors are checked continously.

First I would create a variable called `setAlarmMode` and set it to `false`.

    setAlarmMode = false;

Then I would remove the reading of sensors from the case statement and instead set `setAlarmMode` to `true`.

    // Set alarm
    case 'O' :
      {
        Serial.println("Setting Alarm");

        // Set the LEDs for the mode
        digitalWrite(12, LOW); //red off
        digitalWrite(14, LOW); //yellow off
        digitalWrite(13, HIGH); //green on

        setAlarmMode = true;
      }
      break;

Now I would insert this code outside of the `if (Serial.available() > 0)` code block:

    // Read sensors
    if (setAlarmMode == true)
      {
        Serial.println("Reading sensors");
        int light;
        light = analogRead(0);
        Serial.print("Light sensor value: ");
        Serial.print(light);

        unsigned long distance;

        // Do trigger pulse
        digitalWrite(2, LOW);
        delayMicroseconds(2);
        digitalWrite(2, HIGH);
        delayMicroseconds(10);
        digitalWrite(2, LOW);

        distance = pulseIn(4, HIGH);
        distance = distance / 58; //centimeters
        Serial.print("   Distance sensor value: ");
        Serial.println(distance);

        if (light < 400)
        {
          Serial.println("Light below threshold");
          setAlarmMode = false;
          activateAlarm();
        }

        if (distance < 50)
        {
          Serial.println("Distance below threshold");
          setAlarmMode = false;
          activateAlarm();
        }

        delay(500);
      }

I have also created a function to hold the common code of showing the alarm:

    void activateAlarm(void)
    {
      digitalWrite(12, HIGH); //red on
      digitalWrite(13, LOW); // green off
      digitalWrite(14, LOW); //yellow off
      tone(16, 832);
      delay(500);
    }


body:
I have 2 sketches one is pixel clock with RTC ds 1307 and the other is 7 Segment with DHT 11, I want to merge the two into one but it is giving errors for rtc.
sketch for pixel clock

```cpp
#include <Wire.h>
#include <RTClib.h>
#include <Adafruit_NeoPixel.h>

#define PIN 6
#define PIXEL 60

Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL, PIN, NEO_GRB + NEO_KHZ800);

RTC_DS1307 RTC; // Establish clock object
DateTime Clock; // Holds current clock time

byte hourval, minuteval, secondval;

void setup() {
 Serial.begin(9600);
  Wire.begin();          // Begin I2C
  RTC.begin();   // begin clock

    if (! RTC.isrunning()) {
//  Serial.println("RTC is NOT running!");
  // following line sets the RTC to the date & time this sketch was compiled

  }

//  RTC.adjust(DateTime(__DATE__, __TIME__));
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
  strip.setBrightness(20);

}

sketch for 7 segment
#include <Time.h>        //Time Library
#include <TimeLib.h>
#include <DS1307RTC.h>   //Real Time Clock Library
#include <Wire.h>        //Auxiliary Library for DS1307RTC (Real-Time Clock) - Pins to Arduino UNO: A4 (SDA), A5 (SCL)
#include <DHT.h>         //Temperature and Humidity Library

#define DHTPIN 8         //Sensor DHT11  conected to the pin 8 on Arduino

// Definition of what DHT sensor type you are using
#define DHTTYPE DHT11   // DHT 11
//#define DHTTYPE DHT22   // DHT 22 (AM2302), AM2321
//#define DHTTYPE DHT21   // DHT 21 (AM2301)

DHT dht(DHTPIN, DHTTYPE);

int clockPin = 13; // Pin 13 of Arduino connected in the pin 11 of 74HC595 (Clock)
int latchPin = 10; // Pin 10 of Arduino connected in the pin 12 of 74HC595 (Latch)
int dataPin = 11; // Pin 11 of Arduino connected in the pin 14 of 74HC595 (Data)

int hora, minuto, temp, umid;
int unidadeHora, unidadeMinuto, dezenaHora, dezenaMinuto;
int unidadeTemp, dezenaTemp, unidadeUmid, dezenaUmid;
unsigned long ti;
int brightness; // Brightness of display (Min=1 / Max=20)
int k;

//Digits Matrix - 0 a 9
byte num[] = {
  B01111110, // Zero
  B00110000, // One
  B01101101, // Two
  B01111001, // Three
  B00110011, // Four
  B01011011, // Five
  B01011111, // Six
  B01110000, // Seven
  B01111111, // Eight
  B01111011, // Nine
};

void setup() {

  pinMode(latchPin, OUTPUT); // Define the 3 digital pins as output
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);

  dht.begin();

  setSyncProvider(RTC.get);   // Update the time with data of RTC (Real Time Clock)
  setSyncInterval(300);       // Set the number of seconds between re-sync

  //setTime(hours, minutes, seconds, days, months, years);
  //setTime(15, 05, 00, 13, 02, 2016);
  //RTC.set(now());           // Set the RTC time

  brightness = 15; // Set the brightness of display (Min=1 / Max=20)

}
```

error in the

```
void loop{
a function-definition is not allowed here before '{' token

E:\pixel_clock_with_7_segment\pixel_clock_with_7_segment.ino: In function 'void setup()':

pixel_clock_with_7_segment:86:15: error: a function-definition is not allowed here before '{' token

   void loop() {

E:\pixel_clock_with_7_segment\pixel_clock_with_7_segment.ino: At global scope:

pixel_clock_with_7_segment:257:1: error: expected declaration before '}' token

 }
```

 Can anybody help me in merging the two sketches as I am new to Arduino programming?

title: I have 2 sketches with same RTC DS1307 but when I combine the 2 sketches it gives errors

Answers: 0


body:
I would like to install speaker-dependent voice recognition in a robot equipped with Arduino Uno compatible boards.
Specifically, I want to record the robot's name beforehand and have it respond when I call the robot's name.

Although it is not an Arduino, there is a person who has developed a function that I would like to realize with the M5StickV.
This person used [isolated_word.py][1], a library published by Sipeed, as a reference.

[【K210】マイク搭載版M5StickV,Sipeed Maixシリーズで音声認識をする][2]

After some research, I found [Maix_Speech_Recognition][3] in the library of Maixduino, which can use Arduino IDE.
Apparently, it uses Mel-frequency cepstrum coefficients analysis of speech input, and then uses dynamic time stretching to find the similarity.
The MFCC uses the K210 FFT on the Maixduino.

Arduino Uno does not have an FFT accelerator, but it can do FFT.
Therefore, I thought it would be possible to use Maix_Speech_Recognition for specific speaker speech recognition on ArduinoUno compatible devices.

**Question**
1. Is it possible to use Maix_Speech_Recognition for speaker-dependent voice recognition on Arduino Uno compatible boards?
2. What part of Maix_Speech_Recognition should I modify to make it work on Arduino Uno compatible boards?

  [1]: https://github.com/sipeed/MaixPy_scripts/tree/master/multimedia/speech_recognizer
  [2]: https://raspberrypi.mongonta.com/isorated-word-recognizer-k210/
  [3]: https://github.com/sipeed/Maixduino/tree/master/libraries/Maix_Speech_Recognition

title: Speaker-dependent Voice Recognition

Answers: 1

body:
> Is it possible to use Maix_Speech_Recognition for speaker-dependent voice recognition on Arduino Uno compatible boards?

No. It's not.

> What part of Maix_Speech_Recognition should I modify to make it work on Arduino Uno compatible boards?

Don't even think about it. The UNO *cannot* do anything even remotely like speech recognition of any form without adding extra specific speech recognition hardware.

Just get a K210 board - they're cheap enough.