body:
First, see the schematics (attached). [![schematics][1]][1]

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

The GPS is working properly when I write code only for reading data from it as below:

```
//Connect with pin 18 and 19
#include <TinyGPS.h>
//long   lat,lon; // create variable for latitude and longitude object
float lat,lon; //notice herewhy lon is not ina   get same same
TinyGPS gps; // create gps

void setup()
{
  Serial.begin(57600); // connect serial    for TFT
Serial.println("The GPS Received Signal:");
Serial1.begin(9600); // connect gps sensor    for GPS
  }

void loop(){

    while(Serial1.available()){ // check for gps data

      delay(1000);

        Serial.println( Serial1.read());

    if(gps.encode(Serial1.read()))// encode gps data
    {
    gps.f_get_position(&lat,&lon); // get latitude and longitude

    Serial.print("Position: ");

    //Latitude
    Serial.print("Latitude: ");
    Serial.print(lat,6);
    Serial.print(",");

    //Longitude
    Serial.print("Longitude: ");
    Serial.println(lon,6);

   }
  }
}
```

In the above code, when I print serial data coming from GPS, it is like 44,65,46,48,57,44,13,10,84.... and then gps.encode() function encodes it properly and returns true and ultimately I get correct values of longitude and latitude.

Now, the problem is when I use that same code along with my TFT code, it does not read serial data correctly and prints like 0,44,0,57,0,10,0,44,0,50,0,44... and the gps.encode() function always returns false. and I am unable to get any values of longitude and latitude.

Here is the complete code of TFT + GPS:

```
#include <stdlib.h>
#include <SPI.h>
#include <Wire.h>      // this is needed even tho we aren't using it
#include "Adafruit_GFX.h"
#include "Adafruit_ILI9341.h"
#include <Adafruit_STMPE610.h>
#include <SoftwareSerial.h>
#include <TinyGPS.h>

TinyGPS gps; // create gps

void Draw_Compass_Rose();
void display_item(int x, int y, String token, int txt_colour, int txt_size);
void arrow(int x2, int y2, int x1, int y1, int alength, int awidth, int colour);

// For the Adafruit TFT shield, these are the default.
#define TFT_DC 9
#define TFT_CS 10

// Use hardware SPI (on Uno, #13, #12, #11) and the above for CS/DC
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);

// The STMPE610 uses hardware SPI on the shield, and #8
#define STMPE_CS 8
Adafruit_STMPE610 ts = Adafruit_STMPE610(STMPE_CS);

// This is calibration data for the raw touch data to the screen coordinates
#define TS_MINX 150
#define TS_MINY 130
#define TS_MAXX 3800
#define TS_MAXY 4000

/*** UI details */
#define BUTTON_X 40
#define BUTTON_Y 140
#define BUTTON_W 60
#define BUTTON_H 30
#define BUTTON_SPACING_X 20
#define BUTTON_SPACING_Y 10
#define BUTTON_TEXTSIZE 2

/* Back Button details */
#define BACK_BUTTON_X 40
#define BACK_BUTTON_Y 40

#define BLACK   0x0000
#define BLUE    0x001F
#define RED     0xF800
#define GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF

// text box where numbers go,position the text box/rectangle
#define TEXT_X 10
#define TEXT_Y 10
#define TEXT_X1 10
#define TEXT_Y1 50
#define TEXT_X2 10
#define TEXT_Y2 90
#define TEXT_W 220
#define TEXT_H 30
#define TEXT_TSIZE 3
#define TEXT_TCOLOR ILI9341_MAGENTA
// the data (phone #) we store in the textfield
#define TEXT_LEN 12
char latitude[TEXT_LEN+1] = "";
char longitude[TEXT_LEN+1] = "";
uint8_t latitude_i=0;
uint8_t longitude_i=0;
char STATUS_X;
char STATUS_Y;
float lat = 0.0;
float lon = 0.0;
float AZMTH = 0.0;
float add;

const int centreX  = 160;
const int centreY  = 120;
const int diameter = 100;
int last_dx, last_dy, dx, dy;

// 0 -> Keypad    1 -> Compass
unsigned int page_state = 0;

// 0 -> latitude     1 -> longitude
unsigned int cursor_state = 0;

/* create 15 buttons, in classic candybar phone style */
char buttonlabels[15][5] = {"ENT", "CLR", "NEXT", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", ".", ">"};
uint16_t buttoncolors[15] = {ILI9341_DARKGREEN, ILI9341_DARKGREY, ILI9341_RED,
                             ILI9341_BLUE, ILI9341_BLUE, ILI9341_BLUE,
                             ILI9341_BLUE, ILI9341_BLUE, ILI9341_BLUE,
                             ILI9341_BLUE, ILI9341_BLUE, ILI9341_BLUE,
                             ILI9341_BLUE, ILI9341_BLUE, ILI9341_ORANGE};
Adafruit_GFX_Button buttons[15];

char backButtonLable[1][5] = {"Back"};
uint16_t backButtonColors[1] = {ILI9341_DARKGREEN};
Adafruit_GFX_Button backButton[1];

// Print something in the mini status bar with either flashstring
void status(const __FlashStringHelper *msg) {
  tft.fillRect(STATUS_X, STATUS_Y, 240, 8, ILI9341_BLACK);
  tft.setCursor(STATUS_X, STATUS_Y);
  tft.setTextColor(ILI9341_WHITE);
  tft.setTextSize(1);//font size on top of white box
  tft.print(msg);
}
// or charstring
void status(char *msg) {
  tft.fillRect(STATUS_X, STATUS_Y, 240, 8, ILI9341_BLACK);
  tft.setCursor(STATUS_X, STATUS_Y);
  tft.setTextColor(ILI9341_WHITE);
  tft.setTextSize(1);//font size on top of white box
  tft.print(msg);
}

void setup() {
Serial.begin(57600); // connect serial
Serial.println("The GPS Received Signal:");
Serial1.begin(9600); // connect gps sensor

  // clear the screen
  tft.begin();
  tft.fillScreen(ILI9341_BLACK);
  tft.setTextColor(ILI9341_MAGENTA);
  tft.print("      WELCOME TO AZIMUTH SYSTEM");
  // eep touchscreen not found?
  if (!ts.begin()) {
    Serial.println("Couldn't start touchscreen controller");
    while (1);
  }
  Serial.println("Touchscreen started");

  // create buttons
  for (uint8_t row=0; row<5; row++) {
    for (uint8_t col=0; col<3; col++) {
      buttons[col + row*3].initButton(&tft, BUTTON_X+col*(BUTTON_W+BUTTON_SPACING_X),
                 BUTTON_Y+row*(BUTTON_H+BUTTON_SPACING_Y),    // x, y, w, h, outline, fill, text
                  BUTTON_W, BUTTON_H, ILI9341_WHITE, buttoncolors[col+row*3], ILI9341_WHITE,
                  buttonlabels[col + row*3], BUTTON_TEXTSIZE);
      buttons[col + row*3].drawButton();
    }
  }

  // create 'text field'
  tft.drawRect(TEXT_X, TEXT_Y, TEXT_W, TEXT_H, ILI9341_WHITE);
  tft.drawRect(TEXT_X1, TEXT_Y1, TEXT_W, TEXT_H, ILI9341_WHITE);
  tft.drawRect(TEXT_X2, TEXT_Y2, TEXT_W, TEXT_H, ILI9341_WHITE);

  tft.setCursor(TEXT_X+2, TEXT_Y+10);
  tft.setTextColor(TEXT_TCOLOR, ILI9341_BLACK);
  tft.setTextSize(2);//font size inside white box
  tft.print(" LAT:");

  tft.setCursor(TEXT_X1 + 2, TEXT_Y1+10);
  tft.setTextColor(TEXT_TCOLOR, ILI9341_BLACK);
  tft.setTextSize(2);//font size inside white box
  tft.print(" LONG:");

  tft.setCursor(TEXT_X2 + 2, TEXT_Y2+10);
  tft.setTextColor(TEXT_TCOLOR, ILI9341_BLACK);
  tft.setTextSize(2);//font size inside white box
  tft.print(" AZMTH:");
}

void loop() {

  TS_Point p;

  /*
  while(Serial1.available()){ // check for gps data    //this has issue it is not written correctly
  if(gps.encode(Serial1.read()))// encode gps data
   Serial.print("Position: ");
  }
  */

  //lets try starts

  while(Serial1.available()){

    delay(1000);

      Serial.println( Serial1.read());

    bool res = gps.encode(Serial1.read());

    Serial.println(res);

    if(res)// encode gps data       //here is the problem lies    <<<<<<<<<===================================== it always return 0 thats why not working
    {
      gps.f_get_position(&lat,&lon); // get latitude and longitude

       Serial.print("Position: ");

    //Latitude
    Serial.print("Latitude: ");
    Serial.print(lat,6);
    Serial.print(",");

    //Longitude
    Serial.print("Longitude: ");
    Serial.println(lon,6);

      }

    }

  //lets try ends

  if (ts.bufferSize()) {
    p = ts.getPoint();
  } else {
    // this is our way of tracking touch 'release'!
    p.x = p.y = p.z = -1;
  }

  // Scale from ~0->4000 to tft.width using the calibration #'s
  if (p.z != -1) {
    p.x = map(p.x, TS_MINX, TS_MAXX, 0, tft.width());
    p.y = map(p.y, TS_MINY, TS_MAXY, 0, tft.height());
    Serial.print("("); Serial.print(p.x); Serial.print(", ");
    Serial.print(p.y); Serial.print(", ");
    Serial.print(p.z); Serial.println(") ");
  }

  switch(page_state){
    case 0: // Means Keypad
  // go thru all the buttons, checking if they were pressed
  for (uint8_t b=0; b<15; b++) {
    if (buttons[b].contains(p.x, p.y)) {
      //Serial.print("Pressing: "); Serial.println(b);
      buttons[b].press(true);  // tell the button it is pressed
    } else {
      buttons[b].press(false);  // tell the button it is NOT pressed
    }
  }

  // now we can ask the buttons if their state has changed
  for (uint8_t b=0; b<15; b++) {
    if (buttons[b].justReleased()) {
      // Serial.print("Released: "); Serial.println(b);
      buttons[b].drawButton();  // draw normal
    }

    if (buttons[b].justPressed()) {
        buttons[b].drawButton(true);  // draw invert!

        // ENT Button was clicked
        if (b == 0){
          lon = atof(longitude);
          lat = atof(latitude);
          status(F("  Searching and laser start rotating"));
          Serial.println("Searching ");
          Serial.print("Latitude : ");
          Serial.println(String(lat));
          Serial.print("longitude : ");
          Serial.println(String(lon));
          Serial.print("lat + lon = ");
          AZMTH=lat+lon;
          Serial.println(AZMTH);

            // just add this part in this location
          //----- AND REPLACE THE VALUE -----
          tft.setCursor(TEXT_X2 + 90, TEXT_Y2+10);
              tft.setTextColor(TEXT_TCOLOR, ILI9341_BLACK);
              tft.setTextSize(2);//font size inside white box
              tft.print(AZMTH);
              Serial.print(AZMTH);

        }

        // CLR Button was clicked
        else if (b == 1) {
          switch(cursor_state){
            case 0:
              if (latitude > 0) {
                latitude_i--;
                latitude[latitude_i] = ' ';
              }
              break;

            case 1:
              if (longitude > 0) {
                longitude_i--;
                longitude[longitude_i] = ' ';
              }
              break;
          }
        }

        // NEXT Button was clicked
        else if (b == 2){
          page_state = 1;
          tft.fillScreen(BLACK);
          latitude[0]=0x00;
          latitude_i=0;
          longitude[0]=0x00;
          longitude_i=0;
          cursor_state = 0;

          tft.setRotation(1);
          Draw_Compass_Rose();
            double angle= 270; //use heading from compass
            dx = (diameter * cos((angle-90)*3.14/180)) + centreX;    // calculate X position
            dy = (diameter * sin((angle-90)*3.14/180)) + centreY;    // calculate Y position
            arrow(last_dx,last_dy, centreX, centreY, 20, 20,BLACK);  // Erase last arrow
            arrow(dx,dy, centreX, centreY, 20, 20,CYAN);             // Draw arrow in new position
            last_dx = dx;
            last_dy = dy;
          delay(25);
          tft.setRotation(0);

          }

        // '>' Button was clicked
        else if (b == 14){
          /* Toggle between latitude and longitude */
          if (cursor_state == 0){
            cursor_state = 1;
          } else if (cursor_state == 1){
            cursor_state = 0;
          }
        }

        // if a numberpad button, append the relevant # to the textfield
        else if (b >= 3) {
          switch(cursor_state){
            case 0:
              if (latitude_i < TEXT_LEN) {
                latitude[latitude_i] = buttonlabels[b][0];
                latitude_i++;
                latitude[latitude_i] = 0; // zero terminate
                //fona.playDTMF(buttonlabels[b][0]);
              }
              break;
            case 1:
              if (longitude_i < TEXT_LEN) {
                longitude[longitude_i] = buttonlabels[b][0];
                longitude_i++;
                longitude[longitude_i] = 0; // zero terminate
                //fona.playDTMF(buttonlabels[b][0]);
              }
              break;
          }

        }

       Serial.println("Value of cursor_state: ");    //where is written touch screen started? you there????
       Serial.print(cursor_state);

      switch(cursor_state){   //This condition is always false

            Serial.print("If successfully comes here then this line should print");  //This means

            case 0:
              // update the current latitude
              tft.setCursor(TEXT_X + 90, TEXT_Y+10);//set position of text when user key in the lat angle
              tft.setTextColor(TEXT_TCOLOR, ILI9341_BLACK);
              tft.setTextSize(2);//font size inside white box
              Serial.print(latitude);
             // if (gps.f_get_position(&lat,&lon))    //<- this condition is wrong
              {
             // tft.print(String(gps.f_get_position(&lat));
              gps.f_get_position(&lat,&lon);
              Serial.println("Latitude on Serial: ");

              Serial.print(lat, 6);
              }
              break;

              // update the current longitude
            case 1:
              tft.setCursor(TEXT_X1 + 90, TEXT_Y1+10);//set position of text when user key in the long angle
              tft.setTextColor(TEXT_TCOLOR, ILI9341_BLACK);
              tft.setTextSize(2);//font size inside white box
              Serial.print(longitude);
             // if (gps.f_get_position(&lat,&lon))
              {
             // tft.print(String(gps.f_get_position(&lon));
              gps.f_get_position(&lat,&lon);
              Serial.println("Longitude on Serial: ");
              Serial.print(lon, 6);
              }
              break;
          }

    }
//
      delay(50); // UI debouncing

     }
   }
}

void display_item(int x, int y, String token, int txt_colour, int txt_size) {
    tft.setCursor(x, y);
    tft.setTextColor(txt_colour);
    tft.setTextSize(txt_size);
    tft.print(token);
    tft.setTextSize(2); // Back to default text size
}

void arrow(int x2, int y2, int x1, int y1, int alength, int awidth, int colour) {
  float distance;
  int dx, dy, x2o,y2o,x3,y3,x4,y4,k;
    distance = sqrt(pow((x1 - x2),2) + pow((y1 - y2), 2));
    dx = x2 + (x1 - x2) * alength / distance;
    dy = y2 + (y1 - y2) * alength / distance;
    k = awidth / alength;
    x2o = x2 - dx;
    y2o = dy - y2;
    x3 = y2o * k + dx;
    y3 = x2o * k + dy;
    x4 = dx - y2o * k;
    y4 = dy - x2o * k;
    tft.drawLine(x1, y1, x2, y2, colour);
    tft.drawLine(x1, y1, dx, dy, colour);
    tft.drawLine(x3, y3, x4, y4, colour);
    tft.drawLine(x3, y3, x2, y2, colour);
    tft.drawLine(x2, y2, x4, y4, colour);
}
void Draw_Compass_Rose(){
  int dxo, dyo, dxi, dyi;
    tft.drawCircle(centreX,centreY,diameter,YELLOW);  // Draw compass circle
  for (float i = 0; i <360; i = i + 22.5) {
    dxo = diameter * cos((i-90)*3.14/180);
    dyo = diameter * sin((i-90)*3.14/180);
    dxi = dxo * 0.9;
    dyi = dyo * 0.9;
    tft.drawLine(dxi+centreX,dyi+centreY,dxo+centreX,dyo+centreY,YELLOW);
  }
    display_item((centreX-5),(centreY-85),"N",RED,2);
    display_item((centreX-5),(centreY+70),"S",RED,2);
    display_item((centreX+80),(centreY-5),"E",RED,2);
    display_item((centreX-85),(centreY-5),"W",RED,2);
}

```
Please help me. I shall be very thankful to the person who helps me.

title: Problem with gps.encode() using TinyGPS library

Answers: 0


body:
I designed a custom **ATMega32U4** based *Arduino Leonardo* board. I'm using `MHeironimus/ArduinoJoystickLibrary` to implement an HID joystick. I need to create also a virtual serial port to send NON joystick data to the USB host (Android device).
If I try to set use the usb serial the joystick device is not recognized.
If I stop the serial the joystick works fine.
This's the code:

    #include <Arduino.h>
    #include <Joystick.h>

    #define JOYSTICK_PERIOD 20

    const int BUTTON1_PIN = 4;
    const int BUTTON2_PIN = 5;

    int x = 0, y = 0, rx = 0, ry = 0, din = 0;
    long time1, time2;

    Joystick_ Joystick(
      JOYSTICK_DEFAULT_REPORT_ID,
      JOYSTICK_TYPE_GAMEPAD,
      2, 0,
      true, true, false,
      true, true, false,
      false, false,
      false, false, false
    );

    void setup()
    {
      pinMode(4, INPUT_PULLUP);
      pinMode(5, INPUT_PULLUP);

      pinMode(A0, INPUT);
      pinMode(A1, INPUT);
      pinMode(A2, INPUT);
      pinMode(A3, INPUT);

      Joystick.begin();
      Joystick.setXAxisRange(0, 1000);
      Joystick.setYAxisRange(0, 1000);
      Joystick.setRxAxisRange(0, 1000);
      Joystick.setRyAxisRange(0, 1000);

      time1 = millis();

      Serial1.begin(9600);
      Serial.begin(9600);
    }

    void SerialEvent()
    {
      int _count = Serial.available();

      for(int _i=0;_i<_count;_i++)
        Serial1.write(Serial.read());
    }

    void Serial1Event()
    {
      int _count = Serial1.available();

      for(int _i=0;_i<_count;_i++)
        Serial.write(Serial1.read());
    }

    void loop()
    {
      time2 = millis();

      long _period = time2 - time1;

      time2 = time1;

      if(_period >= JOYSTICK_PERIOD)
      {
        din = (digitalRead(BUTTON1_PIN) << 1) | digitalRead(BUTTON2_PIN);

        x = analogRead(A0);
        y = analogRead(A1);
        rx = analogRead(A2);
        ry = analogRead(A3);

        Joystick.setButton(0, din);

        Joystick.setXAxis(x);
        Joystick.setYAxis(y);
        Joystick.setRxAxis(rx);
        Joystick.setRyAxis(ry);
      }
    }

Anyone has hints?

title: Multiplexing HID and serial on ATMega32U4

Answers: 0


body:
These pins are on the module:

 - 3.3V
 - GND
 - VSYNC
 - SCL
 - SDA
 - HREF
 - D0-D7
 - DCLK
 - PWDN
I have tried many codes and connections of the OV7670 Monocular cameras, none seem to work([Instructables][1] ,  [Circuit Digest ][2], [Youtube][3]).
The binocular cameras seem to be just daisy-chained using the I2C SCCB interface. I cant get any image reading on any of their codes provided. Some other guides mention programming the XCLK on board using SCCB PLL, but I'm not sure how to do it as I don't have much background in this domain.

Edit:-

 1.[Another resource][4]

 2.[Wiki with datasheet and schematic][5] (the module is a copy of this camera)

[![Image of module][6]][6]

  [1]: https://www.instructables.com/id/OV7670-Without-FIFO-Very-Simple-Framecapture-With-/
  [2]: https://circuitdigest.com/microcontroller-projects/how-to-use-ov7670-camera-module-with-arduino
  [3]: https://www.youtube.com/watch?v=6bfY9JXOppI
  [4]: http://embeddedprogrammer.blogspot.com/2012/07/hacking-ov7670-camera-module-sccb-cheat.html
  [5]: https://www.waveshare.com/wiki/Maix_Binocular_Camera
  [6]: https://i.stack.imgur.com/IDW7E.jpg

title: Connecting OV2640 with 17 Pins Binocular Camera module, to any microcontroller (System clock on module pin 18 -NC)

Answers: 0


body:
I'm using an ATmega328P based Arduino to prototype reading a TMP36 temperature sensor. I will eventually move this to an ATtiny85 based board with a battery supply. Both the TMP36 and ATtiny85 have a Vcc range from 2.7V to 5.5V so a battery that starts at say 4.5V and slowly drops to 2.7V should not be out of range.

I am expecting to read temperatures in the range -5°C to +30°C which should correspond to a TMP36 output between 0.5 to 0.9V. I am getting 0.74V at around 23°C so this sort of range seems plausible.

The TMP36 outputs 10 mV/°C regardless of Vcc (within 2.7-5.5v). But I suspect the AnalogRead() value will be scaled by the supply voltage and so will slowly change as the battery drains. Is this correct?

Do I need to include an external voltage-regulator / voltage-reference device to supply some fixed voltage (e.g. 2.5V) to AREF?

----

Solution

Following [Edgar Bonet's Answer](https://arduino.stackexchange.com/a/76443/316) I successfully enabled the internal voltage reference for the ADC.

Initially I added a 100nF bypass capacitor to AREF and tried

    #define REFS1 7
    #define REFS0 6
    #define REFS2 4

...

    //ADMUX = (_BV(REFS1) | _BV(REFS2)); // 2.56V ATtiny85   datasheet §17.3 pp134
    ADMUX = (_BV(REFS1) | _BV(REFS0)); // 1.1V  ATmega328P datasheet §23.9 pp217

but didn't get it to work, my code had no effect on values from `analogRead()`. So after a bit of [further reading](https://www.arduino.cc/reference/en/language/functions/analog-io/analogreference/) I instead used

    analogReference(INTERNAL);

Which worked.

title: How does supply voltage affect `analogRead()` on AVR-based microcontrollers?

Answers: 1

body:
The ADC measures a _voltage ratio_. The conversion result is the rounded
value of 1024×V/Vref, where V is the voltage at the input and
Vref is the voltage reference.

In the default Arduino configuration, the reference is connected to Vcc.
This will not fit your use case, as the voltage you want to read does
not vary proportionately to Vcc. You could use an external reference.
However, the ATtiny85 has two internal voltage references at 1.1 and
2.56 V. Either of these may be well suited for you application,
which should save you having to add an extra part.

See the [chapter on the ADC in the datasheet][datasheet] for details on
how to select the voltage reference.

[datasheet]: http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-2586-AVR-8-bit-Microcontroller-ATtiny25-ATtiny45-ATtiny85_Datasheet.pdf#G1.1202338


body:
I have a counter attached to ISR:

    void ISR_impulse() {
      CNT++;
    }

and I want to calculate rolling count per minute with arbitrary update rate.

However I can only get it to update every minute:

    void loop() {
      if (t - t0 > 60000) {
        CPM = CNT - CNT0;
        t0 = t;
        CNT0 = CNT;
      }

      t = millis();
      delay(100);
    }

Requirement:

- Rolling count with a window of 1 minute, and arbitrary update rate like 1 second ?
- CPU has other tasks to do, which might take a significant amount of time.
- SAMD21 has pulse period measurement in TC, but I have no idea how to set it up.

Partial solution one by [edgar bonet][1]:
```
  static uint8_t buf[60];
  static uint8_t idx;
  static uint32_t t0;
  static uint16_t CNT0;
  static uint8_t cpm;

  if (millis() - t0 >= 1000) {
    t0 = millis();
    uint16_t cps = CNT - CNT0;
    CNT0 = CNT;
    cpm += cps - buf[idx];
    buf[idx] = cps;
    if (++idx >= 60) idx = 0;
  }
```
How ever this only works if the loop code finishes in less than 1ms.

  [1]: https://arduino.stackexchange.com/users/7508/edgar-bonet

title: How to produce rolling count per minute?

Answers: 2

body:
If you want to update every second a one minute running average, you
have no choice but store in memory the counts you got the previous
60 seconds. You store them in a ring buffer, so that every new
reading replaces the oldest one. Then, every second:

* you add to the CPM count the number of counts you got this second
* you subtract the number of counts you got on the second that just got
  out of the sliding window.

I would implement that logic this way:

```
const uint32_t ONE_SECOND = 1000;

uint16_t counts_per_minute;
uint16_t previous_counts[60];
size_t counts_pos;

void loop() {
    static uint32_t previous_second;
    if (millis() - previous_second >= ONE_SECOND) {
        previous_second += ONE_SECOND;
        noInterrupts();
        uint16_t CNT_copy = CNT;
        interrupts();
        static uint16_t CNT_previous;
        uint16_t second_count = CNT_copy - CNT_previous;
        CNT_previous = CNT_copy;
        counts_per_minute += second_count - previous_counts[counts_pos];
        previous_counts[counts_pos] = second_count;
        if (++counts_pos >= 60) counts_pos = 0;
    }
}
```

Note that:

* The timing variable is updated with `previous_second += ONE_SECOND`
  rather than `previous_second = now` in order to avoid the accumulation
  of small timing errors.
* The counter that is updated in the ISR has to be read only once,
  with interrupts disabled. Otherwise the interrupt may change it while
  you are in the middle of reading it.

body:
You need a First-In, First-Out buffer (FIFO) so that the oldest data drops off to make room for the newest. This is usually done with a circular buffer - an array whose beginning / end point change as data is added. (For comparison, the simplistic way is an array whose contents gets moved down (toward i = 0) each time you need to add a datum. But moving data is slow, so remembering where the oldest entry is, replacing it with the newest one, and updating the remembered oldest-data location gives a huge permormance improvement.

Secondly, you need to define how responsive your counter needs to be - how many updates per minute you'll need. That's the number of elements you need in the array.

Evaluating the immediately-passed minute's count is as simple as summing the array, which can be done without caring where the begin/end point is. Sum from 0 to N-1; the result will be the same.


body: I recently built a circuit with an atmega328p (which I have never used before standalone) and attached all the neccessary components (crystal, capacitors etc). However, when I powered it up with a regulated 5v input, I noticed the chip getting a little bit warm. Not hot, the temperature seems quite constant, and everything still works just fine. Another strange thing though, is when I connect the VCC to AVCC together as specified in the datasheet, the circuit doesn't work at all: The LCD screen just shows solid blocks at the top. When I disconnect the wire again, everything is back to normal. What went wrong? It is perfectly possible that there is a small solder bridge on my perfboard.

title: Warm Atmega328p and weird power behaviour

Answers: 0


body:
I know there are fans out there that have a dedicated PWM input, but I like to know if I can PWM control a fan that does not have such a dedicated PWM input. So...

If I have a 3 pin 12v fan like the [Noctua NF-A20][1] with connections:

- GND
- 12 V
- tach out (RPM measurement)

Can I control its speed by PWM on the 12V supply voltage (using a MOSFET most probably)?
Would the tach out still work?

  [1]: https://noctua.at/en/products/fan/nf-a20-flx

title: 3pin (GND, 12V, tach) 12v FAN control using PWM

Answers: 1

body:
Yes, and yes.

You have to modulate the +12V rather than GND because the output is referenced to ground. That means you need to use the classic N+P channel FET arrangement:

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

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

<!-- End schematic -->


body:
I was doing some **Ohm's Law** calculations to calculate the voltage output from a 2-resistor voltage divider, the input will be with a maximum of 12 volts, I want the ATMega328 to measure that voltage, so I simply thought of putting two resistors in series with values of 330 ohms and 220 ohms like this:

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

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

<!-- End schematic -->

Theoretically on paper the maximum voltage outputting from the node going to the ATMega328 is ~4.8V, but I want a special safety feature, I want to put in mind that at **anytime** the ground connection can be hung open (to simulate a lose breadboard connection, bad soldering joint etc...) now based upon my understanding if there is no ground connection, the voltage going to the Arduino will be 12V which is a killer, as after looking on the ATMMega328 datasheet it states that

> 28.1 Absolute Maximum Ratings. Voltage on any pin except RESET with respect
to ground => VCC + 0.5

The current will be limited by the 330ohm resistor to only 36mA which I think is a lot, I thought of doubling the resistors values to 330000 and 220000 by that the current will be limited to only 36uA. Again based upon my understanding there is still 12V going to the Arduino but wouldn't it directly drop if the ground connection was cut off ? That's why I ask what is the maximum input **power** to an Arduino?

title: What is the maximum "wattage" can be pushed into an ATMega328 ADC pins?

Answers: 1

body:
This is actually a special case that is undocumented, and in fact not as simple as you would at first think.

The input port itself is not actually what is in question here. Instead every IO pin on the Arduino, be it set to INPUT or OUTPUT, has a set of ESD protection diodes on them. These look like this:

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

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

<!-- End schematic -->

The "IO MODULE" when in INPUT mode can pretty much be ignored, since it is a very high impedance. Just like a (roughly) 10MΩ resistor to ground. Very very little current will flow that way.

D2 is also reverse biased so that direction can be ignored.

So the current will want to flow through D1 to the VCC rail (+5V).  The diodes have approximately a 600mV forward voltage (which is where the VCC + *0.5* comes from).

So we can recalculate, given those parameters, what the current flowing through the diode will be to the 5V rail:

* Voltage difference = 12V - 5V - 0.5V = 6.5V
* Current = V/R = 6.5/330 = 19.7mA

The recommended maximum (from what I can gather) is only 1mA.  You have 20x that.

So you will need at least 20x higher resistances. 10kΩ in the upper half and 6.8kΩ in the bottom half.  That will give you 4.85V on the output at 12V and limit you to 0.65mA in a failure situation.

It also gives you an output impedance of a little over 4kΩ which is below the recommended maximum of 10kΩ for the ADC input.

You can further protect your input by adding a 5V zener diode and small series resistor on the ADC pin so if the voltage goes above 5V it clamps it and protects the pin.

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

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

<!-- End schematic -->


body:
The messages received by the Arduino take the form: $ Ba, Pb, Rc #

Where $ represents the beginning of the message, # represents m, and B, P, and R are characters representing B button, P period and R repetition.

1. `a 'designates the button to be read, which can be 1, 2 or 3.
2. `b 'designates the time (in seconds) that the button should be expected to be pressed.
3. `c 'designates the number of times the button is expected to be pressed during the indicated period.

For example, with the message: $ B2, P4, R2 #
you want to know if button 2 has been pressed twice for four seconds. If condition is verified, then the Arduino must send the message $ MSG, TRUE # where MSG represents the message received without the start and m message characters. Otherwise, you must send the message $ MSG, FALSE #.

Incoming messages must respect the format presented. If not, the condition is not checked and the message $ NOK, MSG, KON # must be sent as a response.

I have no idea how to do this since im new to arduino

title: Arduino exercise that i have no idea how to do

Answers: 1

body:
To begin, forget the Arduino for a moment and assume the task of determining true or false from $....# message. Think about what you would have to do, step by step, to accomplish this. (e.g.: Read the buttons; Record the time and the button states. Is there a message from the Serial port beginning with '$'? Then read the rest of the message. etc.) Then, for each of those steps, do the same thing again: write down the smaller steps to accomplish what that step requires. Do that until you can't break it down any further.

Those small steps should each look like something you could do in C++ code (sometimes called "Arduino" code, but it's really C++). Start replacing each English (or your language) steps with the C++ equivalent. Do this until all of the human-language steps are written in C++.

There will inevitably be mistakes. Fix one or a few at a time. When you're stuck, ask here, something like "Here is my (well formatted) code. I tried [this]. I expected to see [that]. But what happened instead was [something else]. How can I fix it?"; or: "I am getting this error message [with its complete text including any line numbers, please] from the compiler. What does it mean, and how could I have found that out on my own?"

Small steps....


body:
I would like both the motors to spin the attached wheels forward when I push the joystick forward and vice versa. When the joystick is still, the motors should stop spinning. At the moment, when I push the joystick on x-axis and my `x` variable increases both motors spin, but when I push it in the opposite direction and `x` decreases, only motor A spins. Additionaly when I connect the arduino to the power (usb cable to my pc), motor B spins for approx 1 second and then stops.

This is the circuit I have (sorry for a lack of schematic, let's hope this wonderful drawing is enough):
![Text](https://i.stack.imgur.com/TNuvk.png)

The code:

    int MotorAA = 7;
    int MotorAB = 8;

    int MotorBA = 11;
    int MotorBB = 12;

    int x = 0;

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

      pinMode(MotorAA, OUTPUT);
      pinMode(MotorAB, OUTPUT);

      pinMode(MotorBA, OUTPUT);
      pinMode(MotorBB, OUTPUT);

      digitalWrite(MotorAA, LOW);
      digitalWrite(MotorAB, LOW);

      digitalWrite(MotorBA, LOW);
      digitalWrite(MotorBB, LOW);
    }

    void loop() {
      x = analogRead(A0);
      Move();
      Serial.println(x);
    }

    void Move() {
      if (x == 0){
        return;
      }

      if (x > 520)
      {
        digitalWrite(MotorAA, HIGH);
        digitalWrite(MotorAB, LOW);

        digitalWrite(MotorBA, HIGH);
        digitalWrite(MotorBB, LOW);
      }
      else if (x < 480)
      {
        digitalWrite(MotorAA, LOW);
        digitalWrite(MotorAB, HIGH);

        digitalWrite(MotorBA, LOW);
        digitalWrite(MotorBB, HIGH);
      }
      else{
        digitalWrite(MotorAA, LOW);
        digitalWrite(MotorAB, LOW);

        digitalWrite(MotorBA, LOW);
        digitalWrite(MotorBB, LOW);
      }
    }

title: Problem using 2 motors

Answers: 1

body:
The Arduino can definitely not power that many motors. The Arduino's max output current is 0.1A and you might be drawing around 0.5A. Use an external battery like a LiPo battery for the motor controller.

NOTE: Please watch out! Drawing that many amps from Arduino can kill it! So please use the LiPo or normal batteries!


body:
I am not really 100% too sure how to do this but I am trying to make my arduino UNO communicate with my arduino MEGA. The reason why I needed to do this was because I was using the RFID module along with a TFT display and the problem I faced is that on the arduino mega they both needed pin 53. Luckily I have an arduino UNO so I just went for that instead for the display. I am trying to use the `analogWrite()` function to send analog signals from my MEGA over to the UNO so that the TFT display on the UNO can display the results. The UNO would also read the analog inputs coming from the MEGA. This did not work very well. The analog inputs are being sent from the MEGA but the UNO is not reciving them. I am using a PWN pin on the MEGA to send the analog output to the UNO.

This diagram shows what I mean:

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

These are the 2 compotents I am using:

   https://i.stack.imgur.com/CqXdB.png
TFT display

[![][2]][2]

RFID

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

  [1]: https://i.stack.imgur.com/Wg6Dt.png
  [2]: https://i.stack.imgur.com/vmdKP.jpg
  [3]: https://i.stack.imgur.com/TfNjb.png
This shows how the libary sets out the pins. I am only a beginner so I personally don't want to mess around with the libary.

title: Communication between 2 arduino boards

Answers: 2

body:
Pin 53 is just the default "slave select" pin. There is nothing special about it. You can use any other pin as slave select, as long as the libraries for your devices allow it (check the documentation and tutorials for those libraries).

You cannot transmit information with `analogWrite()` since it isn't really analogue (it's PWM), and analogue doesn't have enough definition for reliably representing more than a handful of discrete values anyway.

body:
You can use the I2C interface.

TX:
```
// Wire Master Writer
// by Nicholas Zambetti <http://www.zambetti.com>

// Demonstrates use of the Wire library
// Writes data to an I2C/TWI slave device
// Refer to the "Wire Slave Receiver" example for use with this

// Created 29 March 2006

// This example code is in the public domain.

#include <Wire.h>

void setup() {
  Wire.begin(); // join i2c bus (address optional for master)
}

byte x = 0;

void loop() {
  Wire.beginTransmission(8); // transmit to device #8
  Wire.write("x is ");        // sends five bytes
  Wire.write(x);              // sends one byte
  Wire.endTransmission();    // stop transmitting

  x++;
  delay(500);
}
```

RX:
```
// Wire Slave Receiver
// by Nicholas Zambetti <http://www.zambetti.com>

// Demonstrates use of the Wire library
// Receives data as an I2C/TWI slave device
// Refer to the "Wire Master Writer" example for use with this

// Created 29 March 2006

// This example code is in the public domain.

#include <Wire.h>

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

void loop() {
  delay(100);
}

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

Schematic:

[![Image by Dronebot Workshop; check out their tutorial for more info: https://dronebotworkshop.com/i2c-arduino-arduino/][1]][1]

Image by Dronebot Workshop; check out their tutorial for more info: https://dronebotworkshop.com/i2c-arduino-arduino/

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

  [1]: https://i.stack.imgur.com/hg5l7.png
  [2]: https://i.stack.imgur.com/B0oUp.png


body:
I recently bought the NodeMCU ESP8266 to work on an embedded project, and for whatever reason, the board will only allow me to upload Arduino sketches when I unplug and replug in the board via the Micro-USB cable. I don't have any jumper wires connected to pins in the board--just the Micro-USB cable. The IDE gives me the following:

```
esptool v0.4.13-1-gf80ae31 - (c) 2014 Ch. Klippel <ck@atelier-klippel.de>
 setting board to nodemcu
 setting baudrate from 115200 to 115200
 setting port from COM1 to COM3
 setting address from 0x00000000 to 0x00000000
 espcomm_upload_file
 espcomm_upload_mem
 setting serial port timeouts to 1000 ms
opening bootloader
resetting board
trying to connect
 flush start
 setting serial port timeouts to 1 ms
 setting serial port timeouts to 1000 ms
 flush complete
 espcomm_send_command: sending command header
 espcomm_send_command: sending command payload
 read 0, requested 1
trying to connect
 flush start
 setting serial port timeouts to 1 ms
 setting serial port timeouts to 1000 ms
 flush complete
 espcomm_send_command: sending command header
 espcomm_send_command: sending command payload
 read 0, requested 1
trying to connect
 flush start
 setting serial port timeouts to 1 ms
 setting serial port timeouts to 1000 ms
 flush complete
 espcomm_send_command: sending command header
 espcomm_send_command: sending command payload
 read 0, requested 1
resetting board
trying to connect
 flush start
 setting serial port timeouts to 1 ms
 setting serial port timeouts to 1000 ms
 flush complete
 espcomm_send_command: sending command header
 espcomm_send_command: sending command payload
 read 0, requested 1
trying to connect
 flush start
 setting serial port timeouts to 1 ms
 setting serial port timeouts to 1000 ms
 flush complete
 espcomm_send_command: sending command header
 espcomm_send_command: sending command payload
 read 0, requested 1
trying to connect
 flush start
 setting serial port timeouts to 1 ms
 setting serial port timeouts to 1000 ms
 flush complete
 espcomm_send_command: sending command header
 espcomm_send_command: sending command payload
 read 0, requested 1
resetting board
trying to connect
 flush start
 setting serial port timeouts to 1 ms
An error occurred while uploading the sketch
 setting serial port timeouts to 1000 ms
 flush complete
 espcomm_send_command: sending command header
 espcomm_send_command: sending command payload
 read 0, requested 1
trying to connect
 flush start
 setting serial port timeouts to 1 ms
 setting serial port timeouts to 1000 ms
 flush complete
 espcomm_send_command: sending command header
 espcomm_send_command: sending command payload
 read 0, requested 1
trying to connect
 flush start
 setting serial port timeouts to 1 ms
 setting serial port timeouts to 1000 ms
 flush complete
 espcomm_send_command: sending command header
 espcomm_send_command: sending command payload
 read 0, requested 1
warning: espcomm_sync failed
error: espcomm_open failed
error: espcomm_upload_mem failed

```
Like I said, it programs fine when I unplug and replug in the board, but it is quite a nuisance to do this every time. I'd like the board to automatically start running my code after uploading. Here's what I've tried/found:

-I've made sure the baud rates are matching in the device manager and the upload speed tab in the IDE.

-The device is in fact being picked up in the device manager with the correct driver: USB-SERIAL CH340.

-I've tried pressing the flash button before programming.

-I've tried connecting the ground pin on the NodeMCU to GPIO pin 0.

-Tried reinstalling drivers.

-Tried switching boards.

This may also explain why my serial monitor is so inconsistent as well; sometimes it outputs nothing and sometimes it outputs garbage, but that's a separate issue that I won't worry about for now. Can someone please help me out here? I've referenced a lot of other posts on here as well as tutorials but none have helped me thus far.

Thanks

title: NodeMCU LUA ESP8266 12E Issues with Programming

Answers: 0


body:
I am using two nano-combo for a RC car and when the remote emitter battery is too down if the car was running and battery finally empty the car was still running...is there any way by programming to check communication between the two nanos and solve this problem??. Thanks.

here is the code:
//Receiver program

#include <SPI.h>;
#include "Mirf.h"
#include "nRF24L01.h"
#include "MirfHardwareSpiDriver.h"
Nrf24l Mirf = Nrf24l(10, 9);

void setup()
{
  Serial.begin(9600);
  Mirf.spi = &MirfHardwareSpi;
  Mirf.init();
  Mirf.setRADDR((byte *)"FGHIJ"); //Set your own address (receiver address) using
  5 characters
  Mirf.payload = sizeof(datos);
  Mirf.channel = 90;             //Set the used channel
  Mirf.config();
  //Serial.println("Listening...");  //Start listening to received data

void loop()
{
 if (Mirf.dataReady()) { //When the program is received, the received data is
                            output from the serial port
     Mirf.getData(datos);
     delay(5);

if (datos[7] >= 150) {     //motor forward

    analogWrite(3,0);
    analogWrite(5,255);
  }

  if (datos[7] <= 90) {    motor back

    analogWrite(3,255);
    analogWrite(5,0);
  }

  if (datos[7] > 90 && datos[7] < 150 or datos[7] == 0) { //motor stop

    analogWrite(5,0);
    analogWrite(3,0);

  }
}
}

it works perfect I can control dc motor no problem but if remoto control battery is low or empty then no communication with NANO receiver and the motor spin itself non stop.

I try different things in the void loop like:

 if (!Mirf.dataReady()) {
    analogWrite(5,0);
    analogWrite(3,0);  }

but still the same problem. So that´s why must be something inside Rf library to check if remote control NANO comms is off I don`t know...

Thanks

title: Arduino Nano-combo NRF2401

Answers: 1

body:
You can do somthing like:

    while(radio.hasData()){
    }
This works in the NRFLite library. I don't know about other libraries like RF24 etc.


body:
i have a Arduino GSMShield and I want to send SMS.
When the module try to connecting to the network, it print AT+CREG?
Dont know why cause there's no serial.println for this

    int8_t answer;
    int onModulePin= 2;
    char aux_str[30];

    //Change here your data
    const char pin[]="";
    //const char phone_number[]=" number OK";
    const char sms_text[]="Test-Arduino-Hello World";

    void setup(){

      pinMode(onModulePin, OUTPUT);
      Serial.begin(115200);

      Serial.println("Starting..");

    //  power_on();

      delay(3000);

      //sets the PIN code
      sprintf(aux_str, "AT+CPIN=%s", pin);
      sendATcommand(aux_str, "OK", 2000);

      delay(3000);

      Serial.println("Connecting to the network..");

      while( (sendATcommand("AT+CGREG?", "+CREG= 0,1", 500) ||
        sendATcommand("AT+CGREG?", "+CREG: 0,5", 500)) == 0 );

      Serial.print("Setting SMS mode..");
      sendATcommand("AT+CMGF=1", "OK", 1000);    // sets the SMS mode to text
      Serial.println("Sending SMS");

      sprintf(aux_str,"AT+CMGS=\"%s\"", phone_number);
      answer = sendATcommand(aux_str, ">", 2000);    // send the SMS number
      if (answer == 1)
      {
        Serial.println(sms_text);
        Serial.write(0x1A);
        answer = sendATcommand("", "OK", 20000);
        if (answer == 1)
        {
          Serial.print("Sent ");
        }
        else
        {
          Serial.print("error ");
        }
      }
      else
      {
        Serial.print("error ");
        Serial.println(answer, DEC);
      }

    }

    void loop(){

    }

    void power_on(){

      uint8_t answer=0;
      Serial.println("2/2..");

      // checks if the module is started
      answer = sendATcommand("AT", "OK", 2000);
      if (answer == 0)
      {
        // power on pulse
        Serial.println("2*3..");
        digitalWrite(onModulePin,HIGH);
        delay(3000);
        digitalWrite(onModulePin,LOW);

        // waits for an answer from the module
        while(answer == 0){     // Send AT every two seconds and wait for the answer
          answer = sendATcommand("AT", "OK", 2000);
            Serial.println("3*2..");

        }
      }

    }

    int8_t sendATcommand(const char* ATcommand, const char* expected_answer, unsigned int timeout){

      uint8_t x=0,  answer=0;
      char response[100];
      unsigned long previous;

      memset(response, '\0', 100);    // Initialice the string

      delay(100);

      while( Serial.available() > 0) Serial.read();    // Clean the input buffer

      Serial.println(ATcommand);    // Send the AT command

        x = 0;
      previous = millis();

      // this loop waits for the answer
      do{
        // if there are data in the UART input buffer, reads it and checks for the answer
        if(Serial.available() != 0){
          response[x] = Serial.read();
          x++;
          // check if the desired answer is in the response of the module
          if (strstr(response, expected_answer) != NULL)
          {
            answer = 1;
          }
        }
        // Waits for the answer with time out
      }
      while((answer == 0) && ((millis() - previous) < timeout));

      return answer;
    }

title: Sending AT Command for sms to arduinoShield

Answers: 0


body:
I am trying to start an event after pressing and holding the *FLASH built-in Nodemcu button* for a specific time, I wrote two functions, one for debouncing and detecting the state, the other is to detect the pressing time, I'm not getting any result unless I decrease the input pressing time to less than 1s, which makes the button works as a single-push button, I think i have a problem with **debouncing** the button, I can't figure out where it is?

    /**
    * @brief debounces the button and returns the current level high or low
    *
    * @return int the button state 0: low, 1: high, -1 indetermined
    */
    int button_state(int btn)
    {
        int const DEBOUNCE = 200;
        static int hi = DEBOUNCE;
        static int lo = 0;
        if (digitalRead(buttonPin[btn]))
        {
            if (hi < DEBOUNCE)
            {
                hi++;
            }
            if (lo > 0)
            {
                lo--;
            }
        }
        else
        {
            if (lo < DEBOUNCE)
            {
                lo++;
            }
            if (hi > 0)
            {
                hi--;
            }
        }

        if (hi == DEBOUNCE)
        {
            return 1;
        }
        else if (lo == DEBOUNCE)
        {
            return 0;
        }
        else
        {
            return -1;
        }
    }
    /**
     * @brief Detects the button state and starts a time to calculate pressing duration
     *
     * @param btn input button pin
     * @param PressTime Desired pressing duration to compare to
     * @return int returns 1 when PressTime is reached
     */
    int PressNHold(int btn, int PressTime)
    {
        int lastButtonState = 0, Startpressed = 0, endPressed = 0, holdTime = 0,
        buttonState = button_state(btn);
        if(buttonState != -1)
        {
            if (buttonState != lastButtonState)
            {
                if (buttonState == 1)
                {
                    Startpressed = millis();
                }
                else
                {
                    endPressed = millis();
                    holdTime = endPressed - Startpressed;
                    if (holdTime >= PressTime)
                    {
                        Serial.printf("Button %d pressed for %ds or more\n", btn, holdTime);
                        holdTime = 0;
                        return 1;
                    }
                }
            }
        }
        lastButtonState = buttonState;
    }
    .....

    void loop {

    if (PressNHold(buttonPin[1], 5 * 1000) == 1)
      {
       //launch your event
      }

title: Problems with detecting button digital state

Answers: 1

body: turns out that it is very simple, I shouldn't put buttonPin[1] a variable for PressNHold, I had to put just1, buttonPin was used already in button_state, also, PressnHold local variables should be declared static to not get a reset after function execution.


body:
I am new to Arduino which I got only this week for my project which sends sms from my windows     application.

I have **Arduino Uno R3** and **GPRS Shield (Simcom) Sim900  (S2-1040S-Z0912)**

I am currently following this guide > https://educ8s.tv/arduino-gsm-shield/

As of the moment I have problem connecting the Sim900 to Arduino (I think Arduino cannot detect Sim900). The Arduino is working properly as my PC detected it. Also I confirm that the SIM900 is working properly as I can call the Sim inside and it is ringing (also the led on the device is blinking almost every 3 secs or so)

I found this, but I'm planning to use USB powered only as I only need the SMS feature so I am stacking the SIM900 on top of the Arduino.
https://arduino.stackexchange.com/questions/9483/how-to-communicate-the-arduino-board-with-sim900

I am using this library http://www.tinyosshop.com/datasheet/GSM_GPRS_GPS_Shield_GSMSHIELD.rar

and below is the sketch:

    #include "SIM900.h"
    #include <SoftwareSerial.h>
    #include "sms.h"
    SMSGSM sms;

    int numdata;
    boolean started=false;
    char smsbuffer[160];
    char n[20];

    char sms_position;
    char phone_number[20];
    char sms_text[100];
    int i;

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

        if (gsm.begin(9600))
        {
            Serial.println("\nstatus=READY");
            started=true;
        }
        else
            Serial.println("\nstatus=IDLE");

        if(started)
        {
            if (sms.SendSMS("214", "?15001"))
            {
              Serial.println("\nSMS sent OK.");
            }
            else
            {
              Serial.println("\nError sending SMS.");
            }
        }
    };

    void loop()
    {
        if(started)
        {
            sms_position=sms.IsSMSPresent(SMS_UNREAD);
            if (sms_position)
            {
                Serial.print("SMS postion:");
                Serial.println(sms_position,DEC);
                sms.GetSMS(sms_position, phone_number, sms_text, 100);
                Serial.println(phone_number);
                Serial.println(sms_text);
            }
            delay(2000);
        }
    };

and here is the output

    Trying to force the baud-rate to 9600

    1200
    2400
    4800
    9600
    19200
    38400
    57600
    115200
    ERROR: SIM900 doesn't answer. Check power and serial pins in GSM.cpp

    status=IDLE

What I have tried so far:

I tried the sketch with ```SoftwareSerial mySerial(7, 8);``` and ```SoftwareSerial mySerial(9, 10)``` which i found on other tutorials but didn't work.

I tried modifying ```GSM.cpp``` and modify the value of ```_GSM_TXPIN_```  and ```_GSM_RXPIN_```  to 7, 8 and 9, 10 but didn't work.

Found that the pin on my Arduino is RX=0 and TX=1, and SIM900 is TX=0 and RX=1, tried the SoftwareSerial code above but with 0, 1 and GSM.cpp with 0, 1 but still not working.

I am currently still trying every other sketch i find on the internet but nothing works.

EDIT:
This is the link for the module i bought
https://www.lazada.com.ph/products/sim900-gsm-shield-i267689740-s379728457.html?mp=1

I cant find the link for the datasheet of this specific module so I will try to include the picture of the module

[![SIM900 Bottom][1]][1]

[![SIM900 Top][2]][2]

  [1]: https://i.stack.imgur.com/6VUi8.jpg
  [2]: https://i.stack.imgur.com/YVKHD.jpg

title: Arduino Uno R3 cannot detect GPRS Shield SIM900

Answers: 1

body:
After many trials, I found the solution to my problem, thanks to @Majenko for mentioning the jumpers.

I am still stacking the SIM900 module on top of Arduino.

Switching the jumpers from `D1` and `D0` to `D8` and `D7` solved the problem (see green square on the pic)

I don't know why it needs to be on `D8` and `D7` since on board it says TX=0 and RX=1 and vise-versa for Arduino

[![JUMPERS][1]][1]

Then used the below sketch from this tutorial > https://lastminuteengineers.com/sim900-gsm-shield-arduino-tutorial/

```
#include <SoftwareSerial.h>

//Create software serial object to communicate with SIM900
SoftwareSerial mySerial(7, 8); //SIM900 Tx & Rx is connected to Arduino #7 & #8

void setup()
{
  //Begin serial communication with Arduino and Arduino IDE (Serial Monitor)
  Serial.begin(9600);

  //Begin serial communication with Arduino and SIM900
  mySerial.begin(9600);

  Serial.println("Initializing...");
  delay(1000);

  mySerial.println("AT"); //Handshaking with SIM900
  updateSerial();
  mySerial.println("AT+CSQ"); //Signal quality test, value range is 0-31 , 31 is the best
  updateSerial();
  mySerial.println("AT+CCID"); //Read SIM information to confirm whether the SIM is plugged
  updateSerial();
  mySerial.println("AT+CREG?"); //Check whether it has registered in the network
  updateSerial();
}

void loop()
{
  updateSerial();
}

void updateSerial()
{
  delay(500);
  while (Serial.available())
  {
    mySerial.write(Serial.read());//Forward what Serial received to Software Serial Port
  }
  while(mySerial.available())
  {
    Serial.write(mySerial.read());//Forward what Software Serial received to Serial Port
  }
}
```

With this, it displays correct output on serial monitor based on the tutorial and I can confirm that its working as well on my windows form application as it can send sms from the application.

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


body:
How do you upload code to an Uno from a Mac using the HC08 Bluetooth module? I know I need to use this wiring.
[![Pins used][1]][1]

  [1]: https://i.stack.imgur.com/2K3wz.jpg
Anyone know?

title: How to upload code to an Arduino Uno using HC08 Bluetooth module

Answers: 0


body:
I try to work with a new sensor - HW-MS03 v.06 sensor. Connecting it pin to pin (**v+** to **5v**, **Sig** to digital-input, and **GND** to **GND** ), both to Arduino Uno and ESP8266 Wemos mini, and got same results:

Only once on every port I got proper readings ( `1` for detection for 2 sec, and `0` for no- detection). Most of the time it was a solid `1`.

Code was very simple , just printing its `digitalRead` of the designated pin.

When tried to pull-down the signal, using a 1K resistor, It never got `1` again.

To be sure it is not a malfunctioned sensor I tried with the other one I have, but again- same results.

[link to purchased product][1]
Appreciate any help.

Guy

  [1]: https://www.aliexpress.com/item/32957025450.html?spm=a2g0s.9042311.0.0.27424c4dyE4ZZK

title: Fail getting readings from Radar sensor HW-MS03

Answers: 0


body:
I'm aware this question has probably been asked many times but I'm pulling my hair out.

I'm trying to get sensor data from an arduino to a MySQL server. I've checked the apache access log and the request is there. But it just isn't being inserted into the database. Manually adding the data using the browser works so the php code seems fine. I've allowed apache through the firewall and updated the permissions all to no avail. Code below:

Arduino Main Code:
```
#include "thingProperties.h"
#include <Arduino_MKRENV.h>
#include <WiFi.h>

WiFiClient client;

void setup() {
  // Initialize serial and wait for port to open:
  Serial.begin(9600);
  // This delay gives the chance to wait for a Serial Monitor without blocking if none is found
  delay(1500);

  //Connect to WiFi network
  int status = WL_IDLE_STATUS;
  while (status != WL_CONNECTED){
    Serial.print("Attempting to connect to SSID: ");
    Serial.println(SSID);
    status = WiFi.begin(SSID, PASS);
    delay(10000);
  }
  Serial.println("This is connected.");

  if (!ENV.begin()) {
  Serial.println("Failed to initialize MKR ENV shield!");
  while(1);
  }
  pinMode(2, INPUT);
}

void loop() {
 relativeHumidity = int(ENV.readHumidity());
 lightIntensity = (ENV.readIlluminance());
 airPressure = int(ENV.readPressure(MILLIBAR));
 temperature = int(ENV.readTemperature());
 if(digitalRead(2) == LOW){
   rain = 1;
 }else if(digitalRead(2) == HIGH){
   rain = 0;
 }
 Serial.println("httpRequest");
 httpRequest();
 delay(10000);
}

void httpRequest(){
  // if there's a successful connection:
  if (client.connect(SERVER, 80)) {
    Serial.println("Connecting to server...");
    // send the HTTP PUT request:
    client.print("GET /weather_data.php?temp=");
    Serial.println("GET /weather_data.php?);
    client.print(temperature);
    client.print("&pressure=");
    client.print(airPressure);
    client.print("&humidity=");
    client.print(relativeHumidity);
    client.print("&illumination=");
    client.print(lightIntensity);
    client.print("&rain=");
    client.print(rain);
    client.print(" ");
    client.println("HTTP/1.1");
    client.print(" Host: ");
    client.println(SERVER);
    client.println();
    Serial.println("Added.");
  } else {
    Serial.println("Not connected.");
  }
  if (client.connected()){
    client.stop();
  }
}
```
thingProperties.h:
```
#include <WiFi.h>
#include <SPI.h>

const char THING_ID[] = "c942a18f-7696-4431-952c-76eaea3214ea";

const char SSID[]     = SECRET_SSID;    // Network SSID (name)
const char PASS[]     = SECRET_PASS;    // Network password (use for WPA, or use as key for WEP)
const char SERVER[]   = SECRET_IP;      // Server IP Address

int airPressure;
float lightIntensity;
float relativeHumidity;
bool rain;
float temperature;
```

title: Sending arduino sensor data via WiFi to a MySQL server

Answers: 2

body: WiFi.h is for Arduino WiFi shield. Use the WiFiNINA library for MKR1010

body:
So I don't quite know why, but I started from scratch and it works now. I've put the new code below in case it helps someone in my situation.

```#include "arduino_secrets.h"
// Arduino Low Power - Version: Latest
//#include <ArduinoLowPower.h>
//#include <ArduinoIoTCloud.h>
#include "thingProperties.h"
#include <Arduino_MKRENV.h>
/*
  Repeating Wifi Web Client

  This sketch connects to a a web server and makes a request
  using a WiFi equipped Arduino board.

  created 23 April 2012
  modified 31 May 2012
  by Tom Igoe
  modified 13 Jan 2014
  by Federico Vanzati

  http://www.arduino.cc/en/Tutorial/WifiWebClientRepeating
  This code is in the public domain.
*/

#include <SPI.h>
#include <WiFiNINA.h>

int status = WL_IDLE_STATUS;

// Initialize the Wifi client library
WiFiClient client;

void setup() {
  //Initialize serial and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  // check for the WiFi module:
  if (WiFi.status() == WL_NO_MODULE) {
    Serial.println("Communication with WiFi module failed!");
    // don't continue
    while (true);
  }

  String fv = WiFi.firmwareVersion();
  if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
    Serial.println("Please upgrade the firmware");
  }

  // attempt to connect to Wifi network:
  while (status != WL_CONNECTED) {
    //Serial.print("Attempting to connect to SSID: ");
    //Serial.println(SSID);
    // Connect to WPA/WPA2 network. Change this line if using open or WEP network:
    status = WiFi.begin(SSID, PASS);

    // wait 10 seconds for connection:
    delay(10000);
  }
  // you're connected now, so print out the status:
  //printWifiStatus();
  //Start arduino cloud.
  //ArduinoCloud.begin(ArduinoIoTPreferredConnection);
  //Begin ENV shield.
  if (!ENV.begin()) {
    Serial.println("Failed to initialize MKR ENV shield!");
    while (1);
  }
}

void loop() {
  //ArduinoCloud.update();
  // if there's incoming data from the net connection.
  // send it out the serial port.  This is for debugging
  // purposes only:
  while (client.available()) {
    char c = client.read();
    Serial.write(c);
  }
    //Serial.println("Start reading sensors.");
    relativeHumidity = int(ENV.readHumidity());
    //Serial.println(relativeHumidity);
    lightIntensity = int(ENV.readIlluminance());
    //Serial.println(lightIntensity);
    airPressure = int(ENV.readPressure(MILLIBAR));
    //Serial.println(airPressure);
    temperature = int(ENV.readTemperature());
    //Serial.println(temperature);
    UV_Index = int(ENV.readUVIndex());
    //Serial.println(UV_Index);
    if (digitalRead(2) == LOW) {
      rain = 1;
    } else if (digitalRead(2) == HIGH) {
      rain = 0;
    }
    //Serial.println(rain);
    //Serial.println("Sensor data read.");
    //Serial.println("Start http request.");
    httpRequest();
    //Serial.println("Stop http request");
    delay(60000);
}

// this method makes a HTTP connection to the server:
void httpRequest() {
  // close any connection before send a new request.
  // This will free the socket on the Nina module
  client.stop();

  // if there's a successful connection:
  if (client.connect(server, 80)) {
    //Serial.println("connecting...");
    // send the HTTP PUT request:
    client.print("GET /weather_data.php?temp=");
    client.print(temperature);
    client.print("&pressure=");
    client.print(airPressure);
    client.print("&humidity=");
    client.print(relativeHumidity);
    client.print("&illumination=");
    client.print(lightIntensity);
    client.print("&UV_Index=");
    client.print(UV_Index);
    client.print("&rain=");
    client.print(rain);
    client.print(" ");
    client.println("HTTP/1.1");
    client.println("Host: 192.168.0.29");
    client.println("User-Agent: ArduinoWiFi/1.1");
    client.println("Connection: close");
    client.println();
  } else {
    // if you couldn't make a connection:
    //Serial.println("connection failed");
  }
}

void printWifiStatus() {
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print your board's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  // print the received signal strength:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");
}


body: I have an HC-08 Bluetooth module Bluetooth module hooked up to an Arduino Uno but for some reason, it doesn’t show up in the Bluetooth menu in my iPad settings. Can you help?

title: HC-08 Bluetooth module not showing up on iPad

Answers: 0


body: Not for any practical purpose but just out of curiosity, I want to abuse the flash memory and write it dynamically at run-time.  This is, in a sense, what the bootloader does.  If I understand it, the only way to modify flash is to do so from instructions written to the boot sector.  Is it possible to stick a simple function in there that writes to flash memory, and call it from running code?  If so, how do I put it there?  I have no issue with calling functions from function pointers, so I don't think I'll have an issue actually calling the function once I get there, but I need to know how to stick into flash in the first place.

title: Can I force a function to live in the boot sector without overwriting the bootloader?

Answers: 1

body:
The Optiboot version 8 has a `do_spm` function which can be called from application. The Optiboot repository contains [an example][1] for the use of this function.

SPM is the AVR CPU instruction to write to flash memory. The Optiboot wraps this in a function. A pointer to this function is put in a 'vector table' at the beginning of the bootloader. The first pointer jumps to `main`, the second pointer jumps to `do_spm`. The optiboot.h then has the function as (version for small Optiboot)
```c
typedef void (*do_spm_t)(uint16_t address, uint8_t command, uint16_t data);
const do_spm_t do_spm = (do_spm_t)((FLASHEND-511+2)>>1)
```

I made an enhancement of this, a [copy_flash_pages function][2] with reset option to bootload an AVR from its own flash. It is added as third entry in the 'vectors table' of Optiboot. It is used in my [ArduinoOTA][3] library for AVR MCUs.
```c
typedef void (*copy_flash_pages_t)(uint32_t dest, uint32_t src, uint16_t page_count, uint8_t reset);
const copy_flash_pages_t copy_flash_pages = (copy_flash_pages_t)((FLASHEND-1023+4)>>1);
```

  [1]: https://github.com/Optiboot/optiboot/tree/master/optiboot/examples/test_dospm
  [2]: https://github.com/Optiboot/optiboot/pull/269
  [3]: https://github.com/jandrassy/ArduinoOTA


body: How do you connect HC-06 with HC-08 with the HC-06 as master and HC-08 as slave? I will try it using 2 Arduino Unos.

title: How to connect HC-06 with HC-08 with the HC-06 as master and HC-08 as slave?

Answers: 1

body:
You cannot. The HC-06 is a slave only device.

So you need to use a device as master, that is actually capable of it. I don't know, if the HC-08 can do it. Another typical bluetooth master device is the HC-05. Just like HC-06, but can also be a master.


body:
I'm trying to develop code, compile, upload and use the Serial monitor for debugging of a script for an Arduino Pro Mini. I'm using Emacs as my IDE. I'm having trouble determining the exact sequence of commands to do this most efficiently. What I'd like to do is:

 - Edit my code, compile and upload from Emacs (able to do this now)
 - Switch to a window running minicom (or putty, etc.) and observe the debug output.
 - rinse and repeat

My problem is that now, I have to stop and start minicom each iteration, after I upload the code. Sometimes, restarting minicom causes my Arduino to reboot, and that then displays the debugging output correctly. Sometimes, it takes two minicom restarts to accomplish this. Also, if I don't kill minicom before uploading, it just prints garbage to the screen, and seems to hang. I'm hoping for something like the Arduino IDE Serial monitor, that just runs continuously, and that correctly displays the debugging output.

Ideally, I'd like help coming up with the exact commands to run a Serial monitor that wouldn't require stopping and starting it. Is this possible?

Thanks for all your suggestions and advice.

-Kevin

title: Workflow when using Emacs, Arduino-makefile and Serial monitor?

Answers: 0


body:
hello guys i have a problem ,

i have a usb host shield v2.0 from circuits @home  attached to an arduino mega and to a usb wireless reciever mouse ,
this is the serial monitor  output :
```
x=0 dy=3
dx=0 dy=-1
dx=0 dy=-1
dx=0 dy=-1
dx=0 dy=-1
dx=0 dy=-1
dx=0 dy=1
dx=0 dy=-2
dx=0 dy=-2
dx=0 dy=2
dx=0 dy=9
dx=0 dy=6
dx=0 dy=-1
dx=0 dy=2
dx=0 dy=-1
dx=0 dy=-1
dx=1 dy=0
dx=2 dy=0
dx=1 dy=0
dx=2 dy=0
```
and this is the code from the library usbhidbootmouse :
```
#include <hidboot.h>
#include <usbhub.h>

// Satisfy the IDE, which needs to see the include statment in the ino too.
#ifdef dobogusinclude
#include <spi4teensy3.h>
#endif
#include <SPI.h>

class MouseRptParser : public MouseReportParser
{
protected:
 void OnMouseMove (MOUSEINFO *mi);
 void OnLeftButtonUp (MOUSEINFO *mi);
 void OnLeftButtonDown (MOUSEINFO *mi);
 void OnRightButtonUp (MOUSEINFO *mi);
 void OnRightButtonDown (MOUSEINFO *mi);
 void OnMiddleButtonUp (MOUSEINFO *mi);
 void OnMiddleButtonDown (MOUSEINFO *mi);
};
void MouseRptParser::OnMouseMove(MOUSEINFO *mi)
{
    Serial.print("dx=");
    Serial.print(mi->dX, DEC);
    Serial.print(" dy=");
    Serial.println(mi->dY, DEC);
};
void MouseRptParser::OnLeftButtonUp (MOUSEINFO *mi)
{
    Serial.println("L Butt Up");
};
void MouseRptParser::OnLeftButtonDown (MOUSEINFO *mi)
{
    Serial.println("L Butt Dn");
};
void MouseRptParser::OnRightButtonUp (MOUSEINFO *mi)
{
    Serial.println("R Butt Up");
};
void MouseRptParser::OnRightButtonDown (MOUSEINFO *mi)
{
    Serial.println("R Butt Dn");
};
void MouseRptParser::OnMiddleButtonUp (MOUSEINFO *mi)
{
    Serial.println("M Butt Up");
};
void MouseRptParser::OnMiddleButtonDown (MOUSEINFO *mi)
{
    Serial.println("M Butt Dn");
};

USB     Usb;
USBHub     Hub(&Usb);
HIDBoot<USB_HID_PROTOCOL_MOUSE>    HidMouse(&Usb);

MouseRptParser                               Prs;

void setup()
{
    Serial.begin( 115200 );
#if !defined(__MIPSEL__)
    while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection
#endif
    Serial.println("Start");

    if (Usb.Init() == -1)
        Serial.println("OSC did not start.");

    delay( 200 );

    HidMouse.SetReportParser(0, &Prs);
}

void loop()
{
  Usb.Task();
}
```
i wanna know the dx is equal to 1 when i press the left button on mouse and is equal to 2 when i press the right button on mouse and the dy is responsible for the x and y coordinates from - to + ? how a single value is responsible for x and y both ?

title: usb host shield + wireless mouse (Read 5 times)

Answers: 0


body:
I would appreciate any help solving this as I have spent several hours trying to debug. My code seems to stop when I get to the initialization of the motor shield.

> motorShield.begin();

```
#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_MS_PWMServoDriver.h"
#include <LiquidCrystal.h>

//CREATE LCD OBJECTm
LiquidCrystal lcd = LiquidCrystal(2, 3, 4, 5, 6, 7);

//CREATE MOTOR SHIELD OBJECT
Adafruit_MotorShield motorShield = Adafruit_MotorShield();

//SET MOTOR VALUES
Adafruit_DCMotor *frontRight = motorShield.getMotor(1);
/*Adafruit_DCMotor *rearRight = motorShield.getMotor(2);
Adafruit_DCMotor *frontLeft = motorShield.getMotor(3);
Adafruit_DCMotor *rearLeft = motorShield.getMotor(4);*/

//DEFINE SENSORS
#define centerTrigPin A2
#define centerEchoPin A3

//DEFINE SENSOR VALUES
long centerDuration; // Variable for the duration of sound wave travel
int centerDistance; // Variable for the distance measurement

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

  lcd.begin(16, 2); //Set LCD dimensions

  //motorShield.begin();

  //frontRight->setSpeed(50);
  /*rearRight->setSpeed(50);
  frontLeft->setSpeed(50);
  rearLeft->setSpeed(50);*/

  //frontRight->run(RELEASE);
  /*rearRight->run(RELEASE);
  frontLeft->run(RELEASE);
  rearLeft->run(RELEASE);*/

  pinMode(centerEchoPin, INPUT);
  pinMode(centerTrigPin, OUTPUT);
}
void loop() {
  //GET CENTER SENSOR
  digitalWrite(centerTrigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(centerTrigPin, HIGH);
  delayMicroseconds(10);
  centerDuration = pulseIn(centerEchoPin, HIGH);
  centerDistance = centerDuration * 0.034 / 2;

  if (centerDistance <= 10){
    //SERIAL OUTPUT
    Serial.print("OBJECT: ");
    Serial.print(centerDistance);
    Serial.println(" cm");

    //LCD OUTPUT
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("OBJECT");
  }else{
    //SERIAL OUTPUT
    Serial.print("DRIVE: ");
    Serial.print(centerDistance);
    Serial.println(" cm");

    //LCD OUTPUT
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("DRIVE");
  }//End Forward/Reverse Check
}//End loop
```
[![enter image description here][1]][1]
[![enter image description here][2]][2]
[![enter image description here][3]][3]

  [1]: https://i.stack.imgur.com/Nj3W9.jpg
  [2]: https://i.stack.imgur.com/86QHs.jpg
  [3]: https://i.stack.imgur.com/lUnEe.jpg

title: Adafruit v2.3 Motor Shield Initialization Failure

Answers: 0


body:
I want to make an RC car based on two Arduino Nanos, two [nRF24L01](https://infocenter.nordicsemi.com/pdf/nRF24L01P_PS_v1.0.pdf)s (Rx and Tx), and a [Pololu brushed motor driver](https://www.pololu.com/product/2990), and it works, more or less.

Sometimes it works very well and everything goes nicely and suddenly it will "freeze" and stop receiving and when it does, the servo always goes to 0° (I think it must be the Rx because it prints the same value until the next restart in the serial monitor).

It seems the servo trebles in the same direction (to 0°) only when I send high PWM values until it stops reading new data and "freezes".

I have 2 batteries, one for the Nano with a step-up converter, and another for the servo and the brushed motor;  they share a common ground. Everything is close to each other and connected by wires soldered to a prototype breadboard. It is really messy but makes a good contact.

So it seems it is a noise problem, doesn't it? But what else could it be? How can I suppress that noise? I have already watched the Pololu guide about noise but I didn't try the bypass capacitors since I don't know how to solder them properly (can they burn the servo?)

Here is the code for the Tx

```C++
#include <SPI.h>
#include "RF24.h"

const int ledBot = 8;
const int padx = A0;
const int pady = A1;
const int sw = 3;
int sws;
int x;
int y;
int botState;
int aBotState;
int ledState;
const float un = 0.25;
const float fy = 0.176;
int sens [4]; // 0: throttle, 1: foward/backwards, 2: steering, 3: lights

RF24 radio(9, 10); // CE, CSN
const byte address[6] = "00001";
void setup() {
  //Serial.begin(9600);
  pinMode(padx, INPUT);
  pinMode(pady, INPUT);
  pinMode(sw, INPUT);
  pinMode(ledBot, INPUT_PULLUP);
  radio.begin();
  radio.setDataRate (RF24_2MBPS);
  radio.openWritingPipe(address);
  radio.setPALevel(RF24_PA_MIN);
  radio.stopListening();
}

void loop() {
  x = analogRead(padx);
  y = analogRead(pady);
  sws = digitalRead(sw);
  botState = digitalRead(ledBot);
  y = 1024-y;

  switch (sws){ //foward and backwards

  case 0:
    sens [0] = un*x;
    sens [1] = 0;
    sens [2] = min(135, max(50, y*fy-2));
    break;

  case 1:
    sens [0] = un*x;
    sens [1] = 1;
    sens [2] = min(135, max(50, y*fy-2));
    break;
  }

  if ( botState == HIGH && aBotState == LOW) { //button switch part
    if (ledState == 0) {
      ledState = 1;
      sens [3] = ledState;
    }
    else {
      ledState = 0;
      sens [3] = ledState;
    }
  }
  aBotState = botState;
  radio.write(&sens, sizeof(sens));

  //Serial.println(sens[0]);
  //Serial.println(ledState);
  // Serial.println(sens[1]);
  //Serial.println(sens [3]);
}
```

And here for the Rx:

```c++
#include <Servo.h>
#include <SPI.h>
#include "RF24.h"

int sens [4];
const int polph = 7;
const int polen = 6;
const int led1 = 2;
const int led2 = 3;
const int ledError = 8;

Servo servo;
RF24 radio(9, 10); //
const byte address[6] = "00001";

void setup() {
  pinMode(polph, OUTPUT);
  pinMode(polen, OUTPUT);
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);

  pinMode(ledError, OUTPUT);
  digitalWrite(led1, HIGH);
  digitalWrite(led2, HIGH);
  delay(300);
  digitalWrite(led1, LOW);
  digitalWrite(led2, LOW);
  delay(300);
  digitalWrite(led1, HIGH);
  digitalWrite(led2, HIGH);
  delay(300);
  digitalWrite(led1, LOW);
  digitalWrite(led2, LOW);
  servo.attach(5);
  //Serial.begin(9600);
  radio.begin();
  radio.setDataRate (RF24_2MBPS);
  radio.openReadingPipe(0, address);
  radio.setPALevel(RF24_PA_MIN);
  radio.startListening();
}

void loop() {
  if (radio.available()) {
    digitalWrite(ledError, LOW);
    radio.read(&sens, sizeof(sens));
    analogWrite(polen, sens [0]);
    digitalWrite(polph, sens[1]);
    servo.write(sens [2]);
    digitalWrite(led1, sens [3]);
    digitalWrite(led2, sens [3]);
  }
}
```

title: Motor noise on my Arduino RC?

Answers: 1

body:
Electrical noise is **the** problem quite often. In order to minimize noise, several key points must be observed:

1. Solder one 0.1uF ceramic capacitor from each terminal to the motor case. These are called decoupling capacitors and are used to suppress HF noise creeping in from the motors due to sparking/arching.

2. Choose appropriate AWS rating for your motor leads and adequate power supply. Inappropriately thin leads or insufficient battery discharge current can cause abrupt voltage drop on acceleration which will lead to sudden MCU resets (brown out resets).

3. Twist the leads around each other. This helps to further nullify arching noise.

As for Arduino, it is not the best way for making reliable RC software because it does simple things terribly wrong, e.g. sequential software polling instead of using hardware input capture. I would highly recommend learning how to write firmware for MCUs in native mode.

Check out this link to gain some inspiration on how to build an RC motor driver:

https://github.com/neoxic/STM8-RC-Dual-Motor-Driver#building-a-dual-12a-bidirectional-esc


body:
I'm trying to set up a network like the following:

|Host| <-------> |Node x 3|

I want to have a two-way connection between a host and each node, but each node cannot communicate with other nodes. The host and nodes are all NodeMCU 1.0 ESP8266 12E with the same software on each node (has to be this way). The problem I'm dealing with at the moment is that I can send messages successfully, but my host is not receiving any messages from the nodes. Right now I'm only testing it with one node, and I'm only testing sending from the node to the host just to make sure the devices are connected properly. Here's my code for both the node and host:

```
#include <espnow.h>
#include <ESP8266WiFi.h>
#include <string.h>

//Macros

#define PORT 80
#define CHANNEL 1
#define ESP_OK 0

//-----Anonymous Project----//
//-----Author: Anonymous----------//
//
// Last Date Modified: 6/18/20
//
// Description: This project is designed to have several node arduinos connected to a host arduino. Whenever an
// event is triggered on a node arduino, the host reacts to this and activates the corresponding LEDs.
// The host arduino acts as a server while the node arduinos act as clients. Both the hosts and clients send data
// back and forth to each other to ensure arduinos are still active and are responding properly.
// All the software is the same on host and client arduinos, so whether an arduino is a host
// or client is determined by its MAC Address.
//
// Progress: At the moment, this project successfully establishes connections between the host and the nodes.
// I am currently working on figuring out why the nodes do not successfully send to the host.

//Global Variables
char hostMACAdd [18] = "XX:XX:XX:XX:XX:XX"; //change this MAC address to change the host node
String SSID = "NETWORK NAME"; //change this SSID to change the network name
String Password = "PASSWORD"; //change this to change the password required to connect. If node, connect to SSID with password given

bool isHost; //flag that controls whether host or node code executes
bool A = true; //flag for event A
bool B = false; //flag for event B

//Server-Specific Globals
bool haveMessage;        //global for detecting readings

//Client-Specific Globals

//Function Prototypes
uint8_t * MACAddrToInt(String MAC);
void configDeviceAP(void);
void initESPNow();
void wifiConnect();

void setup() {
    Serial.begin(115200);
    Serial.println();
    delay(500);

    //is it a host or node?
    if(strcmp(WiFi.macAddress().c_str(),hostMACAdd)){
      //node
      isHost = false;
      Serial.println("Client powered!");
      Serial.println();

      //set device in station mode if it's a node
      WiFi.mode(WIFI_STA); // Station mode for esp-now sensor node

      //Enable ESP Now
      initESPNow();

      Serial.println("Initialization successful!");

      //attempt to connect to host
      Serial.println("Connecting to " + SSID);

      esp_now_set_self_role(ESP_NOW_ROLE_COMBO);
      if(esp_now_add_peer(MACAddrToInt(hostMACAdd), ESP_NOW_ROLE_SLAVE, CHANNEL, NULL, 0)!=ESP_OK){
        Serial.println("Error connecting to host.");
        //TODO: make this station a host and a node
      }

      Serial.println("Connection to host successful!");
    }
    else{
      //host
      isHost = true;
      Serial.println("Host powered!");
      Serial.println();

      //set device in AP mode if it's the host
      WiFi.mode(WIFI_AP);

      //Enable ESP Now
      initESPNow();

      Serial.println("Initialization successful!");
      esp_now_set_self_role(ESP_NOW_ROLE_COMBO);

      int unsuccessfullyRegistered = esp_now_register_recv_cb([](uint8_t *mac, uint8_t *data, uint8_t len) {

        String deviceMac = "";
        deviceMac += String(mac[0], HEX);
        deviceMac += String(mac[1], HEX);
        deviceMac += String(mac[2], HEX);
        deviceMac += String(mac[3], HEX);
        deviceMac += String(mac[4], HEX);
        deviceMac += String(mac[5], HEX);

        Serial.println("Message received from device: ");
        Serial.println(deviceMac);
        Serial.println(*data, DEC);
        //haveMessage = true;
      });

      if(!unsuccessfullyRegistered){
        Serial.println("Callback function registered!");
      }
      else{
        Serial.println("Callback function not registered.");
      }

      Serial.println("Waiting for clients...");
    }
}

void loop() {

  if(isHost){

  }
  else{

    String IP = WiFi.localIP().toString();
    uint8_t flagMsg;                  //message for events A and B.

    //             Inputs | Output
    //                    |
    //             A   B  |  flagMsg
    //             0   0  |  0
    //             0   1  |  1
    //             1   0  |  2
    //             1   1  |  3

    //FOR TESTING
    A = true;
    B = true;

    if(A){
      if(B){
        flagMsg = 3;
      }
      else{
        flagMsg = 2;
      }
    }
    else{
      if(B){
        flagMsg = 1;
      }
      else{
        flagMsg = 0;
      }
    }

    //String message = IP + " " + String(flagMsg); //maybe add pattern to this as well

    uint8_t * intMAC = MACAddrToInt(hostMACAdd);

    while(esp_now_send(intMAC, &flagMsg, sizeof(flagMsg))!=ESP_OK){
      Serial.println("Failed to send.");
      delay(2000);
    }

    Serial.println("Message Sent!");
    delay(5000);
  }

}

//convert MAC Address string to int
uint8_t * MACAddrToInt(String MAC){
  uint8_t hostMACAddArray [6];
  int values[6];

  sscanf(hostMACAdd, "%x:%x:%x:%x:%x:%x", &values[0], &values[1], &values[2], &values[3], &values[4], &values[5]);

  for(int i = 0; i<6; ++i){
    hostMACAddArray[i] = (uint8_t) values[i];
  }
  return hostMACAddArray;
}

//set as Access Point
void configDeviceAP(){
  bool result = WiFi.softAP(SSID.c_str(), Password.c_str(), CHANNEL, 0);
  if (!result)
  {
    Serial.printf("AP Config failed.");
  }
  else
  {
    Serial.printf("AP Config Success. Broadcasting with AP: ");
    Serial.printf("%s", SSID.c_str());
  }
}

void initESPNow(){
  WiFi.disconnect();
  if (esp_now_init() == ESP_OK) {
    Serial.println("ESPNow Init Success");
  }
  else
  {
    Serial.println("ESPNow Init Failed");
    ESP.restart();
  }
}

void wifiConnect() {
  WiFi.mode(WIFI_STA);
  Serial.printf("");
  Serial.printf("Connecting... "); //Serial.printf("%s",SSID.c_str());
  WiFi.begin(SSID, Password);
  while (WiFi.status() != WL_CONNECTED) {
     delay(250);
     Serial.print(".");
  }
  Serial.print("\nWiFi connected."); //Serial.printf("%s",WiFi.localIP().c_str());
}
```

The code isn't near finished yet, but theoretically the nodes should send an integer to the host and the host should print it. The console output for the node shows that the message is being sent, but the last thing that shows up on the host console output is "Waiting for clients", which would indicate that the host isn't receiving anything. I'm pretty new to ESP_NOW but I've been reading a lot of documentation on it recently and my code shouldn't be breaking any rules, but here we are.

Some potential problems that I suspect:

 1. I had to define ESP_OK in my file for whatever reason. In most examples I've looked at, this macro hasn't had to be defined, and it's possible the value isn't actually 0.
 2. Maybe I need to set up the host as a WIFI_AP_STA instead of WIFI_AP. Not sure why this would cause problems, but I'm just speculating at this point.

title: ESP-NOW host not receiving data

Answers: 0


body:
I am trying to store data in ATmega328 (Arduino Uno) using the following code using tinkercad:
```
#include <EEPROM.h>

void setup() {
  int addr, data=1;
  Serial.begin(9600);
  for (addr=0; addr<1023; addr++) {
    EEPROM.write(addr, data);
  }
  for (addr=0; addr<1023 ; addr++) {
    Serial.print(EEPROM.read(addr), DEC);
  }
}
```
When I simulate the code in the tinkercad, then i get the following error:
```
In function `main':
43: undefined reference to `loop'
 error: ld returned 1 exit status
```
Please help me where is the error in my code. I am not able to understand the error source.

title: Error while inputting EEPROM.read() and EEPROM.write()

Answers: 1

body:
Have you looked at any Arduino IDE example programs?

They all have a `setup()` and `loop()` function.

Apparently, Tinkercad is missing the `loop()` function in your code.

You can solve the issue by adding an empty `void loop() { }` after your `void setup() { ... }` code.


body:
I am aiming at precise speed control of [this BLDC motor][1]: it has an integrated controller, outputting digital Hall signal (period 20.8ms on oscilloscope, w/o load) and taking PWM as input for speed regulation.

As far as my knowledge goes, this is a task for PID: measure Hall pulses at input, adjust duty cycle of the PWM based on target period/frequency of the Hall output.

The speed should be controlled with <1% error (even less is better).

* Is this goal realistic with this particular motor?
* How should I measure pulse duration?
* Is `pulseIn` (with interrupts disabled) going to be sufficiently precise? Should I measure lows or highs?
* Should I measure several pulses instead (and how)? Or should I accept imprecision in the pulse period and compensate (smooth) it using integral/derivative terms?
* Do I need more than 8-bit PWM resolution for this task? (I will use Nano at first, but might switch to Nano Every, which has 10-bit PWM).

Any other comments/suggestions are welcome.

  [1]: https://www.ebay.com/itm/DC-6V-12V-24V-Schnecken-Getriebemotor-5-60RPM-Brushless-Worm-Gear-Motor-GW4058/283678690228

title: Speed control of BLDC with an integrated controller (Hall out, PWM in)

Answers: 2

body:
This is only a partial answer, about measuring pulse period or duration.

For best accuracy, I would recommend using the “input capture” feature
of a 16-bit timer. This is not as easy as using `pulseIn()` or timing
the signal with `micros()`: you will have to carefully study the MCU's
datasheet and manually configure the bits of some I/O registers. You
will be rewarded with high accuracy (single-cycle if the timer runs at
the MCU clock speed) and without the jitter inherent to any
software-based approach.

Beware that the Nano and Nano Every use different MCUs, with very
different timers. Both have input capture capability, but if you switch
from one to the other you will have to redo most of the work. Note that
the Nano is capable of 10-bit PWM if you program it low-level.

A software-based approach (`pulseIn()` or `attachInterrupt()` +
`micros()`) has the advantage of portability.

body:
To expand a little on Edgar's answer:

There are two main ways of measuring frequency, and both require different resources and are better for different situations.

The method Edgar describes using the Input Capture method, is good for rapidly changing low frequency signals where you want to respond very quickly to changes in the frequency. It works by measuring the time between two pulses using a free-running timer. Of course you can only measure frequencies as fast as the timer can run, which is pretty fast anyway, and if configured right it can run almost entirely asynchronously so you can just query the current recorded time whenever you need to.

The other option is to count the number of pulses within a given time period. This can also be done in hardware but using a different set of peripherals.

For this you have two timers. Timer 1 has the ability to us an external signal on pin D5 as its clock. This basically turns it into a pulse counter, and every time a pulse arrives on the timer pin it increments the count by one.

Then you have a second timer which triggers an interrupt at a predefined period. What that period is depends on the responsiveness you want and the frequency range you want to measure.  You can also use the "prescaler" of Timer 1 to increase the frequency measurement range by only counting every 2nd or 4th or 8th etc edge.

Of course, all that timer use would interfere with PWM generation on the Nano, but should be better on the Nano Every, but you'd want to check the datasheet for timer usages.

So in summary:

**Input capture**

* Fast response
* Limited frequency range

**Pulse counting with timer 1**

* Slower response
* Naturally smoothed output
* Greater frequency range
* Understands the concept of zero Hz
* Interferes with PWM generation

Whichever method you choose, sure, feed it through PID to create a stable output RPM.