body:
I have a 2.8" Color TFT Touchscreen from Adafruit, and I'm currently trying to set it up. I've been following [this guide][1] to set up the screen. The screen powers on when connected to power, but it's not displaying what the example says it should. I can't tell if it's the code of our the hardware that's the issue, but since the hardware setup is pretty straightforward on the site, my guess is it's the code.

The guide says to check the serial console, and that the configuration bytes should be similar. Here's the example's configuration bytes:

[![Configuration bytes from the example][2]][2]

Versus what my serial console is displaying

[![Configuration bytes from my console][3]][3]

I should note that I am using a Nano every instead of an Uno, but looking up the SPI pins for the Nano Every, I found that they should be the same as for the Uno. But if anyone can confirm that, much appreciated. That could definitely be the problem if I'm wrong.

Finally, I'm including the code that I am currently using below. There are no issues with uploading, and I've triple checked that I have the right libraries downloaded, and am using the correct board and port. I'm thinking the everything before the setup is what might be causing the issue, but I've included the entirety of the setup as well.

  [1]: https://learn.adafruit.com/adafruit-2-8-and-3-2-color-tft-touchscreen-breakout-v2/spi-wiring-and-test
  [2]: https://i.stack.imgur.com/52rQk.png
  [3]: https://i.stack.imgur.com/7QYPA.png

```/***************************************************
  This is our GFX example for the Adafruit ILI9341 Breakout and Shield
  ----> http://www.adafruit.com/products/1651

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

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

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

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

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

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

  tft.begin();

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

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

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

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

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

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

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

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

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

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

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

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

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

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

}```

title: Driver configuration not showing the right numbers on the Graphics Test example's serial monitor for Adafruit IlI9341 library

Answers: 0


body:
I'm trying to measure the current, voltage, and power of AC load using Peacefair PZEM-004Tv3.0 module. For the serial communication of this module, I'm using SoftwareSerial Pins 2 and 3 on Arduino Uno.
But this module seems doesn't work well, it just read the voltage and the rest is zero. The datasheet said:

 - current test value is from the beginning of 0.02A
 - power test value is from the beginning of 0.4W

I have assumed the load that I'm trying to measure hasn't enough minimum current or power. But I have tried to measure a bigger load also, and the result of current and power measurement is still zero.

I don't think it is caused by the program because I just run the example of the library. I'm using [this][1] library.

Here I attached how do I wire my pieces stuff:
[![picture][2]][2]

Any suggestions?

  [1]: https://github.com/mandulaj/PZEM-004T-v30
  [2]: https://i.stack.imgur.com/EZnWc.jpg

title: PZEM-004T can't read current

Answers: 0


body:
I have two Attiny85 communicating over 433mhz radio (Rx & Tx on either ends) using virtual wire library, how will the programming be to pair them by the press of a button on either module ?
i have so far been able to pair them both through the program (exclude any external devices by giving a node ID to listen to in my Rx) or think of adding DIP switches (but i run out of pins & combinations sooner). I am expecting  something similar to a commercial product where i can connect/pair multiple Tx modules to a single Rx base station in a press of a button on the Tx side. so i am seeking some technical expertise on the idea to understand such programming technique/methods.

Regardless of using 433mhz or a NRF24L01 module or anything else, i want to know how this feature of pairing module together is made.

*------*
Edit 22 July 2021:
This is added here in response from Crisl's comment

you have correctly understood my question, yes i want to learn how such a pairing protocol is implemented, i am not too concerned about the device for the communication gateway.

this question is regarding the protocol, and not about a specific circuit

*------*
I am a mechanical engineer by profession, with a hobby towards programming & electronics, so kindly spare some patience/detail in explaining this concept/technique.

title: how to write a program in Arduino that pairs a single Rx to multiple Tx modules? i want to learn implementing this protocol

Answers: 1

body:
If it is sufficient to distinguish between the two (or several) transmitters and you don't need to exclude intrusions, accidental or otherwise, a "protocol" can be as simple as:

XMTRID BYTECOUNT BYTE[0] BYTE[1] ... BYTE[COUNT-1]

, where each of the above represents a single byte. Does the library include message integrity checking, such as a checksum? If not, and the physical conditions warrant, you might add that to your protocol as well, and include an expectation by the transmitter that it receives an acknowledgement or rejection of correct reception (ACK or NAK) within a short time and will re-transmits the same message if it hasn't received an ACK. Then you'll want a message ID byte that increments for each new message (but not for retramsmission), so the receiver can reject a retransmission (if, say, its attempt to acknowledge had been lost).

Then your protocol could look something like this:

XMTRID MSGID CHKSUM BYTECOUNT BYTE[0] BYTE[1] ... BYTE[COUNT-1]

. and it just keeps getting better from there as you add features for robustness, security, and whatever else you might need it to accomplish. But I'm guessing this is already sufficient.

Update:
To clarify:

    XMTRID    - ID of sending 433MHz radio (any value you like, as long as each device has its own).
    MSGID     - An incrementing number (rollover allowed), a new one for each *new* message
                (enables the receiver to distinguish new messages from resent ones).
    CHKSUM    - A sum of bytes in the message to let the receiver check the message integrity.
    BYTECOUNT - The number of message bytes to follow.
    BYTE[0] ... BYTE[BYTECOUNT-1] - The actual message data.


body:
Just to preface I am not that great at coding or anything and I am currently building sensors off of Oregon State University's Smart Rock sensor code, so the code I am being used is not mine. I am currently operating off their 2.5 and 2.5.1 Firmware as the code and every piece of the device works properly except for initializing an SD card, which continuously gives me the error of:

    [Factory] Creating: SD
    [SD] Initialize failed
    [Device] Cannot add inactive module

I have attempted this in many different boards with different SD cards and the issue remains the same, so I am inclined to think the issue is within the firmware. Is there anyone who could potentially guide me in the right direction on this or determine where the issue is coming from. I will respond quickly. I am using a Feather m0 Adafruit board and a Hypnos V3.1 board. Here is the serial monitor report when running this code, just to add, I am only seeking to fix the SD card issues:

    Initialized Serial!

    = = = = = Parse Config = = = = =

    Config Pretty Version:
    {
      "general": {
        "name": "Device",
        "instance": 1
      },
      "components": [
        {
          "name": "Analog",
          "params": [
            8,
            12,
            true,
            false,
            true,
            false,
            false,
            false,
            5,
            0,
            4,
            0,
            0,
            0
          ]
        },
        {
          "name": "SD",
          "params": [
            true,
            1000,
            10,
            "data",
            true
          ]
        },
        {
          "name": "DS3231",
          "params": [
            11,
            true,
            true
          ]
        },
        {
          "name": "Interrupt_Manager",
          "params": "default"
        },
        {
          "name": "Sleep_Manager",
          "params": [
            true,
            false,
            1
          ]
        },
        {
          "name": "MS5803",
          "params": [
            119
          ]
        }
      ]
    }
    SIZE: 949
    = = = = = Generate Objects = = = = =

    [Factory] Creating: Analog
    [Device] Adding Module: Analog
    [Factory] Creating: SD
    [SD] Initialize failed
    [Device] Cannot add inactive module
    [Factory] Creating: DS3231
    [DS3231] Current Time (before possible reset)
    [DS3231] Time: 2021/7/21 23:42:44
    [DS3231] Time: 2021/7/21 23:42:44
    [DS3231] Clearing DS3231 alarms
    [Device] Adding Module: DS3231
    [Device] Adding Module: InterruptManager
    [Factory] Creating: Sleep_Manager
    [Device] Adding Module: SleepManager
    [Factory] Creating: MS5803
    Oversampling setting: 512
    C0 = 0
    C1 = 0
    C2 = 0
    C3 = 0
    C4 = 0
    C5 = 0
    C6 = 0
    C7 = 0
    p_crc: 0
    n_crc: 0
    [MS5803_0] Initialize failed
    [Device] Adding Module: MS5803_0
    = = = = = = = = = = = = = = = = =

    [Device] Config:
     Device Name         : Device
     Instance Number     : 1
     Device Type         : Node
     Interval            : 1000
    [Device] Modules:
     Others
      [+] InterruptManager
      [+] SleepManager
     Sensors
      [+] Analog
      [+] MS5803_0
     RTCs
      [+] DS3231
    [InterruptManager] Registering ISR on pin 12 to be triggered on 0 and is immediate

     ** Setup Complete **
    [Device] Json:
    {
      "type": "data",
      "id": {
        "name": "Device",
        "instance": 1
      },
      "contents": [
        {
          "module": "Packet",
          "data": {
            "Number": 1
          }
        },
        {
          "module": "Analog",
          "data": {
            "Vbat": 0.012891,
            "EC[0]": 357.7055,
            "turbidity[2]": 2471
          }
        },
        {
          "module": "MS5803_0",
          "data": {
            "pressure": 0,
            "temp": 20
          }
        },
        {
          "module": "LocalTime",
          "data": {
            "Date": "2021/7/21",
            "Time": "15:42:44",
            "TimeZone": "PST"
          }
        }
      ],
      "timestamp": {
        "date": "2021/7/21",
        "time": "23:42:44"
      }
    }

Any help would be appreciated! I'm sorry if the formatting is wonky I'm very new to this.

title: SD Card Initialization Failed, cannot add inactive module

Answers: 0


body:
I am using the [EnableInterrupt][1] library, infact the only library that I can find that allows me to use six interrupts to wake the Arduino. However when I use it with the [LMIC][2] library (Matthijs Kooijman ) the "Forward uplink data message" is not sent during initial registration, only if
#include <EnableInterrupt.h> is commented out does it work. I am using a RFM95 with the following LMIC pin assignments:

const lmic_pinmap lmic_pins = {
    .nss = 10,
    .rxtx = LMIC_UNUSED_PIN,
    .rst = 9,
    .dio = {3, 8, LMIC_UNUSED_PIN},
};

This must be something to do with the library sharing ISRs.  Could somebody point to which parts of the LMIC library so as not to have this conflict?

I have tried swapping 8 for A5 and it again only works when the line is commented. Any help would be greatly appreciated.

  [1]: https://github.com/GreyGnome/EnableInterrupt/
  [2]: https://github.com/mcci-catena/arduino-lmic

title: Using Arduino LMIC library with EnableInterrupt

Answers: 1

body:
This is the best I can get to work with 6 available pin change interrupts - just enough!

    #define EI_ARDUINO_INTERRUPTED_PIN
    #define EI_NOTPORTB  // DISABLE FOR LMIC
    #define EI_NOTPORTD  // DISABLE FOR LMIC


body:
so i am working on a project which needs a lots of bit manipulation and shifting out the bits to control the pins of shift registers individually.

So i am using 2 shift registers daisy chained with 16 LEDS. Now, what i want is that, i want to control the LEDs individually just by shifting out the bits

here is what i tried

first Attempt

    int latchPin = 4; // Latch pin of 74HC595 is connected to Digital pin 5
    int clockPin = 5; // Clock pin of 74HC595 is connected to Digital pin 6
    int dataPin = 3; // Data pin of 74HC595 is connected to Digital pin 4

    byte leds=0b1000000000000001; // byte has 16 bits

    void setup()
    {

      pinMode(latchPin, OUTPUT);
      pinMode(dataPin, OUTPUT);
      pinMode(clockPin, OUTPUT);
    }

    void loop()
    {

      updateShiftRegister();

    }

    void updateShiftRegister()
    {
       digitalWrite(latchPin, LOW);

       shiftOut(dataPin, clockPin, LSBFIRST, leds);
       digitalWrite(latchPin, HIGH);
    }

Does not work! the 2nd shift register seems to be copying the first shift register which i don't want

In second attempt, i tried the masking method with HEX data type.
Here is it.

    int latchPin = 4; // Latch pin of 74HC595 is connected to Digital pin 5
    int clockPin = 5; // Clock pin of 74HC595 is connected to Digital pin 6
    int dataPin = 3; // Data pin of 74HC595 is connected to Digital pin 4

    byte leds=0xFFFF & 0x8001; // used hex masking method

    // 0xFFFF = 1111111111111111
    // 0x8001 = 1000000000000001
    // After & it should be 1000000000000001

    void setup()
    {

      pinMode(latchPin, OUTPUT);
      pinMode(dataPin, OUTPUT);
      pinMode(clockPin, OUTPUT);
    }

    void loop()
    {

      updateShiftRegister();

    }

    void updateShiftRegister()
    {
       digitalWrite(latchPin, LOW);

       shiftOut(dataPin, clockPin, LSBFIRST, leds);
       digitalWrite(latchPin, HIGH);
    }

This too makes same effect like the attempt 1 above.

Now here is what i want and need...

    byte leds = 0b1000000000000001

    /* As you can see the index 0 and index 15 of the byte led
      is set 1 or high which should produce +ve to the 15th pin of first register and 8th pin of second register.

but whenever i try this, it seems that one of the register is copying another one.

So, is there any way to shift out bits to control the shift register outputs individually?

if yes then please give a clear example code with a clear explanation.

if no then, please suggest me some alternative ways which can be used in the same way i want , of course with example code and explanation.

Schematic: [arduino.cc/en/Tutorial/Foundations/ShiftOut][1]

Thank You so much for your precious time.

Looking forward to your replies .

:)

  [1]: http://arduino.cc/en/Tutorial/Foundations/ShiftOut

title: How to control Shift registers output individually bitwise

Answers: 2

body:
The function `shiftOut()` only works for 8-bit values, as its documentation says.

Additionally, a `byte` can only store 8 bits. It doesn't matter how many bits you try to assign. (The compiler should have given you a warning, but the IDE likes to hide this.)

You need to write your own output function to shift out 16 bits, AFAIK.

body:
You have two problems with your code:

- `byte` is equal to `unsigned char` and can only hold exactly one byte, aka 8 bits (not 16 bits like your comment says). But you are trying to assign a 16bit number to it. The upper 8 bits are cut out in that process. They are lost. If you want to hold a 16bit number, you need to use a data type, that is at least 16 bits in its size, for example `uint16_t` (or you can use `unsigned int`, though in such situations it is often better to use a type, which has the same size on all platforms).

        uint16_t leds = 0b1000000000000001;

- The `shiftOut()` function has this declaration in wiring_shift.c:

        void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val)

    You can see, that `val` (which is the data, that should be shifted out) is of type `uint8_t`, the same as `byte`, which also can only hold 8 bits. The upper 8 bits of a 16bit value would be cut off and the function also just transmits 8 bits, nothing more (When you look at its implemention in the mentioned file, you will see a for loop with 8 as limit).

    Instead you should call that function for every byte, that you want to transmit in a single transmission; 2 times in your case  because you have 2 shift registers.

So the resulting program would look something like this:

    int latchPin = 4;   // Latch pin of 74HC595 is connected to Digital pin 5
    int clockPin = 5;   // Clock pin of 74HC595 is connected to Digital pin 6
    int dataPin = 3;    // Data pin of 74HC595 is connected to Digital pin 4

    uint16_t leds=0b1000000000000001; // uint16_t has 16 bits

    void setup()
    {

      pinMode(latchPin, OUTPUT);
      pinMode(dataPin, OUTPUT);
      pinMode(clockPin, OUTPUT);
    }

    void loop()
    {

      updateShiftRegister();

    }

    void updateShiftRegister()
    {
       digitalWrite(latchPin, LOW);

       // Shiftout lower byte by masking the other byte with bitwise AND (&)
       shiftOut(dataPin, clockPin, LSBFIRST, leds & 0xFF);
       // Shiftout higher byte by shifting the bit pattern 8 bits to the right
       // resulting in the high byte getting to the position of the low byte
       // and then masking away anything else than the new position of the high
       // byte data
       shiftOut(dataPin, clockPin, LSBFIRST, (leds >> 8) & 0xFF);
       digitalWrite(latchPin, HIGH);
    }

Note, that the masking with the bitwise AND operator is not really necessary here, but I like to do such things explicitly to make it more clear.

---

> So I need to store almost 50 bits in the variable to control the columns so can 'uint' method be useful in this case ?

In that case I would use a byte array to hold the data. With 50 bits you are at 6.25 or 7 bytes (since you cannot have sub bytes). The declaration would be something like this:

    byte leds[] = {0b00011001, ... }; // list the byte data here

And then you can shift that out with a for loop:

    void updateShiftRegister()
    {
       digitalWrite(latchPin, LOW);
       for(int i=0;i<sizeof(leds)/sizeof(leds[0]);i++){
           shiftOut(dataPin, clockPin, LSBFIRST, leds[i]);
       }
       digitalWrite(latchPin, HIGH);
    }

Note that `sizeof(leds)` will return the size of the `leds` array in bytes. I also divided through the size of a single element of the array to get the number of elements in the array instead of bytes. In this case this is the same, but since datatypes might change while the code progresses it is better to be save than sorry.

> i tried the masking method with HEX data type.

The data, that comes out is the same. The Arduino only knows of binary data. It doesn't know of different representions (like binary, HEX or decimal). The compiler will already convert that to the target value. So for the Arduino both ways are equivalent.


body:
I am currently planning a thesis that involve scanning fingerprints and storing the data in a database. The problem is that I do not know if it is possible for me/us to get the fingerprint data or variables scanned by the fingerprint scanner.

I tried searching on google, of course, but I don't see any information on how to display the data in a form such as binary.  I'm not sure if I can extract the data from the Arduino then store it in a website/database (---which to be fair, since fingerprints can be confidential, I understand if some articles don't provide a sample.)

Is it possible to get and extract the fingerprint scan data? For example, converting the scanned data in to a binary representation (011010101 etc.)

title: Arduino and fingerprint scanner - can I get the fingerprint scanner data?

Answers: 3

body:
Echoing my comment on SO with more information:

Commercial fingerprint sensors like [this one][1] do local store and compare and do not expose the actual image or binary signature. What they transmit to the microcontroller are ID's and match success.

If you need the binary data of the image itself you may be able to write your own image processing algorithm, perhaps using machine learning, and use a simple video camera connected to a microcontroller that in turn will send the captured image to your web server for processing.

Arduino can be programmed to capture still images and transfer a bitmap file to a server, such devices (microcontroller and cameras) are widely available.

  [1]: https://www.aliexpress.com/item/32847055230.html

body:
There is a discussion thread on [Quora][1] discussing finger print scanners that provide raw output. The Quora author recommends a  [Futronic][2] device which comes with an API for raw image collection. They also discussed [NeuroTechnology][3] which apparently also has a downloadable image database. Looking at the neurotechnology website they also have some interesting SDK options. These of course all give you an image not the binary output you described.

It strikes me that a binary encoded output would likely be the result of a recognition algorithm, or a resultant / generated security key. Not sure that is what you intended by your question?

There are a [mass][4] of academic papers on open finger print scanning algorithms.

I did a bit of google searching for people capturing raw data from Arduino compatible devices. Didn’t find anyone saying it was easy. Please post back here if you make progress.

Hope this helps get you started.

  [1]: https://www.quora.com/Are-there-any-fingerprint-scanners-that-provide-raw-images-as-output
  [2]: https://www.futronic-tech.com/pro-detail.php?pro_id=1535
  [3]: https://www.neurotechnology.com/verifinger.html
  [4]: https://scholar.google.com.au/scholar?hl=en&as_sdt=0,5&q=open fingerprint scanning algorithm&btnG=

body:
I'm a software engineer that works with biometric sensors. The answer is, it will vary **greatly** depending on the scanner you've chosen. Some hardware solutions have built-in subject enrollment and database matching; some simply collect an image and return it in an appropriate format- sometimes an image file (e.g. PNG), or a template file (a binary representation of a subject and/or their fingerprint(s)).

For you, I **highly** recommend avoiding the pain of interfacing with an Arduino at such a low level, and use a Raspberry Pi or other full computer to write a collection program with your vendor's SDK. Linux is supported by all the major players I've worked with, and that will drastically ease integration with whatever database or website you have in mind. Many vendors have built-in enrollment, storage, and matching examples as part of their SDKs that will help you get up and going in short order

**EDIT**: As this is an Arduino SE, I realize **I should give a microcontroller-friendly answer as well**. There are indeed [scanners like this][1]. It does templating and matching on board if I understand correctly, and the provided library does indeed allow you to transfer those templates over serial. Granted, you still have to get that data from your Arduino to a computer of some sort, so I still think a Pi is the shorter putt ;)

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


body: I bought a board which the above MCU is the atmega328p. Since I haven't used atmel MCU before, now it's a bit confusing. Are the ATMEGA and STM32 programmers not universal? What programming methods can this chip support? Is there serial programming or SWD programming? Need help. Many thanks!

title: As a novice, how do I program my Atmega328p?

Answers: 2

body:
> **Are the ATMEGA and STM32 programmers not universal?**

They are not the same. As far as I know their programming arrangements are completely distinct.

> **What programming methods can this chip support?**

- Traditional AVR In-Circuit-Serial-Programming ([ICSP](https://en.wikipedia.org/wiki/In-system_programming)) using a 2x3 header pin connector and one of a variety of programmers such as the STK500 which has low-cost clones like the [Pololu AVR programmer](https://www.pololu.com/product/1300) (less than $10). These programmers typically connect to a PC's USB port and can be used either with the software development tools from Atmel (now Microchip) or using the Arduino integrated development environment (IDE) which uses a program named avrdude to communicate with the ATMega328P (or other AVR family MCUs). ICSP is sometimes called In System Programming (ISP). It uses the MCU's [SPI](https://en.wikipedia.org/wiki/Serial_Peripheral_Interface) interface and you have to be careful what other circuitry is attached to those pins when you program the device.

- Serial-port programming by communicating with a pre-loaded "bootloader" program installed in the ATMega328P. This is the normal way to use the Arduino IDE but it depends on having that bootloader installed. Most bare ATMega328Ps are sold without this bootloader installed. All "Arduino" boards will have a bootloader installed in their MCU and many will have a serial-to-USB interface on-board so that the board can be plugged in to a PC directly. Otherwise you would need a USB-to-Serial interface like the [Adafruit FTDI friend](https://learn.adafruit.com/ftdi-friend) or many others.

There is also a [high-voltage programming](https://microchipsupport.force.com/s/article/How-to-perform-High-Voltage-Programming-on-AVR-devices) method but that isn't something a novice would need to use. I believe it is most often needed when you have configured the MCU in such a way that the above methods cannot be used. For example after having disabled the reset pin so it can be used as an IO pin that can be pulled to GND without resetting the MCU.

You can use an Arduino to emulate a programmer and use that to program boards that lack a USB serial interface. This is called [Arduino as ISP](https://www.arduino.cc/en/Tutorial/BuiltInExamples/ArduinoISP)

Microchip's newer generation of AVR MCUs use a different programming method than ICSP called [UPDI](http://www.technoblogy.com/show?2OJT).

body:
> What programming methods can this chip support? Is there serial programming or SWD programming?

The Arduino IDE (a free download) supports programming in C++. The IDE pre-processes your code (which they call a "sketch") slightly but it is still C++.

You can drop into assembler if you absolutely must, but the C++ compiler does a good job of producing efficient code, almost always.

With the assistance of a serial interface (many Arduinos, like the Uno, have one built-in connected to a USB interface) you can quickly and easily upload your code. The wherewithal to do that is built into the IDE.


body:
I have a cheap wireless doorbell. My plan is to include an ESP8266 and power the doorbell from the microcontroller 3.3V output as the doorbell also runs on 3V

I specifically chose a model with a LED, as I thought it should be easy to use the LED as a trigger on the ESP8266 and consume as a digital input.

I've soldered two wires from the LED positive and negative solder points. What I find strange is that I measure 3V between the PCB ground and the positive LED wire when the doorbell is not triggered. If I measure between the negative LED wire and positive LED wire, I see a voltage spike corresponding to each LED flash (it flashes 5 times). I plan to debounce this in software.

I did not expect to measure a voltage when the doorbell is not triggered between the positive LED wire and the PCB ground, and this will definitely not work as I intended.

*Disclaimer: I'm not an electronic engineer, and my test equipment consists of a multimeter.*

I've included a photo of the PCB. It is labelled "QH-823A-19" but searching for this on the Internet has provided no usable information.

What have I tried?
1. I've tried to trace the tracks running to the LED solder points, but the tracks run under some components which makes this hard
2. I've tried to measure different points on the board for a positive 3V spike when the LED flashes, no success

Any advice on how to achieve this? Am I going about this the wrong way?

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

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

title: How to read wireless doorbell's indicator LED circuit

Answers: 2

body:
Your LED is connected between V+ and the GPIO of the microcontroller. This is a common arrangement because historically microcontrollers have been able to sink more current than they can source. It's also easier to make a "low side" constant current source, which this custom chip may have, to reduce the number of external components needed.

To read the state you need to take the voltage at the cathode of the LED referenced to the ground of the doorbell circuit. This will give you a voltage at or near the board supply voltage when the LED is off, and a lower voltage (near zero but probably not zero) when the LED is on.

If the voltages are within the threshold voltages VIH and VIL of the ESP8266 then you can just directly read that level as a logic level. If not then you may need to "condition" the voltage to give proper logic levels.

For example you could use a comparator (an op-amp running in "saturated" mode) to compare that voltage to a single threshold voltage that is roughly half way between the HIGH and LOW voltages. That would then swing the output between the supply and ground voltage levels giving you a much cleaner signal.

Or you may use an analog input (the ESP8266 only has one, and that is quite a crude one with only 1.1V maximum allowed on it, so a voltage divider will be needed) to measure the voltage and do the comparison in software.

Another option would be to remove the LED completely and replace it with an optocoupler, thus making the LED itself an electronically operated button to the ESP8266. This will also keep the ESP8266 ganvalically isolated from  the doorbell.

body:
# Schmitt Trigger using a Comparator

If you follow @Majenko's advice of using a comparator, you could add some hysteresis to it with a few resistors to create an inverting [Schmitt trigger][1]. This will increase the noise immunity and thus reduce the noise going to the ESP8266. The following simulation has a noisy input transformed into square pulses. It also performs a small level shift from an input of 3 V to an output of 3.3 V.

<a href="https://www.falstad.com/circuit/circuitjs.html?ctz=CQAgjCAMB0l3BWcMBMcUHYMGZIA4UA2ATmIxEMJCQUmoFMBaMMAKAEMRs0Q08QALN174Q-bNGxRk8OL2h5IGFhjyEEWQgISVwsUsSGRDGFAJTF+YWZFYB3QcL6OUvU1FYAnF29co8-JiudNbw9rwBvGZcPCjRtg7+gdFJvh6JkXECEVYC2bbeqWB5OWJ0IbJepUGl2NhUFWEA5rX1tYT85awA8j7OAooinR4ASqWDqQPSdAJ0ElLlUNAI4dwhxH7RYBseAG7ghOub2dvB4IIhekjly6xjYIfgO2D+T2cQoTfX07cADlEnHZZLhtRYJAEgqgoHSQ9K8GF1KGRREef7QqEpBGg6bhdEQ1LA2wAe3A2WEITixDmS3gEEuADUAJYAO1YJOIMWks0s1CWdPO9KJAFcAC5s0mcmYWOjXaAfXggDl0JnMgA6AGdduqNYLRawgA">

*Figure 1 – Schmitt trigger circuit.*

[![Schmitt trigger simulation waveforms][2]][2]

*Figure 2 – Schmitt trigger simulation.*

# Hysteresis versus Low-Pass Filtering

There is a subtle difference between hysteresis and low-pass filtering.

The following experimental circuit, Figure 3, demonstrates this difference with an interactive simulation where you can click on the switches to add/remove noise and add/remove filtering.

The low-pass filter has a cut-off frequency of 40 Hz.

I've set the high-going threshold, Vt+, to 2.31 V and the low-going threshold, Vt-, to 1.54 V. I calculated these figures from the [74HC14 datasheet][3] using the thresholds for 3 V at 25°C and scaling them for 3.3 V.

<a href="https://www.falstad.com/circuit/circuitjs.html?ctz=CQAgjCAMB0l3AmcMGIOxoMyQBwIGwCchaIArJOSACybkCmAtGGAFAAe5mOyS+CEMJDI1w1EAFkAwgFUAOgGcAxgEsATkoCuKgC5qAnqwBGIfJiSYypBNxA4RkDiEaEeQvshHiw4gCIB7fzUjegAbUMVVDW09QxM0fBBLHmYhO0THACUkpEJE8xoeSkpqSjpiqGgyVjB+HPB8MqRUHiQAE3oAMwBDTVCdRlD6NvAoMZhITFY1etqmkDyxoUcAd3rMTES5pM2oVjWChFL13dX6loXEi4RWTudakAQj8+eCsCrKyBu17Y2rnB4fz2awQAJ2+Rw4iBWXuV2ejGorWelCQx3eInR4yqrGyoJ4izxhXGNDK0HKWOqAHkaATcKY6RcII4AOYNMq7X74Ip7MA4Oi0Zp06i07kwDFVcQIMkQTBkvacagYsCEengJ6iMBITI3JRJSGPMHcKGnJLQHDEC2Wq1oJikd6EWoENBwagINCg1CkCaQNgHfUXAWPOmOT1B1oMumLcQANVCKgAdgBrG6ho1hvXiKMgaOdFT9ehqYasUPCq5CxZZ6P+TQ6aYG-H-cPc5aOGaE66Gk0txwKyCSzAqqwo10apBoagACSkPgANIpowM5ABHdHUaNzhQLuQAB2XUswYGjdfbdLTF0o3dYADdLuBCEhtsqkBeSSjiWL9umO03Hk4WIIyG8agANIbwkAAOX8FQFHoVgFAzdMzzBF8elCGCnBcOEREYNAVSeHgwOzBNWAAZS-OltnPUZUJgsZvlvC4CWRT8mO8RpHmYtYRVvJ89lDRZeIrRIYzjJM2E4HwRCOZpNUeRVRxASDoPoRQFBWXQlAACycA8pMRJI0FaMgIEIgAxPMdALVT1J0LTWH8cA6HwcQLyeB0kk+OAmUeRyPOjYiHJVZyljckpoAtXC3LIPBuDAcpYC8uiFj80TEzYByECClySVcKhvX4BwfMylKE2Teyg1MbLNUy0lFURLASCeah8HwIQXISn0ktQPzc3zQs2nKsARGC1yatNeL4G8iAqxrVggA">

*Figure 3 – Circuit showing difference between hysteresis and low-pass filtering.*

Hysteresis provides greater noise immunity and reshapes a slowly changing signal into a square wave ready for a digital input. But it can't filter out noise spikes that breach its threshold levels. These spikes would cause the Schmitt trigger to output square pulses. See the orange section of Figure 4.

Low-pass filtering filters out high frequency spikes which could breach the upper and lower thresholds of a Schmitt trigger. See the green section of Figure 4. Note that it also introduces a phase shift. If the noise were created by switch-bounce, then the low-pass filter would be performing debouncing. The blue section represents the ideal world where there is no noise, no need of filtering, and the output is in phase with the input.

[![Simulation of hysteresis versus filtering.][5]][5]

*Figure 4 – Simulation of hysteresis versus low-pass filtering.*

  [1]: https://en.wikipedia.org/wiki/Schmitt_trigger
  [2]: https://i.stack.imgur.com/iLE95.png
  [3]: https://www.onsemi.com/pdf/datasheet/mc74hc14a-d.pdf
  [4]: https://i.stack.imgur.com/vxEDh.png
  [5]: https://i.stack.imgur.com/BVBsd.png


body:
I'm using an ESP32 and SQLite3 from https://github.com/siara-cc/esp32_arduino_sqlite3_lib
Everything is OK except the ALTER TABLE command.
When I try

        ALTER TABLE TAB_JOUEUR RENAME TO TAB_NEW_JOUEUR

I get a "SQL logic error". I just see that the default source code will not compile with the ALTER TABLE option if SQLITE_OMIT_ALTERTABLE is defined.
So at the begining of the .c source, I added:

     #if defined(SQLITE_OMIT_ALTERTABLE)
       #undef SQLITE_OMIT_ALTERTABLE
    #endif

But result is the same.... Any idea?

title: ESP32 and SQLite - ALTER TABLE problem

Answers: 1

body:
Well. After searching a lot here's the way todo a "RENAME" for a table. It's a bit tricky...
Renaming table in ESP SQLite is very interesting because SQLite has very limited features for editing table. So you can't add field, remove and so on. The only way is to create a new tmp table, copy the content of the orginal one into this tmp table, drop the original one and rename the tmp with the name of the new one.
DROP TABLE is OK with the ESP version of SQLite, but as said in the question, ALTER RENAME don't work.

So here is the way to do:

**1-What tables do we have?**

When we init the ESP, we call

      sqlite3_initialize();

and then we give SQLite the file it will use for saving data with a call to sqlite3_open() giving the name of a previously created file.

All our own tables will be saved into this file but also definitions of our tables. For that, SQLite create system table. So in the database we have our own tables but also the SQLlite system tables

**2 - The data base schema table**

One of the most important table is the database schema one. Its name depend on the version of SQLite. With the version we use on ESP8266 or ESP32, its name is *sqlite_master* .
This table has 4 fields:

 - type. Value can be  'table', 'index', 'view', or 'trigger'
 - name. Value is the name of the data. If type='table', name is the name of
   the table defined in this record
 - tbl_name. Name of the table. So if type='name', tbl_name = name
 - rootpage. An int which is the index in the Btree used by SQLite to
   access the data
 - sql. The code to create the table

**3-Check the schema**

To check the content of this specific table, just make a  CREATE TABLE then SELECT * FROM sqlite_master

Here is what I've done and the result:

The CREATE TABLE CALL:

*create TABLE    IF NOT EXISTS     TAB_JOUEUR ('tjoueur_id' INTEGER,"tjoueur_prenom" TEXT   , "tjoueur_nom" TEXT,   "tjoueur_ville" TEXT ,  PRIMARY KEY("tjoueur_id" AUTOINCREMENT))*

The result of the SELECT * FROM sqlite_master

 - type = table
 - name = TAB_JOUEUR
 - tbl_name = TAB_JOUEUR
 - rootpage = 2
 - sql    = CREATE TABLE TAB_JOUEUR ('tjoueur_id'
   INTEGER,"tjoueur_prenom" TEXT   , "tjoueur_nom" TEXT,"tjoueur_ville" TEXT ,  PRIMARY    KEY("tjoueur_id" AUTOINCREMENT))

and then

 - type = table
 - name = sqlite_sequence
 - tbl_name = sqlite_sequence
 - rootpage = 3
 - sql = CREATE TABLE sqlite_sequence(name,seq)

As you can see the sql field relative to the table "TAB_JOUEUR" as the CREATE call but it's not a pure copy of the original CREATE call. The original one as "create" in lower case, had extra spaces and has a "IF NOT EXISTS" which we don't have in the sql field of sqlite_master. But the part between the () is **exactly** the same (single quote for tjoueur_id, double for tjoueur_nom, extra spaces...)

**4 - The trick**

In order to rename a table, you just have to make a SELECT on sqlite_master in order to get the record of the table you want to rename. Then, change the content of the sql field to replace the "old name" by the "new one", and perform an update, using the rootpage as id.
So like that:

    void alter_table(String old_name, String new_name){

 int rc ;
 String data_rootpage;
 String data_sql;
 int pos_start;
 char *err_msg = 0;

 String query_sql = "SELECT rootpage,sql FROM sqlite_master WHERE type='table' AND name = '"+old_name+"'";

 const char* sql = query_sql.c_str();
 rc = sqlite3_prepare_v2(db_handle, sql, -1, &stmt, NULL);
 rc = sqlite3_step(stmt);
 data_rootpage = (const char *)sqlite3_column_text(stmt, 0);
 data_sql = (const char *)sqlite3_column_text(stmt, 1);

 // Find first ( in the string
 pos_start = data_sql.indexOf ('(');
 String tmp = "CREATE TABLE "+new_name+" "+data_sql.substring(pos_start);

 query_sql = "UPDATE sqlite_master SET sql='"+tmp+"', name='"+new_name+"', tbl_name='"+new_name+"' WHERE rootpage = "+data_rootpage;
 sql = query_sql.c_str();
 rc = sqlite3_exec(db_handle, sql, 0, 0, &err_msg);

    sqlite3_close(db_handle);
 sqlite3_initialize();
 sql_connect("/littlefs/transcom.db", &db_handle);}

It's basic and don't have test (you must add some!). I start by searching for the record concerning the "old_name" table. In the sql field I search for the "(" and then I replace the first part of the sql field data with the new name of the table.
Then I update. Notice I don't escape the quote because I've previously make a CREATE call without any ' or " (easier!)

After that, I perform a sqlite3_close() then re-open with sqlite3_initialize(); If you don't do that, SQLite don't take change in account (maybe there is a cache for data).

**5 - Great but... not enought!**

If you try this, you'll get an error on the update call. That's because for you, "user", sqlite_master is a read only table. So you can't update it. In order to prevent writing on some table (like the sqlite_master one), when SQLite create it, it sets a "read only" flag. The trick is to edit the source code in order to give to this flag, the value of "read and write".
In the sqlite3.c of the LIB, it's a line 17420. You'll see:

      #define TF_Readonly        0x0001    /* Read-only system table */

Just change it by

       #define TF_Readonly        0x0000    /* Read-only system table */

So when SQLite will create a system table, it will set a read+write flag and so, you would be able to update the sqlite_master table. You need to compile again de lib (on Arduino IDE, just select a wrong board, try to compile, get an error, select ESP32 and compile again and the IDE will perform a full compilation of the lib)

If you have trigger, and some other specific feature, maybe it would be nice to check the result of the select * from sqlite_master in order to see if some records need also to be updated. But for basic table, this will do the job.

Hope this will help.

***Edit***

If you add an index (or more than one) to your table, you'll have also to update 'index" records from sqlite_master. They are like that:

 - type = index
 - name = index_ttest_nom
 - tbl_name = TAB_TEST
 - rootpage = 6
 - sql = CREATE UNIQUE INDEX index_ttest_nom ON TAB_TEST (ttest_nom)

So just update the tbl_name value giving the new name of the table, and update the sql field the same way.


body:
I need help getting my MPU 6050 to actually give me data. As of right now, my program is only reading 0s from the gyroscope and when I move it, the values all go to -1 and the program just stops until I close and reopen the serial monitor. I know this question has been asked multiple times before, but I've already looked at each of those questions and tried all of the fixes listed there, but not a single one has worked. The I2C scanner does find the sensor at 0x68, but that's only thing that works. These are all brand new boards that I got a couple days ago.

I've tried every library and every example sketch I could find. I've switched to 2 new boards. I've even tried looking at the [datasheet][1] for the MPU 6050 and reading/writing the registers directly and still I'm getting no results. The serial monitor either stays blank, shows only 0s or -1s, or just gives me garbage values that change randomly. Please help me.

I've wired the sensor like this (I'm currently on an Arduino Uno):

VCC ==> 5V\
GND ==> GND\
SCL ==> A5\
SDA ==> A4\
AD0 ==> digital 13 (set to LOW)

And the code I'm using is this:

  [1]: https://invensense.tdk.com/wp-content/uploads/2015/02/MPU-6000-Register-Map1.pdf

```
#include <Wire.h>

const int addressPin = 13;

int gyroX, gyroY, gyroZ;

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

  //designating pins as I/O
  pinMode(addressPin, OUTPUT);

  //setting IMU address to 0x68 (LOW)
  digitalWrite(addressPin, LOW);

  initializeSensor();
}

void loop() {
  readGyro();

  Serial.print(gyroX);
  Serial.print("    ");
  Serial.print(gyroY);
  Serial.print("    ");
  Serial.println(gyroZ);
}

void initializeSensor() {
  //performing full device reset, disables temperature sensor, disables SLEEP mode
  Wire.beginTransmission(0x68);

  Wire.write(0x6B);
  Wire.write(0b10001000);

  Wire.endTransmission();

  //writing to gyro config register
  Wire.beginTransmission(0x68);

  Wire.write(0x1B);
  Wire.write(0b00001000);

  Wire.endTransmission();
}

void readGyro() {
  //requesting data from gyro data registers
  Wire.beginTransmission(0x68);

  Wire.write(0x43);

  Wire.endTransmission();

  Wire.requestFrom(0x68, 6);

  gyroX = Wire.read()<<8|Wire.read();
  gyroY = Wire.read()<<8|Wire.read();
  gyroZ = Wire.read()<<8|Wire.read();
}
```

P.S. I few weeks ago I posted a question about I2C devices and in it, I said I had managed to successfully read data from the sensor, but I found out later those were garbage numbers. :(

title: MPU6050 does not give output

Answers: 3

body:
From the [MPU-6000/MPU-6050 Register Map and Descriptions][1]:

- Section 4.28, Register 107 – Power Management 1 PWR_MGMT_1, pages 40 to 41:

   > Note:<br>
   > When using SPI interface, user should use DEVICE_RESET (register 107) as well as SIGNAL_PATH_RESET (register 104) to ensure the reset is performed properly. The sequence used should be:
   > 1. Set DEVICE_RESET = 1 (register PWR_MGMT_1)
   > 2. Wait 100ms
   > 3. Set GYRO_RESET = ACCEL_RESET = TEMP_RESET = 1 (register SIGNAL_PATH_RESET)
   > 4. Wait 100ms

- Section 4.26, Register 104 – Signal Path Reset SIGNAL_PATH_RESET, page 37:
   > Note: This register does not clear the sensor registers. The reset initializes the serial interface as well.

 - Section 3, Register Map, page 8:
   > The reset value is 0x00 for all registers other than the registers below.
   > - Register 107: 0x40.
   > - Register 117: 0x68.

This means that the PWR_MGMT_1 register defaults to sleep mode after a reset so it needs to be rewritten to disable sleep mode after commanding a reset.

```cpp
void initializeSensor()
{
  //
  // Perfrom full reset as per MPU-6000/MPU-6050 Register Map and Descriptions, Section 4.28, pages 40 to 41.
  //

  // performing full device reset, disables temperature sensor, disables SLEEP mode
  Wire.beginTransmission(0x68);  // Device address.
  Wire.write(0x6B);              // PWR_MGMT_1 register.
  Wire.write(0b10001000);        // DEVICE_RESET, TEMP_DIS.
  Wire.endTransmission();
  delay(100);                    // Wait for reset to complete.

  Wire.beginTransmission(0x68);  // Device address.
  Wire.write(0x68);              // SIGNAL_PATH_RESET register.
  Wire.write(0b00000111);        // GYRO_RESET, ACCEL_RESET, TEMP_RESET.
  Wire.endTransmission();
  delay(100);                    // Wait for reset to complete.

  // Disable SLEEP mode because the reset re-enables it. Section 3, PWR_MGMT_1 register, page 8.
  Wire.beginTransmission(IMUAddress);   // Device address.
  Wire.write(0x6B);                     // PWR_MGMT_1 register.
  Wire.write(0b00001000);               // SLEEP = 0, TEMP_DIS = 1.
  Wire.endTransmission();
}
```

In the following code I've:
1. Modified `readGyro()` to implement 3 states (Request, Wait, and Read) and return `true` when 6 bytes have been read from the MPU-6050.

2. Added [Blink Without Delay][2] to `loop()` to see whether the MCU freezes which requires changing the ADO pin from pin 13 (the built-in led) to another pin, i.e. pin 12.

3. Added several `Serial.print()` statements for debugging to see where things go wrong.

4. Tweaked the code in response to comments.

```cpp
#include <Wire.h>

const byte IMUAddress = 0x68;   // Added for readability and maintainability.
const byte addressPin = 12;     // Changed from 13 to 12 because 13 is built-in LED.

int gyroX, gyroY, gyroZ;

void setup()
{
  Wire.begin();
  Serial.begin(115200);
  Serial.println(F("\n\nMPU-6050 Test\n"));

  // Designating pins as I/O.
  pinMode(addressPin, OUTPUT);
  pinMode(LED_BUILTIN, OUTPUT);  // Added LED for heartbeat signal.

  // Setting IMU address to 0x68 (LOW).
  digitalWrite(addressPin, IMUAddress & 1);  // Added bit mask of bit 0.

  initializeSensor();
}

void loop()
{
  //
  // TASK 1: Blink without delay to indicate that MCU hasn't frozen.
  //
  const unsigned int INTERVAL = 250;
  unsigned long current_timestamp = millis();
  static unsigned long previous_timestamp = current_timestamp;
  static bool led_state = false;
  if (current_timestamp - previous_timestamp >= INTERVAL)
  {
    led_state = !led_state;
    digitalWrite(LED_BUILTIN, led_state);
    previous_timestamp += INTERVAL;
  }

  //
  // TASK 2: Read gyro.
  //
  if (readGyro())
  {
    Serial.print(gyroX);
    Serial.print(F("    "));
    Serial.print(gyroY);
    Serial.print(F("    "));
    Serial.println(gyroZ);
  }
}

void initializeSensor()
{
  //
  // Perform full reset as per MPU-6000/MPU-6050 Register Map and Descriptions, Section 4.28, pages 40 to 41.
  //

  Serial.print(F("Performing full reset of MPU-6050..."));

  Wire.beginTransmission(IMUAddress);   // Device address.
  Wire.write(0x6B);                     // PWR_MGMT_1 register.
  Wire.write(0b10001000);               // DEVICE_RESET, TEMP_DIS.
  Wire.endTransmission();
  delay(100);                           // Wait for reset to complete.

  Wire.beginTransmission(IMUAddress);   // Device address.
  Wire.write(0x68);                     // SIGNAL_PATH_RESET register.
  Wire.write(0b00000111);               // GYRO_RESET, ACCEL_RESET, TEMP_RESET.
  Wire.endTransmission();
  delay(100);                           // Wait for reset to complete.

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

  // Disable SLEEP mode because the reset re-enables it. Section 3, PWR_MGMT_1 register, page 8.
  Serial.print(F("Disabling sleep mode of MPU-6050..."));
  Wire.beginTransmission(IMUAddress);   // Device address.
  Wire.write(0x6B);                     // PWR_MGMT_1 register.
  Wire.write(0b00001000);               // SLEEP = 0, TEMP_DIS = 1.
  Wire.endTransmission();
  Serial.println(F(" Done."));

  //
  // Writing to gyro config register.
  //
  Serial.print(F("Configuring gyro of MPU-6050..."));
  Wire.beginTransmission(IMUAddress);   // Device address.
  Wire.write(0x1B);                     // GYRO_CONFIG register.
  Wire.write(0b00001000);               // +/-500 deg/s.
  Wire.endTransmission();
  Serial.println(F(" Done."));
}

typedef enum State
{
  Request,
  Wait,
  Read
};

bool readGyro()
{
  static State state = State::Request;

  switch (state)
  {
    case State::Request:
      // Request data from gyro data registers.
      Serial.print(F("Requesting data from gyro..."));
      Wire.beginTransmission(IMUAddress);   // Device address.
      Wire.write(0x43);                     // GYRO_XOUT_H register.
      Wire.endTransmission(false);          // Restart connection, i.e. keep alive.
      Wire.requestFrom(IMUAddress, 6);      // GYRO_XOUT_H, GYRO_XOUT_L, GYRO_YOUT_H, GYRO_YOUT_L, GYRO_ZOUT_H, GYRO_ZOUT_L.
      Serial.println(F(" Done."));
      state = State::Wait;
      Serial.print(F("Waiting for data from gyro..."));
      break;

    case State::Wait:
      // Wait for data to arrive into buffer.
      if(Wire.available() < 6)
      {
        //Serial.print(F("."));
        Serial.print(F(" "));
        Serial.print(Wire.available());  // Added to show bytes received.
      }
      else
      {
        Serial.print(F(" "));
        Serial.print(Wire.available());  // Added to show bytes received.
        Serial.println(F(" Done."));
        state = State::Read;
      }
      break;

    case State::Read:
      // Read data from gyro registers.
      Serial.print(F("Reading gyro data..."));
      gyroX = Wire.read() << 8 | Wire.read();
      gyroY = Wire.read() << 8 | Wire.read();
      gyroZ = Wire.read() << 8 | Wire.read();
      Serial.println(F(" Done."));
      state = State::Request;
      return true;  // Indicate data was received.
      break;
  }

  return false;  // Indicate no data received yet.
}
```

**Update based upon RowanP's answer**

While concentrating on the software issues I missed a crucial piece of information from the other datasheet ([MPU-6000/MPU-6050 Product Specification][3]), i.e. the electrical characteristics in Sections 6.3 and 6.4 on pages 14 and 15 showing a Vdd range of 2.375 V to 3.46 V:

[![Electrical Characteristics of MPU-6050][4]][4]
[![Vdd power supply of MPU-6050][5]][5]

**6.4 Electrical Specifications, Continued**
[![Digital inputs and outputs of MPU-6050][6]][6]

This will require [level shifters][7]  on the signals between the 3.3 V MPU-6050 and the 5 V Arduino.

  [1]: https://invensense.tdk.com/wp-content/uploads/2015/02/MPU-6000-Register-Map1.pdf
  [2]: https://www.arduino.cc/en/Tutorial/BuiltInExamples/BlinkWithoutDelay/
  [3]: https://invensense.tdk.com/wp-content/uploads/2015/02/MPU-6000-Datasheet1.pdf
  [4]: https://i.stack.imgur.com/DQsKX.png
  [5]: https://i.stack.imgur.com/T0Y6x.png
  [6]: https://i.stack.imgur.com/j79QD.png
  [7]: https://www.falstad.com/circuit/circuitjs.html?ctz=CQAgjCAMB0l3BWcMBMcUHYMGZIA4UA2ATmIxAUgoqoQFMBaMMAKADMQ8AWPcDQzjxCYUIbKLDQkMSChYAnEBgSiRSlXwFUw8SApDEuXTQaPCMo7bpYB3TuPOjlqi1FvqXownl5q5dvEJjNUNg1z07UMdkfGi5ACUPE2dwFF4qKi4qbGhsKHyYBBZEqLB U2MwNIKQLOoMqCl3FLKBbl5WtztvXmxsNqE rXd2sX6Y3vG9AHNBSYHe7wKWAGcJ6J1YofyINgBDABsVulWQHrGBc7VtEH2jk4APM7BiYUJLrleiV8rRAGUAMIAGVYTx0Dm yEInlqqRAgKBcieGBeBnIxDwSE2sJQxgAQgBLBgAEwJ8joAGMAC4EgD2ADtDgAdFYHOgANzoBxZKwAFgS2FS6PIWLTYUF8lkMfVYNJhLC8gjWGKPpLINKuNBSBjmAhvDxCBhIHkZHAIFQvGJ4cC5EA

body:
A while ago while figuring out I2C difficulties of my own I did some research and listed out all the failure modes and test techniques I could think of regarding I2C. See https://arduino.stackexchange.com/questions/79775/i2c-protocol-doesnt-work-properly/81001#81001. I routinely go through the list now to tick off the things I need to check to get a new I2C connection working, usually it's something simple (fingers crossed). Do you have access to an oscilloscpe?

(Edit) This old post seems to describe a similar problem (only getting zeros) https://arduino.stackexchange.com/questions/37629/mpu6050-doesnt-work. The consensus there was that the **3.3V MPU6050 had been connected to a 5V UNO, frying the MPU6050 chip**. That sounds very like your situation.

body:
I used 5 V from my Arduino to power the MPU6050, and it was fine. Check out: https://www.instructables.com/How-to-Make-a-Robot-Car-Drive-Straight-and-Turn-Ex/, which has very similar code.

Also, I typically avoid pin 13, since it performs some special additional function, unlike pin 2 to 12.


body:
I know this module is super old but the network I am on still uses GPRS so should work.

This is the module:
[![enter image description here][1]][1]
I am using the Adafruit example scipt FONAtest. I can connect to GPRS

``` ---> AT+CIPSHUT
 <--- SHUT OK
 ---> AT+CGATT=1
 <--- OK
 ---> AT+SAPBR=3,1,"CONTYPE","GPRS"
 <--- OK
 ---> AT+SAPBR=3,1,"APN","live.vodafone.com"
 <--- OK
 ---> AT+CSTT="live.vodafone.com","",""
 <--- OK
 ---> AT+SAPBR=3,1,"USER",""
 <--- OK
 ---> AT+SAPBR=3,1,"PWD",""
 <--- OK
 ---> AT+SAPBR=1,1
 <--- OK
 ---> AT+CIICR
 <--- OK
FONA>
```

There is credit on the SIM so it has data for sure, I can also send SMS.

There are several different approaches people seem to take (altering AT commands) to persuade this device to work, pretty sure I have tried all of them :) I always get a timeout when trying to read or GET a webpage.

I have tried several combinations via terminal and I seem to connect ok but get no further. It has worked once, but that was in a different part of town.

How do I check that the GPRS is actually connected? Any troubleshooting tips?

There is a dedicated 2A 5V connected to the unit, it isn't dropping out AFAIK. Do you have a rock-solid AT sequence that always works?

Also, there seem to be SAPBR commands that don't work at all, not sure why?

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

title: SIM800L and UNO can't request web page

Answers: 2

body:
It highly depends on the URL you are trying to fetch.
Those modules DO NOT understand secure HTTP/S. They only understand plain unsecure HTTP.
Most web pages nowdays don't offer unsecure HTTP access and always redirect the request to a HTTP/S server. So in my opinion the usefulness of those devices is very limited when it comes to internet access.

If you have full control over the web server you should disable the enforcement of a secure connection.

Beyond that. The sequence you posted is just for activating GPRS.

I also found the FONA sample for fetching a page not very reliable but I was able to request the page multiple time. Perheps you have your module in a place with low signal strenght. Does your module offer an u.fl connector for a better antenna?

body:
Don't know why, I had to manually set the DNS t0 8.8.8.8 using `AT+CDNSCFG?`

It had DNS entries in there but they didn't want to resolve for some reason.


body: I design a PCB that one of its components is a 3.3v Pro Mini. Since I want it versatile regarding powering the PCB (3.3v or 5.0v) I want to know if it is a good practice to supply 3.3v to Pro Mini's RAW pin( rather than to the VCC Pin ).

title: Pro Mini - Using RAW pin for 3.3v input

Answers: 1

body:
It is not ideal, no.  The RAW pin first goes into a 3.3V voltage regulator whose dropout voltage is up to 200mV (worst case).  That means that you would get around 3.1V out, and it wouldn't be properly regulated.

Oh, it would *work*, but the power won't be stable, which means that any analogue readings that you make that don't directly use the (shakily) regulated "3.3V" (now 3.something else V) in the generation of the analog signal (such as a simple potentiometer) will be inaccurate.

Also output logic voltages will be lower than expected which may have an effect if communicating with something whose upper input threshold is at or near the 3.3V mark (such as many 5V devices).


body:
I'm currently using the MPU-6050 accelerometer to receive the acceleration and angular velocity data. I'm trying to process the data for my experiment but I can't understand the exact meaning of it. I have threee questions about the situation. I append the arduino code below.

First, I happen to know that the AcX value of the code below means how much the sensor is inclined along the x axis. Is there other way to get acceleration directly? or Do I have to use formula(v = v_0 + a*t)?

Second, for the gyro sensor, I can't understand the meaning of the value. Does it sends the angular velocity or angular acceleration and if it is one of these, what's the limit?

 Third, according to code, it receives data in the form of 2^14(14bit) but sometimes it sends value way over the limit. How can I translate raw data to rather regular unit like degree and rad?

Thank you

```#include <Wire.h>
const int MPU_addr=0x68;  // I2C address of the MPU-6050
int16_t AcX,AcY,AcZ,GyX,GyY,GyZ;

void setup(){
  Wire.begin();
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x6B);  // PWR_MGMT_1 register
  Wire.write(0);     // set to zero (wakes up the MPU-6050)
  Wire.endTransmission(true);
  Serial.begin(9600);
  Serial.println("CLEARDATA");
  Serial.println("LABEL,TIME,AcX,AcY,AcZ,GyX,GyY,GyZ");
}

void loop(){
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(MPU_addr,14,true);  // request a total of 14 registers

  // deviding the 16bit input??
  AcX=Wire.read()<<8|Wire.read();  // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
  AcY=Wire.read()<<8|Wire.read();  // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
  AcZ=Wire.read()<<8|Wire.read();  // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
  GyX=Wire.read()<<8|Wire.read();  // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
  GyY=Wire.read()<<8|Wire.read();  // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
  GyZ=Wire.read()<<8|Wire.read();  // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)

  //Serial.print("AcX = ");
  Serial.print(AcX);
  Serial.println(",");
  //Serial.print(",");
  //Serial.print(" | AcY = ");
  //Serial.print(AcY); Serial.print(",");
  //Serial.print(" | AcZ = ");
  //Serial.print(AcZ); Serial.print(",");
  //Serial.print(" | GyX = ");
  //Serial.println(GyX);
  //Serial.print(" | GyY = ");
  Serial.println(GyY); //Serial.print(",");
  //Serial.print(" | GyZ = ");
  //Serial.println(GyZ);
  delay(200);
}

title: Accelerometer value meaning

Answers: 1

body:
> Is there other way to get acceleration directly? or Do I have to use
> formula(v = v_0 + a*t)?

The code appears to be currently retrieving the raw X, Y & Z acceleration and storing it in AcX, AcY & AcZ.  The equation "v = v_0 + a*t" appears to be [deriving velocity][1].  So the question is confusing.

> ...for the gyro sensor, I can't understand the meaning of the value. Does
> it sends the angular velocity or angular acceleration

The accelerometer sensors measure acceleration.  As the last question ultimately asked for angles, the gyroscope is not needed.  However, on page 12 in the [MPU-6050 specifications][2] the dimensions of the gyroscope is given in degrees per second or angular velocity.  Likely the mechanism within the chip depends on the [Coriolis effect][3]

> ...and if it is one of these, what's the limit?

On the same page [the MPU-6050 chip specification][2] shows a table containing values such as GYROSCOPE SENSITIVITY & Full-Scale Range.  Consider reading these and other values regarding the gyroscope.

> ...according to code, it receives data in the form of 2^14(14bit) but
> sometimes it sends value way over the limit.

The code retrieves a high 8 bit and low 8 bit value for each axis of the accelerometer and the gyroscope.  This makes a 16 bit value.  Not a 14 bit value.

> How can I translate raw data to rather regular unit like degree and
> rad?

 1. To obtain an angle in degrees only the accelerometer is required.
 2. Consider calibrating the accelerator for offset and magnitude errors before using the raw values.
 3. Consider constraining the problem such that the accelerometer is only rotated around the Z-axis.
 4. The angle can be found by taking the inverse tangent of the ratio of the calibrated X acceleration and calibrated Y acceleration.

Other considerations:

 - If angles are desired in 3 dimensional space consider using commonly referred to values such as pitch, roll & yaw.  In which case many situate the accelerometer such to use these equations:

[![enter image description here][4]][4]

The above equations, a discussion and some example code can be found [here][5].

 - So far, all the equations discussed use trigonometry and can go to infinity (unusable results) given certain inputs.  The mathematical equivalent of [gimbal lock][6] if you will.  To avoid this consider using [quaternions][7].  This mathematical method of representing rotation in 3 dimensional space does not suffer the above problem, is easier for computers to calculate and is used extensively in computer graphics.

  [1]: https://en.wikipedia.org/wiki/Equations_of_motion#Constant_translational_acceleration_in_a_straight_line
  [2]: https://invensense.tdk.com/wp-content/uploads/2015/02/MPU-6000-Datasheet1.pdf
  [3]: https://en.wikipedia.org/wiki/Coriolis_force
  [4]: https://i.stack.imgur.com/7j1zY.png
  [5]: https://wiki.dfrobot.com/How_to_Use_a_Three-Axis_Accelerometer_for_Tilt_Sensing
  [6]: https://en.wikipedia.org/wiki/Gimbal_lock
  [7]: https://en.wikipedia.org/wiki/Quaternion


body:
I want to read the analog values of my ardunio uno into a separate c++ program. On the Arduino I have a serial port initialized for 9600 baud:

    int sensorPin = A0;    // select the input pin for the potentiometer

    int sensorValue = 0;  // variable to store the value coming from the sensor

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

    void loop() {
      // read the value from the sensor:
      sensorValue = analogRead(sensorPin);
      Serial.println(sensorValue);
    }

The output value should be right around 390, given the current settings. My serial port reading code seems to read the port fine, but only displays some of the characters sometimes.... some of the time, it reads the value fine. other times I get one or 2 of the characters, such as 3, or 39.

    #include <stdio.h>      // standard input / output functions
    #include <stdlib.h>
    #include <string.h>     // string function definitions
    #include <unistd.h>     // UNIX standard function definitions
    #include <fcntl.h>      // File control definitions
    #include <errno.h>      // Error number definitions
    #include <termios.h>    // POSIX terminal control definitions
    #include <iostream>
    using namespace std;

    int main(){
     const char* device ="/dev/ttyACM0";
    /* Open File Descriptor */
    //int USB = open( device, O_RDWR| O_NONBLOCK | O_NDELAY );
    int USB = open( device, O_RDWR| O_NOCTTY );

    /* Error Handling */
    if ( USB < 0 ){
    cout << "Error " << errno << " opening " << device << ": " << strerror (errno) << endl;
    }

    /* *** Configure Port *** */
    struct termios tty;
    struct termios tty_old;
    memset (&tty, 0, sizeof tty);

    /* Error Handling */
    if ( tcgetattr ( USB, &tty ) != 0 ) {
       cout << "Error " << errno << " from tcgetattr: " << strerror(errno) << endl;
    }

    /* Save old tty parameters */
    tty_old = tty;

    /* Set Baud Rate */
    cfsetospeed (&tty, (speed_t)B9600);
    cfsetispeed (&tty, (speed_t)B9600);

    /* Setting other Port Stuff */
    tty.c_cflag     &=  ~PARENB;            // Make 8n1
    tty.c_cflag     &=  ~CSTOPB;
    tty.c_cflag     &=  ~CSIZE;
    tty.c_cflag     |=  CS8;

    tty.c_cflag     &=  ~CRTSCTS;           // no flow control
    tty.c_cc[VMIN]   =  1;                  // read doesn't block
    tty.c_cc[VTIME]  =  5;                  // 0.5 seconds read timeout
    tty.c_cflag     |=  CREAD | CLOCAL;     // turn on READ & ignore ctrl lines

    /* Make raw */
    cfmakeraw(&tty);

    /* Flush Port, then applies attributes */
    tcflush( USB, TCIFLUSH );
    if ( tcsetattr ( USB, TCSANOW, &tty ) != 0) {
       cout << "Error " << errno << " from tcsetattr" << endl;
    }

    if ( tcsetattr ( USB, TCSANOW, &tty ) != 0){
    cout << "Error " << errno << " from tcsetattr" << endl;
    }

    /* Allocate memory for read buffer */
    char buf [1024];
    memset (&buf, '\0', sizeof buf);

    /* *** READ *** */
    int n = read( USB, &buf , sizeof buf );
    cout << "buffer: " << &buf << endl;
    /* Error Handling */
    if (n < 0)
    {
         cout << "Error reading: " << strerror(errno) << endl;
    }

    /* Print what I read... */
    cout << "Read: " << buf << endl;

    close(USB);
     return 0;
    }

How can I read the correct value being sent every time?

title: how can I accurately recieve potentiometer values over the USB port?

Answers: 2

body:
A [USB connection][1] is actually very complex.  And [serial communications (or the CDC class of USB)][2] is only 1 of over a dozen protocols used over USB.  Most cheap embedded processors save money by leaving out this feature.  Most Arduino's use cheap embedded processors.  For instance, the classic [Arduino Uno][3] needs a [second chip (search for New USB in this link)][4] to even talk Serial over the USB port.  Fortunately this is what [Serial.print()][5] does.  It takes care of setting up the Serial protocol over the USB port for you.  And will send your data over that connection.

How you pick up that data at the other end of the USB connection is usually beyond the discussion range of this stack exchange site.  But if you are on a windows machine it will probably be one of the COM ports.  And on Linux it will probably be something like /dev/ttyUSB0 or 1.

  [1]: https://en.wikipedia.org/wiki/USB
  [2]: https://en.wikipedia.org/wiki/USB_communications_device_class
  [3]: https://store.arduino.cc/usa/arduino-uno-rev3
  [4]: https://learn.adafruit.com/arduino-tips-tricks-and-techniques
  [5]: https://www.arduino.cc/reference/en/language/functions/communication/serial/print/

body:
There are a few issues at play here. One is that the Arduino
resets every time you open the serial connection on the PC side. You can
prevent this by putting a 1 µF (or more) capacitor between 5V and
RESET. A second issue is that the tty driver may be keeping old data in
its buffer, and you get this data when you open the connection. The
third issue is that `read()` returns as soon as it is able to read
_some_ data: it doesn't wait until it has got `sizeof buf` bytes.

To fix those issues, I suggest:

1. Have some form of handshake, where the PC sends a request to the
   Arduino, and then the Arduino acknowledges and starts to send the
   data. The PC program would then discard everything preceding the
   acknowledgement.
2. On the PC, repeatedly `read()` until you have a full line (which ends
   with CRLF). You may want to use a line-oriented stream if you want
   the libc to handle this for you: see fdopen(3) setlinebuf(3).

**Edit**: A very simple example of handshake: the PC sends `S` (for
“start”), then the Arduino sends `OK`, then it starts sending the data.
On the Arduino side:

```c++
void setup() {
    Serial.begin(9600);

    // Wait for the 'S' (start) command from the computer.
    while (Serial.read() != 'S')
        /* wait */ ;

    // Send acknowledgement.
    Serial.println("OK");
}
```

A longer “start” command would be more robust, but a bit more complex to
handle on the Arduino. The PC should wait a bit before sending the
command (in case the Arduino is restarting), or maybe send it multiple
times until it gets an answer.


body:
```
int pin1 = 8, pin2 = 9, pin3 = 10, pin4 = 11;
volatile byte  num = 0;
int coinPin = 2;

void setup() {
  Serial.begin(9600);
  attachInterrupt(digitalPinToInterrupt(coinPin), inc_counter, RISING );
  pinMode(pin1, OUTPUT);
  pinMode(pin2, OUTPUT);
  pinMode(pin3, OUTPUT);
  pinMode(pin4, OUTPUT);
}

void display(int num) {
  digitalWrite(pin1, bitRead(num, 1));
  digitalWrite(pin2, bitRead(num, 2));
  digitalWrite(pin3, bitRead(num, 3));
  digitalWrite(pin4, bitRead(num, 4));
}

void loop() {
  Serial.print(num);
  Serial.print("credit(s) towards balance");
  display(num);
  delay(500);
}

void inc_counter() {
  num++;
}
```

title: I am building a coin operated machine and am using arduino uno its working but i have to press the switch twice for credit to show on seven segment

Answers: 1

body:
Based on the code supplied, you are only updating the display every half second because of the `delay(500)`. You could press the button a number of times in 500mills.

I feel it may be better to update a flag and check that in your loop to increment your value and trigger the display update.

Based on the info provided, this may help in your endeavours.

```c++
int pin1 = 8, pin2 = 9, pin3 = 10, pin4 = 11;
int coinPin = 2;
int num = 0;
volatile bool coinFlag = false; // When true there is a coin.

void coin_present()
{
    coinFlag = true;
}

void setup()
{
    Serial.begin(9600);
    attachInterrupt(digitalPinToInterrupt(coinPin), coin_present, RISING);
    pinMode(pin1, OUTPUT);
    pinMode(pin2, OUTPUT);
    pinMode(pin3, OUTPUT);
    pinMode(pin4, OUTPUT);
}

void display(int num)
{
    digitalWrite(pin1, bitRead(num, 1));
    digitalWrite(pin2, bitRead(num, 2));
    digitalWrite(pin3, bitRead(num, 3));
    digitalWrite(pin4, bitRead(num, 4));
}

void loop()
{
    // If the flag is set increment num and then display value.
    if (coinFlag)
    {
        //We have a coin, reset the flag first.
        coinFlag = false;

        num++;        // Increment value
        display(num); //
        Serial.print(num);
        Serial.println("credit(s) towards balance");
    }

    // No need for a delay as only `coinFlag` being `true` will update the display.
}
```

Hope this helps in someway.


body:
I am try to build this AC-DC meter, the code original used default A3 as input, how can change the input on A0?
the link:
https://simple-circuit.com/arduino-autoranging-ac-dc-voltmeter-with-trms/

Thanks for help
Adam

 ```cpp

/**************************************************************************
 *
 * Arduino autoranging AC/DC voltmeter.
 * Voltage and frequency are printed on 1602 LCD screen.
 * This is a free software with NO WARRANTY - Use it at your own risk!
 * https://simple-circuit.com/
 *
 *************************************************************************/

#include <LiquidCrystal.h>   // include Arduino LCD library
// LCD module connections (RS, E, D4, D5, D6, D7)
LiquidCrystal lcd(8, 9, 10, 11, 12, 13);

// define autoranging channel pins
#define CH0  2
#define CH1  3
#define CH2  4
#define CH3  5

const uint16_t Time_Out = 50000,  // time out in microseconds
               Periods  = 10;     // number of periods of measurement (for AC voltage only)

// variables
byte ch_number;
const uint16_t res_table[4] = {2444, 244, 94, 47},  // voltage divider resistances in tenths kOhms
               total_res = 22444;                   // total resistance in tenths kOhms
uint16_t current_res;
volatile byte per;

void setup(void)
{
  pinMode(CH0, OUTPUT);
  pinMode(CH1, OUTPUT);
  pinMode(CH2, OUTPUT);
  pinMode(CH3, OUTPUT);

  lcd.begin(16, 2);     // set up the LCD's number of columns and rows
  lcd.setCursor(1, 0);
  lcd.print("Voltage:");

  ch_number = 0;
  ch_select(ch_number);

  // ADC and analog comparator configuration
  ADMUX  = 0x03;
  ADCSRA = 0x87;
  ADCSRB = (0 << ACME);  // select AIN1 as comparator negative input
  ACSR   = 0x13;         // turn on analog comparator

}

// analog comparator ISR
ISR (ANALOG_COMP_vect)
{
  byte count = 0;
  for(byte i = 0; i < 50; i++) {
    if ( ACSR & 0x20 )
      count++;
  }

  if(count > 48)
    per++;
}

// main loop
void loop()
{
  bool dc_flag = 0; // DC voltage flag bit
  int32_t sum = 0;  // sum of all readings
  uint16_t n = 0;   // number of readings (samples)

  ACSR = (1 << ACI);   // clear analog comparator interrupt flag
  ACSR = (1 << ACIE);  // enable analog comparator interrupt

  uint32_t current_m = micros();  // save current millis
  byte current_per = per;         // save current period number
  while ( (current_per == per) && (micros() - current_m < Time_Out) ) ;

  if( micros() - current_m >= Time_Out ) {  // if there's time out event ==> voltage signal is DC
    dc_flag = 1;
    for (byte i = 0; i < 200; i++) {
      ADCSRA |= 1 << ADSC;   // start conversion
      while(ADCSRA & 0x40);  // wait for conversion complete
      int16_t an = (int16_t)(ADCL | (uint16_t)ADCH << 8) - 511;
      sum += an;
      n++;         // increment number of readings
      delay(1);
    }
  }

  else {   // here, voltage signal is AC
    current_m = micros();  // save current millis()
    per = 0;
    while ( (per < Periods) && (micros() - current_m < (uint32_t)Time_Out * Periods) ) {
      ADCSRA |= 1 << ADSC;   // start conversion
      while(ADCSRA & 0x40);  // wait for conversion complete
      int32_t an = (int16_t)(ADCL | (uint16_t)ADCH << 8) - 511;
      sum += sq(an);  // sq: square
      n++;            // increment number of readings
    }
  }

  ACSR = (0 << ACIE);  // disable analog comparator interrupt
  uint32_t total_time = micros() - current_m;  // used to claculate frequency

  // voltage calculation
  float v;
  if(dc_flag)   // if voltage signal is DC
    v = (4 * sum)/n;   // calculate Arduino analog channel DC voltage in milli-Volts

  else  // here voltage signal is AC
    v = 4 * sqrt(sum/n);   // calculate Arduino analog channel RMS voltage in milli-Volts

  // claculate actual (input) voltage in milli-Volts (apply voltage divider equation)
  v = v * (float)total_res/current_res;
  v /= 1000;  // get voltage in Volts

  uint16_t v_abs = abs(int16_t(v));
  if( (v_abs >= 10 && ch_number == 0) || (v_abs >= 100 && ch_number == 1) || (v_abs >= 250 && ch_number == 2) ) {
    ch_number++;
    ch_select(ch_number);
    delay(10);
    return;
  }

  if( (v_abs < 220 && ch_number == 3) || (v_abs < 80 && ch_number == 2) || (v_abs < 8 && ch_number == 1) ) {
    ch_number--;
    ch_select(ch_number);
    delay(10);
    return;
  }

  char _buffer[8];
  lcd.setCursor(0, 1);
  if( v < 0)
    lcd.print('-');
  else
    lcd.print(' ');
  if(v_abs < 10)
    sprintf( _buffer, "u.u", v_abs, abs((int16_t)(v * 100)) % 100 );
  else if( v_abs < 100)
    sprintf( _buffer, "u.u", v_abs, abs((int16_t)(v * 10)) % 10 );
  else
    sprintf( _buffer, "u ", v_abs );

  lcd.print(_buffer);
  if(dc_flag)
    lcd.print("VDC        ");
  else {
    lcd.print("VAC ");
    // calculate signal frequency in Hz
    uint32_t period_time = total_time/Periods;
    float freq = 1000000.0/period_time;
    sprintf( _buffer, "u.uHz", (uint16_t)freq % 100, (uint16_t)(freq * 100) % 100 );
    lcd.print(_buffer);
  }

  delay(500);    // wait half a second

}

void ch_select(byte n) {
  switch(n) {
    case 0:
      digitalWrite(CH0, HIGH);
      digitalWrite(CH1, LOW);
      digitalWrite(CH2, LOW);
      digitalWrite(CH3, LOW);
      break;
    case 1:
      digitalWrite(CH0, LOW);
      digitalWrite(CH1, HIGH);
      digitalWrite(CH2, LOW);
      digitalWrite(CH3, LOW);
      break;
    case 2:
      digitalWrite(CH0, LOW);
      digitalWrite(CH1, LOW);
      digitalWrite(CH2, HIGH);
      digitalWrite(CH3, LOW);
      break;
    case 3:
      digitalWrite(CH0, LOW);
      digitalWrite(CH1, LOW);
      digitalWrite(CH2, LOW);
      digitalWrite(CH3, HIGH);
  }
  current_res = res_table[n];
}

// end of code.

```

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

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

title: how to config the Arduino ADC'S input on A0 instead of use default?

Answers: 2

body:
Your code is to hard to read, it is just a blob of characters on my screen but you have a pretty picture of the arduino. Change your code to use A0 instead of A3. Change your physical connection from A3 to A0 and you are all set. I miss read the code you posted.

It is a tricky circuit and he did all of the the registers directly, making it extremely hard to follow. I do not know the register set well enough to speak knowledgeable about what he is doing. The Optocouplers short out parts of the input divider network which he selects in his code. This is how he does the ranging. The optocouplers are drawn in reverse with the output on the left and the input on the right. Try this link to Nick Gammon's site: https://www.gammon.com.au/adc Also try this one: https://www.arduino.cc/en/Reference/PortManipulation

body:
The input to the ADC is selected by the four least-significant bits of
the “ADC Multiplexer Selection Register”, aka `ADMUX`. It is set to
analog input 3 by this line of code:

```c++
ADMUX  = 0x03;
```

Change this line to `ADMUX = 0;` and the ADC will read pin A0.


body:
I've connected the arduino UNO to the sim900a. But after checking the serial communication between the two I keep getting these output.

[![][1]][1]

Here is the connections and code that I used

    #include <SoftwareSerial.h>
    SoftwareSerial SIM900A(2, 3);
    // Connect the SIM900A TX to Arduino pin 2 RX.
    // Connect the SIM900A RX to Arduino pin 3 TX.
    char c = ' ';
    void setup()
    {
     // start th serial communication with the host computer
     Serial.begin(9600);
     while (!Serial);
     Serial.println("Arduino with SIM900A is ready");
     // start communication with the SIM900A in 9600
     SIM900A.begin(9600);
     Serial.println("SIM900A started at 9600");
     delay(1000);
     Serial.println("Setup Complete! SIM900A is Ready!");
     }
     void loop()
     {
      // Keep reading from SIM900 and send to Arduino Serial Monitor
      if (SIM900A.available())
      { c = SIM900A.read();
        Serial.write(c);
       }
      // Keep reading from Arduino Serial Monitor and send to SIM900A
      if (Serial.available())
      { c = Serial.read();
       SIM900A.write(c);
      }
     }

[![enter image description here][2]][2]

How can I fix this?

  [1]: https://i.stack.imgur.com/Lqnqh.jpg
  [2]: https://i.stack.imgur.com/CrYn8.jpg

title: How to fix serial communication problem between Arduino UNO and sim900A

Answers: 1

body:
You are using the wrong pins on the SIM900A to communicate with your Arduino.

That specific module has a MAX232 interface on it to convert TTL UART to RS232. That is not compatible with the Arduino unless you add another MAX232 to undo the conversion that the one on the board does.

Instead you need to use the other 3-pin header at the other end of the board.  It should ([according to this site](https://microcontrollerslab.com/sim900a-gsm-module-pinout-examples-applications-datasheet/)) be wired like this:

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

Of course you can use other pins than 0/1 on your Arduino, as long as you connect them to the right place on the SIM900A module as shown in that diagram.

Also note what I take to be a pair of jumpers bridging pins on the header you're currently connecting to (ring around them in the diagram).

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


body:
I am trying to use [Topway display][1] for HMI lcd with Arduino. This display using RS232C protocol [at docs][2] it has a "Communication Packet Structure" like this.

[![enter image description here][3]][3]

**So my query should start with AA and end with CC 33 C3 3C**.  This sample reading code was taking [topway youtube channel][4].

    Serial.write(0xaa); // packet head
    Serial.write(0x3e); // VP_N16 read command
    Serial.write(0x00); // VP_N16 address
    Serial.write(0x08);
    Serial.write(0x00);
    Serial.write(0x00);
    Serial.write(0xcc); // packet tail
    Serial.write(0x33); // packet tail
    Serial.write(0xc3); // packet tail
    Serial.write(0x3c); // packet tail

3E is the command (for reading) code and this is the list of all commands. [docs over here][2]

[![enter image description here][5]][5]

The point is parsing of smart LCD's response at the original. They use [this code][4]: (at first comment)

         while (!Serial.available()) {}
         if (Serial.read()==0xaa) {                     // packet head
         packet_OK=1;
         while (!Serial.available()) {}
         if (Serial.read()==0x3e) {                   // packet command
          while (!Serial.available()) {}
          temp_h=Serial.read();                      // read back value high byte
          while (!Serial.available()) {}
          temp_l=Serial.read();                      // read back value low byte
          while (!Serial.available()) {}
          if (!(Serial.read()==0xcc)) {packet_OK=0;} // packet tail
          while (!Serial.available()) {}
          if (!(Serial.read()==0x33)) {packet_OK=0;} // packet tail
          while (!Serial.available()) {}
          if (!(Serial.read()==0xc3)) {packet_OK=0;} // packet tail
          while (!Serial.available()) {}
          if (!(Serial.read()==0x3c)) {packet_OK=0;} // packet tail
          }
          else
          {packet_OK=0;}
         }
         else
         {packet_OK=0;}

It looks nasty and cumbersome because I must write different method for each LCD display commands. **Is there any way to read all serial response them as a char array with starting marker "0xAA" and read until finishing marker "0xCC 0x33 0xC3 0x3C" and after that parse it?**

You can watch and check this code on [youtube][4]

  [1]: https://www.topwaydisplay.com/product/smart-lcd/smart-lcd-module-HMT070ATA-1C
  [2]: https://www.topwaydisplay.com/sites/default/files/2020-06/Topway-Smart-LCD-SGTools-Handbook.pdf
  [3]: https://i.stack.imgur.com/CF810.png
  [4]: https://www.youtube.com/watch?v=t7VGK24kyLE
  [5]: https://i.stack.imgur.com/y1WwH.png

title: Read serial with header and end marker

Answers: 1

body:
The short answer to your question is “yes, there is a way”. Multiple
ways actually. You could write a _blocking_ function, which follows more
or less the logic of the example you show, blocking while waiting for
each new byte. Or you could write a _non blocking_ function, which
always return _immediately_ and, either gives you the complete packet,
or tells you that no full packet has been received so far.

The non-blocking way may be a bit more complicated, but it is more
useful, because you program can do other stuff, and be responsive, while
waiting for a packet. Here is my take at it. It is based on a [finite
state machine][fsm]:

```c++
// Return whether the payload of this command is of string type.
bool command_payload_is_string(uint8_t command);

// Return the expected packet length for the provided command,
// excluding header and tail.
int packet_length(uint8_t command);

// Attempt to read a packet, but do not block.
// Return a pointer to a static buffer holding the packet,
// or nullptr if no complete packet was received this time.
uint8_t *read_packet() {
    const uint8_t expected_header = 0xaa;
    const uint8_t expected_tail[4] = {0xcc, 0x33, 0xc3, 0x3c};

    // Return immediately unless we have a byte to process.
    if (Serial.available() == 0) return nullptr;
    uint8_t data = Serial.read();

    static uint8_t buffer[BUFFER_SIZE];
    static int bytes_received, bytes_expected;
    static enum {
        EXPECTING_HEADER, EXPECTING_COMMAND,
        EXPECTING_STRING, EXPECTING_PAYLOAD, EXPECTING_TAIL
    } state = EXPECTING_HEADER;
    switch (state) {
        case EXPECTING_HEADER:
            if (data = expected_header)
                state = EXPECTING_COMMAND;
            break;
        case EXPECTING_COMMAND:
            buffer[0] = data;  // command byte
            bytes_received = 1;
            if (command_payload_is_string(data)) {
                state = EXPECTING_STRING;
                // bytes_expected is not relevant in this case.
            } else {
                state = EXPECTING_PAYLOAD;
                bytes_expected = packet_length(data);
            }
            break;
        case EXPECTING_STRING:
            if (data == '\0') {  // end of string
                buffer[bytes_received++] = '\0';
                state = EXPECTING_TAIL;
                bytes_expected = 4;
                bytes_received = 0;
            } else if (bytes_received < BUFFER_SIZE - 1) {
                buffer[bytes_received++] = data;
            } else {
                // Do nothing. As the string is too long
                // to fit in the buffer, this byte is discarded.
            }
            break;
        case EXPECTING_PAYLOAD:
            buffer[bytes_received++] = data;
            if (bytes_received >= bytes_expected) {
                state = EXPECTING_TAIL;
                bytes_expected = 4;
                bytes_received = 0;
            }
            break;
        case EXPECTING_TAIL:
            // If we don't get the expected tail,
            // give up and wait for a new header.
            if (data != expected_tail[bytes_received++]) {
                state = EXPECTING_HEADER;
                break;
            }
            // If the tail is all right, return the buffer
            // and get ready for the next packet.
            if (bytes_received >= bytes_expected) {
                state = EXPECTING_HEADER;
                return buffer;
            }
    }
    return nullptr;
}
```

It will be up to you to implement `packet_length()`. See jstola's
comment on why it is needed.

You would use `read_packet()` like this:

```c++
void loop() {
    uint8_t *packet = read_packet();
    if (packet)
        parse_and_handle(packet);

    // the rest of the program, never blocked by read_packet()...
}
```

**Edit**: According to your comment, some commands have a payload which
is a string of unknown length, but [seemingly NUL-terminated][nul]. I
edited the code, and added an extra `EXPECTING_STRING` state to handle
this special case. It is up to you to implement the boolean function
`command_payload_is_string()`.

[fsm]: https://majenko.co.uk/blog/finite-state-machine
[nul]: https://arduino.stackexchange.com/questions/85360/how-to-convert-a-string-to-hex-array


body:
I am trying to figure out how to capture the `OK` or the `ERROR` from a SIM800l.

I have tried
```
mySerial.println("AT");
while (mySerial.available() > 0 ) {
String str = mySerial.readString();
Serial.println(str);
     if (str.equals("OK")) {
        Serial.println("ok");
     } else {
        Serial.println("unknown");
     }
   }

```

But I always getting nothing back?

title: Find OK or ERROR in serial string

Answers: 1

body:
You can use `.indexOf` to find characters in a String. It returns a `-1` if a match is not found. See https://www.arduino.cc/reference/en/language/variables/data-types/string/functions/indexof/

```c++
mySerial.println("AT");
String str;

while (mySerial.available() > 0 )
{
    str = mySerial.readString();
    Serial.println(str);

    if (str.indexOf("OK") != -1)
    {
  Serial.println("ok");
    } else if (str.indexOf("ERROR") != -1)
    {
  Serial.println("error!");
    } else {
  Serial.println("unknown");
    }
}
```


body:
Dear Stack Exchanger's,

I want to reset my Arduino and system in every 24h for preventing frozen software and also other connectivity stuffs.

I wrote a program which connects a digital pin to reset pin of Arduino and I want to reset with that way.

For example my code :

```
unsigned long myTime; // Millis() function time value
int timeExpected = 5000; // I want to reset it in every 5 secs for testing.
const int RESET_PIN = 2; // Reset pin's connection

void setup() {
  Serial.begin(9600);
  pinMode(LED_BUILTIN,OUTPUT);
}
void loop() {
  digitalWrite(LED_BUILTIN,HIGH);
    myTime = millis();
    Serial.println(myTime); // prints time since program started
     delay(1000);

   if(myTime % timeExpected == 0) {
    digitalWrite(LED_BUILTIN, LOW);
    delay(1000);
     Serial.println("RESET");
    //digitalWrite(RESET_PIN, LOW);(I just test with LED_BUILTIN Low function)
    }

  }
```

I have tried the watchdog timer but I cannot do it for 24 hours.
If you have another solution for reset in 24h please tell me and send me the related article/book/link etc. I will check and implement into my code.

UPDATE:
I have done this but it does not reset at very 5s .
Code :
```
#include <avr/wdt.h>
unsigned long myTime;
int timeExpected = 5000;

void setup() {
  Serial.begin(9600);
Serial.println("Setup started :");
// make a delay before enable WDT
// this delay help to complete all initial tasks
delay(2000);
wdt_enable(WDTO_2S);
}

void loop() {
    myTime = millis();
    delay(1000);
    Serial.println(myTime); // prints time since program started
   if(myTime == timeExpected) {
     Serial.println("RESET");
    wdt_reset();
    }
```

title: Arduino Reset via Software (every day)

Answers: 2

body:
You can do an almost immediate full reset with watchdog by activating it 'on place'.
```
wdt_enable(WDTO_15MS); // resets the MCU after 15 milliseconds
while (true);
```

You can use millis() for timing the reset as any other timed function.

body:
You can use the watchdog timer, but you have to change the way you measure the elapsed time. Try this code:

    #include <avr/wdt.h>

    unsigned long myTime; // Millis() function time value
    unsigned long elapsedTime;
    unsigned long timeExpected = 5000; // I want to reset it in every 5 secs for testing.
    const int RESET_PIN = 2; // Reset pin's connection

    void setup() {
      Serial.begin(9600);
      pinMode(LED_BUILTIN, OUTPUT);
      myTime = millis();
      Serial.println("INIT");
      wdt_enable(WDTO_2S); //Enable wdt every two seconds

    }
    void loop() {

      //************RESET HANDLER********************//
      elapsedTime = millis() - myTime;
      if (elapsedTime > timeExpected) {
        Serial.print("RESET");
        while (1); //Intentionally halt the program, so the watchdog performs the reset
      }
      //**********************************************
      //****************REST OF THE PROGRAM***********
      wdt_reset(); //Ensure one call to this function at least one time in two seconds or less
      digitalWrite(LED_BUILTIN, HIGH);
      Serial.println(elapsedTime); // prints time since program started
      delay(1000);
    }

Please note that if you have multiple delays in your program, you have to ensure the call to wdt_reset() in order to prevent unwanted resets.
Personally I try not to use delays and would recommend avoid delays as much as possible. You may check out [this tutorial][1] if you want to see how to avoid delays. If you achieve avoiding delays you can call wdt_reset() just one time at the begining of the loop.

  [1]: https://youtu.be/xcvXUCih30Y


body:
I'm using FastLED library, Arduino Nano and 5 addressable LEDs (WS2812B).
I'd like to create the sequence in the image attached. (all in white color for example)

I know how to turn ON each LED every 0.2 sec and I know how to fade.
I don't know how to make sure each LED goes from 0% brightness to 100% in 0.4 sec + start fading in the next LED after 0.2 sec.

Here is a fading LED:

    void loop() {
   uint32_t cur_ms = millis();
  if (cur_ms - fade_ms > 200) {
   fade_ms = cur_ms;
   brightness += 5;
   leds[0] = CHSV(255, 0, brightness);
  }

 FastLED.show();
 // delay(10);
}

Can anyone help me figure it out?
[![enter image description here][1]][1]

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

title: How to fade LED in a defined time using FastLED

Answers: 1

body:
One of the SimpleTimer libraries such as [this one by Marcello Romani][1] (which I mention because I have used it; there are others). It creates a timers object that has 10 (in this case) software-based timers with a variety of operating modes (run once, run x times, run forever, e.g.).

The basic idea (for a 1-LED example) is that you write a function (known as a "callback" to step up the brightness of an LED by one step. Let's call it `stepUp()`.

You write another callback function to turn off the LED and start a timer that will call `stepUp()` at whatever interval you choose for as many times as it takes to reach 100%. Let's call this one `cycleLED()`.

In your `setup()`, you'll start another timer that will call `cycleLED()` as often as you want that process to run - every 1200 mSec in this case - and for as many times (or forever) as you choose.

In your loop() function, you'll need a call to your timer object's .run() function as often as possible - that is what makes the timers work, and it is the timers that will call your callback functions to make your LEDs behave as you want them to.

So far, we one fading-up LED, and I'd recommend you implement this much at first.

There are two ways to go from here. You can write the above pair of callbacks for each LED, but they will be nearly identical and why write maintain the same code, several times over? Or you can use another feature of the library - a pointer-to-void argument to the callback function - in which you can pass any value, such as an LED's number or address, so that one callback could operate on the specified LED.

If you go with first option, your `setup()` function will need to to start 5 timers, one for each `cycleLED()` function (which would need to have distinct names, of course), and those timers start-times will need to be staggered.

With the second option, you would write a third callback, `allCycles()` that sequences the starts of each `cycleLED()` in turn. In this case, your `setup()` function would only need to start a timer to repeatedly call `allCycles()`.

There's a lot there, if these are new concepts. If so, it will be a lot easier to experiment with the SimpleTimer library doing something trivial at first, like flashing (not fading) one LED, then several LEDs, until this way of coding timed events feels less foreign.

  [1]: https://github.com/marcelloromani/Arduino-SimpleTimer


body:
So I want to connect multiple LED Panels with dynamic addressing to a Master Controller.
Seems like SMBus should be able to do that, however I don't find any Library for the Arduino framework.
Does SMBus require Hardware implementation and if if works in Software is there a library for that and does it even work on the ATTiny?

title: SMBus on ATTiny204

Answers: 1

body:
The AVR chips lack hardware support for bus arbitration when operating as a slave device in I2C, which would be required for it to work as SMBus with ARP.

You would have to write your own bit-banged driver to act as a slave whilst monitoring the SDA pin whenever it transmits to look for bus collisions.

A better solution would be to allocate each device a unique address using an address space of your choosing (to give you enough addresses for uniqueness) at build / programming time. A bus of some design (maybe RS485 would be a good choice for this) can then be scanned looking for, and cataloguing, what addresses are in use.