title: CO2 sensor for arduino

text:
# Question
Title: CO2 sensor for arduino
I want to add CO2 measuring feature to my room weather station. Can someone please recommend a CO2 sensor easy to integrate with Arduino?

# Answer
You could try the K30 CO2 sensor. There is also a guide using it to make an arduino CO2 detector here.

I've also seen people use the MG-811 module, you can buy them from dfrobot.com . There is also good documentation for how to use the MG-811 with arduino here.
> 4 votes

# Answer
Based on hands-on time with CCS811 CO2 sensors, I would recommend against them. They tend to drift high, sometimes way high, and then come back to their senses and provide reasonable readings when reset.

I've tried two batches of CJMCU-811 sensors, purchased months apart (hoping to get a different manufacturing lot), and they were all rubbish.
> 1 votes

# Answer
This worked well for me on a colour screen. A small delay for the sensor and a long burn (24hrs) required. But easy KIWI

```
#include <XTronical_ST7735.h> // Hardware-specific library
#include <SPI.h>
#include <Adafruit_GFX.h>    // Core graphics library
#include <sSense-CCS811.h>
#include <dht.h>

#define SERIAL_SPEED  9600

#define TFT_SCLK 13         // SPI clock
#define TFT_MOSI 11         // SPI Data
#define TFT_CS   10         // Display enable (Chip select), if not enabled will not talk on SPI bus
#define TFT_RST   9         // Display reset pin, you can also connect this to the Arduino reset
                            // in which case, set this #define pin to -1!
#define TFT_DC     8
CCS811 ssenseCCS811;
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS,  TFT_DC, TFT_RST);
dht DHT;

#define DHT11_PIN 7

void setup()
{
  DebugPort.begin(SERIAL_SPEED);
  delay(5000);
  Serial.println("s-Sense CCS811 I2C sensor.");
  if(!ssenseCCS811.begin(uint8_t(I2C_CCS811_ADDRESS), uint8_t(CCS811_WAKE_PIN), driveMode_1sec))
    DebugPort.println("Initialization failed.");
  tft.init();   // initialize a ST7735S chip,
  tft.setRotation(0);
  tft.fillScreen(ST7735_GREEN);
  tft.setTextColor(ST7735_RED);
  tft.setCursor(0, 30);
  tft.setTextSize(1);
}

void loop()
{
  ssenseCCS811.setEnvironmentalData((float)(21.102), (float)(57.73));  // replace with temperature and humidity values from HDC2010 sensor
  int chk = DHT.read11(DHT11_PIN);
  if (ssenseCCS811.checkDataAndUpdate())
  {

    tft.fillScreen(ST7735_GREEN);
    tft.setCursor(10,10);
    tft.print("CO2 ppm  ");
    tft.print(ssenseCCS811.getCO2());
    tft.setCursor(10,40);
    tft.print("tVOC ppb ");
    tft.print(ssenseCCS811.gettVOC());
    tft.setCursor(10,70);
    tft.print("Temp C   ");
    tft.print(DHT.temperature);
    tft.setCursor(10,100);
    tft.print("Humid %  ");
    tft.print(DHT.humidity);

  }
  else if (ssenseCCS811.checkForError())
  {
    ssenseCCS811.printError();
  }

  delay(2000);
}

```
> 1 votes

# Answer
How about this one? http://cgi.ebay.de/ws/eBayISAPI.dll?ViewItem&item=380915024016&ssPageName=STRK:MESE:IT The MG-811 is highly sensitive to CO2 and less sensitive to alcohol and CO.
> 0 votes

# Answer
This one: http://sandboxelectronics.com/?product=mg-811-co2-gas-sensor-module

They also got a nice demo code there. Here is a wiring scheme if you use the demo without modification:

1. Red - 5V
2. Black - GND
3. Yellow - Analog input 0
4. Green - Digital I/O 2

The easeir integration ever
> 0 votes

---
Tags: sensors
---


# Question
Title: Modbus TCP together with MQTT over same ethernet
I'm currently in a planning phase for a project. I want to read some sensor data over Modbus TCP, do some simple calculations on the Arduino and publish the results over MQTT. Which means I have 2 RJ-45s and two different protocols.

Given a Arduino Mega with an Ethernet shield. Does it work if I simply add a network switch and connect the sensor and an internet router to it, and use both protocols in parallel? Or are there any problems running such a thing on only one Arduino?

# Answer
> 1 votes
> Does it work if I simply add a network switch and connect the sensor and an internet router to it, and use both protocols in parallel?

Kind of, yes. You just connect both the MODBUS device and the Arduino to the network provided by the router. The Arduino is just a normal network device - the IP address for it allocated by the router, as is the MODBUS device.

Any device can communicate with any other device in a network.

---
Tags: ethernet, modbus, mqtt, ethernet-shield
---


# Question
Title: Grounding Arduino UNO with external voltage source
I was experimenting with external power supplies and noticed that the only way the Arduino can communicate with an externally powered sensor (through SPI) is when the GND pin under power AND the GND pin under AREF on the UNO is connected to the external ground?

From what I understand, both these pins are connected to the boards mutual ground (i.e. they are already internally connected)?

In the attached image both the orange and yellow wires were required and would not work individually.

I feel that either this shouldn't be the case or I am simply missing something and would appreciate an explanation.

Thanks!

# Answer
The circuit in the image shows the plan of the Arduino Uno, as you can see the GND pin under AREF and in the GND under the Power pin VCC are connected.

you can double-check this with a tester and figure it out. so yes, they are internally connected.

now, in your breadboard you have connected GND to VIN, that's the problem, Vin is an input voltage that is regulated to supply 3.3V and 5V.

So remember to share grounds with external voltage supplies (DC-DC), that set the circuit to the same reference.
> 1 votes

---
Tags: arduino-uno, power
---


# Question
Title: log STK500v2 commands while flashing a Mega
My final goal is to replicate the process with which the PC programs the arduino. I have gone through the commands.h file and made a couple of attempts to get the logic right. But no success at flashing the arduino. Is there any way to view the Hex commands that are written to the arduino from the PC? Something like verbose but list every hex command. My idea is that I will just replicate the same commands and try uploading hex files from SD card.

# Answer
Add the flag `-vvvv` to the `avrdude` command. That will show you the flow of data between the computer and the Arduino.

You can copy and paste the executed command from the IDE and run it in a terminal / command window adding the flag manually. Or you could modify the platform.txt file for the AVR core.
> 1 votes

---
Tags: arduino-mega, attiny
---


# Question
Title: Wiring Multiple MPU 6050 to Micro/Lenardo
*disclaimer I am new at hardware/circuits*

I am currently trying to connect two MPU-6050 to a single Micro board. In addition, there are 5 additional buttons to be connected.

I am under the impression to connect multiple devices to the I2C bus, there must be unique addresses. I read there was a way to make unique addresses (https://playground.arduino.cc/Main/MPU-6050/#multiple).

However I am not sure of the wiring or if the voltage/resistors/anything is supposed to be located.

I have a sketch of what it may look like.

Can anyone help me verify that this is the proper configuration? Or what a proper configuration would look like?

# Answer
Buttons are just buttons. You can have them "active high" with pulldown resistors as you have there (10K is fine. The actual value doesn't really matter, just don't have it too low or excess current will be drawn), or "active low" without resistors and connecting to ground when pushed instead of VCC and use INPUT\_PULLUP. The choice is yours. There's no real benefit in this situation to either way of doing it.

The critical part is your AD0 connection. Whether you connect one to ground and leave the other unconnected, or connect one to VCC and leave the other unconnected, depends entirely on the design of the breakout board. It should have a resistor on the AD0 pin internally that either connects it to GND or to VCC. If it connects to GND then you need to link that pin to VCC to override it. If it connects it to VCC (or more likely 3.3V) internally then you need to connect it to GND to override it.

To find out which you will have to either consult the documentation or schematic for the board or measure the voltage at the AD0 pin. If it measures 0V (within a few mV) then it connects to ground and you will have to connect it to VCC to override it. If it measures more (probably nearer 3.3V) then connect it to ground to override it.

Because those chips are 3.3V and the board contains a 3.3V regulator (if your boards are the same as you picture in your wiring diagram) the chances are that the AD0 is pulled up to 3.3V so you just need to connect one to ground.

So it looks to me like your wiring diagram is most likely suitable and correct, pending confirmation of the pullup/pulldown in the AD0 pin.
> 1 votes

---
Tags: i2c, arduino-leonardo, arduino-micro, mpu6050, atmega32u4
---


# Question
Title: DS3231 rtc.begin() always returning false
I am using Arduino UNO with a RTC DS3231 module. I have connected SDA & SCL pins of RTC DS3231 with Arduino SDA & SCL pins near AREF pin. RTC module is having attached battery also. My code is as below :

```
#include <RTClib.h>
#include <Wire.h>
RTC_DS3231 rtc;

char daysOfTheWeek[7][12] = {
  "Sunday", "Monday", "Tuesday",
  "Wednesday", "Thursday", "Friday", "Saturday"
};

void setup() {
  Serial.begin(9600);
  Wire.begin();
  delay(3000);
  //rtc.begin();
  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }
  if (rtc.lostPower()) {
    Serial.println("RTC lost power, lets set the time!");
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
       // Following line sets the RTC with an explicit date & time
    // for example to set January 27 2017 at 12:56 you would call:
    // rtc.adjust(DateTime(2017, 1, 27, 12, 56, 0));
  }
}

void loop() {
  DateTime now = rtc.now();
  Serial.println("Current Date & Time: ");
    Serial.print(now.year(), DEC);
    Serial.print('/');
    Serial.print(now.month(), DEC);
    Serial.print('/');
    Serial.print(now.day(), DEC);
    Serial.print(" (");
    Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
    Serial.print(") ");
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.println();

    Serial.println("Unix Time: ");
    Serial.print("elapsed ");
    Serial.print(now.unixtime());
    Serial.print(" seconds/");
    Serial.print(now.unixtime() / 86400L);
    Serial.println(" days since 1/1/1970");

    // calculate a date which is 7 days & 30 seconds into the future
    DateTime future (now + TimeSpan(7,0,0,30));

    Serial.println("Future Date & Time (Now + 7days & 30s): ");
    Serial.print(future.year(), DEC);
    Serial.print('/');
    Serial.print(future.month(), DEC);
    Serial.print('/');
    Serial.print(future.day(), DEC);
    Serial.print(' ');
    Serial.print(future.hour(), DEC);
    Serial.print(':');
    Serial.print(future.minute(), DEC);
    Serial.print(':');
    Serial.print(future.second(), DEC);
    Serial.println();

    Serial.println();
    delay(1000);

}

```

While running the above command and opening the Serial Monitor, I always get following output:

```
Couldn't find RTC

```

Can anyone help me to correct this problem.

# Answer
No fault is there in code. Rather, it was an faulty connection which prevented RTC module from working. Now, after restoration, the RTC module is working fine.
> 3 votes

---
Tags: arduino-uno, rtc
---


# Question
Title: How do you configure ADC7 on the Arduino Pro Mini as a digital output?
I'm attempting to use the pin labeled 'ADC7' from the Atmega328p TQFP package. The Atmega documentation suggests that can be used either as an analog or digital I/O point. I'm trying to configure it as a digital output.

Referencing the documentation (and specifically arduino\_pins.h), I determined the associated pin number was 21. Thus I called pinMode(21, OUTPUT). However, this pin does not appear to be working with my SPI device. I previously tested that the device worked, but I made a last second change of pin and am now using ADC7.

So my question, is there an additional step required to configure this pin as a digital output? I noticed that this pin doesn't exist on the DIP Atmega328p (used on the Arduino Uno), so I'm not sure if I have to add another line of code somewhere.

Any ideas?

Regards,

# Answer
> 2 votes
Those are analog pins only. They can't be used as outputs or digital inputs.

# Answer
> 3 votes
This may be a little left field, but I use the ADC6 and ADC7 inputs to detect switches. I just don't use the digitalRead() function, but instead use analogRead() function. Using a resistor network and switches and some decoder software code in our sketch, we can use a single input pin to interface with many more switches. The switches can only be on one at a time, but in many instances, this would be OK.

# Answer
> 2 votes
Gerben's answer probably is correct, but there are some interesting discrepancies in Atmel datasheets for various models of the ATmega168 and ATmega328, as outlined below.

Some Atmel datasheets refer to ADC6 and ADC7 as PE2 and PE3, while others just refer to them as ADC6 and ADC7.

Regarding port E, the 2014 ATmega168PA and 2015 ATmega168 datasheets say nothing, don't list any of PE0 to PE3, and don't specify port membership for ADC6 and ADC7. They show pins 3 and 6 on the LQFP as Gnd and Vcc, vs PE0 and PE1 as in the ATmega168PB sheet.

Regarding port E, the 2015 ATmega168PB datasheet says:

```
Table 15-12.  Port E Pins Alternate Functions
     Port Pin       Alternate Function
       PE3          ADC7 (ADC Input Channel 7)
       PE2          ADC6 (ADC Input Channel 6)
       PE1          NONE
       PE0          ACO (AC Output Channel 0)

```

Regarding port E, the 2016 ATmega168PB datasheet, Atmel-42176G-ATmega48PB/88PB/168PB\_Datasheet\_Complete-03/2016, says the following and also lists several Alternate Functions while referring to Timer/Counters 3 and 4 (although there seem to be no registers in the register summary relevant to such Timer/Counters):

"Port E is an 4-bit bi-directional I/O port with internal pull-up resistors (selected for each bit). The Port E output buffers have symmetrical drive characteristics with both high sink and source capability. As inputs, Port E pins that are externally pulled low will source current if the pull-up resistors are activated. The Port E pins are tri-stated when a reset condition becomes active, even if the clock is not running."

```
Table 19-12.  Port E Pins Alternate Functions
 Port Pin            Alternate Function
 PE3                 ADC7 (ADC Input Channel 7)
                     T3 (Timer/Counter 3 External Counter Input) & PCINT27
 PE2                 ADC6 (ADC Input Channel 6)
                     ICP3 (Timer/Counter3 Input Capture Input)
                     SS1 (SPI1 Bus Master Slave select) & PCINT26
 PE1                 T4 (Timer/Counter 4 External Counter Input)
                     SCL1 (2-wire Serial1 Bus Clock Line) & PCINT25
 PE0                 ACO (AC Output Channel 0)
                     ICP4 (Timer/Counter4 Input Capture Input)
                     SDA1 (2-wire Serial1 Bus Data Input/Output Line) & PCINT24

```

# Answer
> 2 votes
According to everything you can find in the datasheet about ADC6 and ADC7 they are analog only pins.

The pinout for the TQFP-32 as used on the Pro Mini shows those two pins as *only* having the analog functions:

I suspect the color coding of the pins may be wrong - they should be solid green. They have no port names on the pins, purely the ADCx designation.

The block diagram for the chip shows the ADC6/7 pins being separate from a port:

As you can see the other 6 pins are referred to by the digital port they share, but ADC6 and 7 are known purely as ADC6 and ADC7.

The pin function table, 6-1, shows ADC6 and ADC7 as the only functions on those pins. No digital port names, nothing - just purely analog input.

So in summary, for the ATMega328P chip used in the Arduino Pro Mini you cannot use those two pins for digital at all, only for analog input.

# Answer
> 2 votes
I appreciate this is an old question but those pins are subtly different on the ATMEGA328PB compared to the ATMEGA328P which I discovered recently. See the Microchip app note AT15007, page 3.

Microchip AT15007 app note

---
Tags: arduino-pro-mini, digital
---


title: Arduino ESP32F-TFT-1.44 Driver

text:
# Question
Title: Arduino ESP32F-TFT-1.44 Driver
**Datasheet** https://github.com/espressif/esp-hosted/files/5190376/ESP-32F.pdf

The below code is not working.
I can see only White screen

```

#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library for ST7735
#include <Adafruit_ST7789.h> // Hardware-specific library for ST7789
#include <SPI.h>

#define TFT_CS        26 // Hallowing display control pins: chip select
#define TFT_RST       16 // Display reset
#define TFT_DC        17 // Display data/command select
#define TFT_BACKLIGHT  13 // Display backlight pin

// OPTION 1 (recommended) is to use the HARDWARE SPI pins, which are unique
// to each board and not reassignable. For Arduino Uno: MOSI = pin 11 and
// SCLK = pin 13. This is the fastest mode of operation and is required if
// using the breakout board's microSD card.

// For 1.44" and 1.8" TFT with ST7735 (including HalloWing) use:
//Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);

// For 1.54" TFT with ST7789:
//Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);

// OPTION 2 lets you interface the display using ANY TWO or THREE PINS,
// tradeoff being that performance is not as fast as hardware SPI above.
#define TFT_MOSI 19  // Data out
#define TFT_SCLK 18  // Clock out
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);

float p = 3.1415926;

void setup(void) {
  Serial.begin(115200);
  Serial.print(F("Hello! ST77xx TFT Test"));

  //#ifdef ADAFRUIT_HALLOWING
  // HalloWing is a special case. It uses a ST7735R display just like the
  // breakout board, but the orientation and backlight control are different.
  tft.initR(INITR_HALLOWING);        // Initialize HalloWing-oriented screen
  pinMode(TFT_BACKLIGHT, OUTPUT);
  digitalWrite(TFT_BACKLIGHT, HIGH); // Backlight on
  //#else
  // Use this initializer if using a 1.8" TFT screen:
  //  tft.initR(INITR_BLACKTAB);      // Init ST7735S chip, black tab

  // OR use this initializer (uncomment) if using a 1.44" TFT:
  //  tft.initR(INITR_144GREENTAB); // Init ST7735R chip, green tab

  // OR use this initializer (uncomment) if using a 0.96" 180x60 TFT:
  //  tft.initR(INITR_MINI160x80);  // Init ST7735S mini display

  // OR use this initializer (uncomment) if using a 1.54" 240x240 TFT:
  //tft.init(240, 240);           // Init ST7789 240x240
  //#endif

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

  uint16_t time = millis();
  tft.fillScreen(ST77XX_BLACK);
  time = millis() - time;

  Serial.println(time, DEC);
  delay(500);

  // large block of text
  tft.fillScreen(ST77XX_BLACK);
  testdrawtext("Hello World asdf sdf adfsdf sdf sdf sdf sdf sdf ", ST77XX_BLACK);
  delay(1000);

  Serial.println("done");
  delay(1000);
}

void loop() {
  tft.invertDisplay(true);
  delay(500);
  tft.invertDisplay(false);
  delay(500);
}

void testdrawtext(char *text, uint16_t color) {
  tft.setCursor(0, 0);
  tft.setTextColor(color);
  tft.setTextWrap(true);
  tft.print(text);
}

```

# Answer
> 0 votes
```
#include <WiFi.h>

#include <time.h>
#include "AudioFileSourcePROGMEM.h"
#include "AudioGeneratorTalkie.h"
#include "AudioOutputI2S.h"

#ifndef STASSID
#define STASSID "WIFI_SSID"
#define STAPSK  "WIFI_PASSWORD"
#endif

const char *ssid = STASSID;
const char *pass = STAPSK;

long timezone = 7;
byte daysavetime = 1;

#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library for ST7735
#include <Adafruit_ST7789.h> // Hardware-specific library for ST7789
#include <SPI.h>

#define TFT_CS        26 // Hallowing display control pins: chip select
#define TFT_RST       16 // Display reset
#define TFT_DC        17 // Display data/command select
#define TFT_BACKLIGHT  13 // Display backlight pin

// OPTION 1 (recommended) is to use the HARDWARE SPI pins, which are unique
// to each board and not reassignable. For Arduino Uno: MOSI = pin 11 and
// SCLK = pin 13. This is the fastest mode of operation and is required if
// using the breakout board's microSD card.

// For 1.44" and 1.8" TFT with ST7735 (including HalloWing) use:
//Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);

// For 1.54" TFT with ST7789:
//Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);

// OPTION 2 lets you interface the display using ANY TWO or THREE PINS,
// tradeoff being that performance is not as fast as hardware SPI above.
#define TFT_MOSI 23  // Data out
#define TFT_SCLK 18  // Clock out
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);

float p = 3.1415926;

AudioGeneratorTalkie *talkie;
AudioOutputI2S *out;

bool GetLocalTime(struct tm * info, uint32_t ms) {
  uint32_t count = ms / 10;
  time_t now;

  time(&now);
  localtime_r(&now, info);

  if (info->tm_year > (2016 - 1900)) {
    return true;
  }

  while (count--) {
    delay(10);
    time(&now);
    localtime_r(&now, info);
    if (info->tm_year > (2016 - 1900)) {
      return true;
    }
  }
  return false;
}

int threshold = 40;
bool touch1detected = false;
bool touch2detected = false;

void gotTouch1() {
  touch1detected = true;
}

void gotTouch2() {
  touch2detected = true;
}
void initLCD() {
  tft.initR(INITR_HALLOWING);        // Initialize HalloWing-oriented screen
  pinMode(TFT_BACKLIGHT, OUTPUT);
  digitalWrite(TFT_BACKLIGHT, HIGH); // Backlight on

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

  uint16_t time = millis();
  tft.fillScreen(ST77XX_BLACK);
  time = millis() - time;

  Serial.println(time, DEC);
  delay(500);

  // large block of text
  tft.fillScreen(ST77XX_BLACK);

}
void setup(void) {

  touchAttachInterrupt(T2, gotTouch1, threshold);
  touchAttachInterrupt(T0, gotTouch2, threshold);

  Serial.begin(115200);
  Serial.print(F("Hello! ST77xx TFT Test"));

  initLCD();

  /*
    delay(1000);

    // tft print function!
    tftPrintTest();
    delay(4000);

    // a single pixel
    tft.drawPixel(tft.width() / 2, tft.height() / 2, ST77XX_GREEN);
    delay(500);

    // line draw test
    testlines(ST77XX_YELLOW);
    delay(500);

    // optimized lines
    testfastlines(ST77XX_RED, ST77XX_BLUE);
    delay(500);

    testdrawrects(ST77XX_GREEN);
    delay(500);

    testfillrects(ST77XX_YELLOW, ST77XX_MAGENTA);
    delay(500);

    tft.fillScreen(ST77XX_BLACK);
    testfillcircles(10, ST77XX_BLUE);
    testdrawcircles(10, ST77XX_WHITE);
    delay(500);

    testroundrects();
    delay(500);

    testtriangles();
    delay(500);

    mediabuttons();
    delay(500);

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

    //*/

  Serial.print("Connecting to ");
  Serial.println(ssid);
  testdrawtext("Connecting to ", ST77XX_WHITE);

  WiFi.begin(ssid, pass);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("WiFi connected");

  tft.fillScreen(ST77XX_BLACK);
  testdrawtext(strcat("WiFi connected ", ""), ST77XX_WHITE);
  clearText();
  delay(1000);

  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  Serial.println("Contacting Time Server");

  configTime(3600 * timezone, daysavetime * 3600, "time.nist.gov", "0.pool.ntp.org", "1.pool.ntp.org");
  struct tm tmstruct ;
  do {
    tmstruct.tm_year = 0;
    Serial.printf(".");
    GetLocalTime(&tmstruct, 5000);
    delay(100);
  } while (tmstruct.tm_year < 100);

  audioLogger = &Serial;
  out = new AudioOutputI2S(0, 1);
  talkie = new AudioGeneratorTalkie();
  talkie->begin(nullptr, out);
}

char temp[300];

int alarmHours = 5;
int alarmMinutes = 44;

void loop() {
  //  tft.invertDisplay(true);
  //  delay(500);
  //  tft.invertDisplay(false);
  //  delay(500);

  struct tm tmstruct ;
  tmstruct.tm_year = 0;
  GetLocalTime(&tmstruct, 5000);
//  Serial.printf("\nNow is : %d-%02d-%02d %02d:%02d:%02d Alarm %2d : %2d\n",
//                tmstruct.tm_year + 1900, tmstruct.tm_mon + 1,
//                tmstruct.tm_mday, tmstruct.tm_hour,
//                tmstruct.tm_min, tmstruct.tm_sec,
//                alarmHours, alarmMinutes);
  Serial.printf("\nNow is : %02d:%02d:%02d\n",
                tmstruct.tm_hour,
                tmstruct.tm_min, tmstruct.tm_sec);

  //  sprintf(temp, "%d-%02d-%02d% 02d:%02d:%02d Alarm %2d : %2d\n", tmstruct.tm_year + 1900, tmstruct.tm_mon + 1, tmstruct.tm_mday, tmstruct.tm_hour, tmstruct.tm_min, tmstruct.tm_sec, alarmHours, alarmMinutes);
  sprintf(temp, "%02d:%02d:%02d", tmstruct.tm_hour, tmstruct.tm_min, tmstruct.tm_sec);

  if (60 * alarmHours + alarmMinutes <= 60 * tmstruct.tm_hour + tmstruct.tm_min) {
    Serial.printf("-Alarm-");
    Serial.printf("\n** Now is : %d-%02d-%02d %02d:%02d:%02d Alarm %2d : %2d\n",
                  tmstruct.tm_year + 1900, tmstruct.tm_mon + 1,
                  tmstruct.tm_mday, tmstruct.tm_hour,
                  tmstruct.tm_min, tmstruct.tm_sec,
                  alarmHours, alarmMinutes);
    //    sayTime(tmstruct.tm_hour, tmstruct.tm_min, talkie);
    //    initLCD();
  }

  //  clearText();

  tft.fillRect(40, 30, 50, 10, ST77XX_BLACK );
  //  testdrawtext(temp, ST77XX_WHITE);
  tft.setCursor(40, 30);
  tft.setTextColor(ST77XX_WHITE);
  //  tft.setTextWrap(true);
  tft.print(temp);

  delay(1000);

  if (touch1detected) {
    touch1detected = false;
    Serial.println("Touch 1 detected");
    alarmMinutes = alarmMinutes + 10;
  }
  if (touch2detected) {
    touch2detected = false;
    Serial.println("Touch 2 detected");
    alarmMinutes = alarmMinutes + 10;
  }
}

void testlines(uint16_t color) {
  tft.fillScreen(ST77XX_BLACK);
  for (int16_t x = 0; x < tft.width(); x += 6) {
    tft.drawLine(0, 0, x, tft.height() - 1, color);
    delay(0);
  }
  for (int16_t y = 0; y < tft.height(); y += 6) {
    tft.drawLine(0, 0, tft.width() - 1, y, color);
    delay(0);
  }

  tft.fillScreen(ST77XX_BLACK);
  for (int16_t x = 0; x < tft.width(); x += 6) {
    tft.drawLine(tft.width() - 1, 0, x, tft.height() - 1, color);
    delay(0);
  }
  for (int16_t y = 0; y < tft.height(); y += 6) {
    tft.drawLine(tft.width() - 1, 0, 0, y, color);
    delay(0);
  }

  tft.fillScreen(ST77XX_BLACK);
  for (int16_t x = 0; x < tft.width(); x += 6) {
    tft.drawLine(0, tft.height() - 1, x, 0, color);
    delay(0);
  }
  for (int16_t y = 0; y < tft.height(); y += 6) {
    tft.drawLine(0, tft.height() - 1, tft.width() - 1, y, color);
    delay(0);
  }

  tft.fillScreen(ST77XX_BLACK);
  for (int16_t x = 0; x < tft.width(); x += 6) {
    tft.drawLine(tft.width() - 1, tft.height() - 1, x, 0, color);
    delay(0);
  }
  for (int16_t y = 0; y < tft.height(); y += 6) {
    tft.drawLine(tft.width() - 1, tft.height() - 1, 0, y, color);
    delay(0);
  }
}

char prevText[300];

void clearText() {
  testdrawtext(prevText, ST77XX_BLACK);
}

void testdrawtext(char *text, uint16_t color) {
  strcpy(prevText, text);
  tft.setCursor(0, 0);
  tft.setTextColor(color);
  tft.setTextWrap(true);
  tft.print(text);
}

void testfastlines(uint16_t color1, uint16_t color2) {
  tft.fillScreen(ST77XX_BLACK);
  for (int16_t y = 0; y < tft.height(); y += 5) {
    tft.drawFastHLine(0, y, tft.width(), color1);
  }
  for (int16_t x = 0; x < tft.width(); x += 5) {
    tft.drawFastVLine(x, 0, tft.height(), color2);
  }
}

void testdrawrects(uint16_t color) {
  tft.fillScreen(ST77XX_BLACK);
  for (int16_t x = 0; x < tft.width(); x += 6) {
    tft.drawRect(tft.width() / 2 - x / 2, tft.height() / 2 - x / 2 , x, x, color);
  }
}

void testfillrects(uint16_t color1, uint16_t color2) {
  tft.fillScreen(ST77XX_BLACK);
  for (int16_t x = tft.width() - 1; x > 6; x -= 6) {
    tft.fillRect(tft.width() / 2 - x / 2, tft.height() / 2 - x / 2 , x, x, color1);
    tft.drawRect(tft.width() / 2 - x / 2, tft.height() / 2 - x / 2 , x, x, color2);
  }
}

void testfillcircles(uint8_t radius, uint16_t color) {
  for (int16_t x = radius; x < tft.width(); x += radius * 2) {
    for (int16_t y = radius; y < tft.height(); y += radius * 2) {
      tft.fillCircle(x, y, radius, color);
    }
  }
}

void testdrawcircles(uint8_t radius, uint16_t color) {
  for (int16_t x = 0; x < tft.width() + radius; x += radius * 2) {
    for (int16_t y = 0; y < tft.height() + radius; y += radius * 2) {
      tft.drawCircle(x, y, radius, color);
    }
  }
}

void testtriangles() {
  tft.fillScreen(ST77XX_BLACK);
  int color = 0xF800;
  int t;
  int w = tft.width() / 2;
  int x = tft.height() - 1;
  int y = 0;
  int z = tft.width();
  for (t = 0 ; t <= 15; t++) {
    tft.drawTriangle(w, y, y, x, z, x, color);
    x -= 4;
    y += 4;
    z -= 4;
    color += 100;
  }
}

void testroundrects() {
  tft.fillScreen(ST77XX_BLACK);
  int color = 100;
  int i;
  int t;
  for (t = 0 ; t <= 4; t += 1) {
    int x = 0;
    int y = 0;
    int w = tft.width() - 2;
    int h = tft.height() - 2;
    for (i = 0 ; i <= 16; i += 1) {
      tft.drawRoundRect(x, y, w, h, 5, color);
      x += 2;
      y += 3;
      w -= 4;
      h -= 6;
      color += 1100;
    }
    color += 100;
  }
}

void tftPrintTest() {
  tft.setTextWrap(false);
  tft.fillScreen(ST77XX_BLACK);
  tft.setCursor(0, 30);
  tft.setTextColor(ST77XX_RED);
  tft.setTextSize(1);
  tft.println("Hello World!");
  tft.setTextColor(ST77XX_YELLOW);
  tft.setTextSize(2);
  tft.println("Hello World!");
  tft.setTextColor(ST77XX_GREEN);
  tft.setTextSize(3);
  tft.println("Hello World!");
  tft.setTextColor(ST77XX_BLUE);
  tft.setTextSize(4);
  tft.print(1234.567);
  delay(1500);
  tft.setCursor(0, 0);
  tft.fillScreen(ST77XX_BLACK);
  tft.setTextColor(ST77XX_WHITE);
  tft.setTextSize(0);
  tft.println("Hello World!");
  tft.setTextSize(1);
  tft.setTextColor(ST77XX_GREEN);
  tft.print(p, 6);
  tft.println(" Want pi ? ");
  tft.println(" ");
  tft.print(8675309, HEX); // print 8,675,309 out in HEX!
  tft.println(" Print HEX!");
  tft.println(" ");
  tft.setTextColor(ST77XX_WHITE);
  tft.println("Sketch has been");
  tft.println("running for : ");
  tft.setTextColor(ST77XX_MAGENTA);
  tft.print(millis() / 1000);
  tft.setTextColor(ST77XX_WHITE);
  tft.print(" seconds.");
}

void mediabuttons() {
  // play
  tft.fillScreen(ST77XX_BLACK);
  tft.fillRoundRect(25, 10, 78, 60, 8, ST77XX_WHITE);
  tft.fillTriangle(42, 20, 42, 60, 90, 40, ST77XX_RED);
  delay(500);
  // pause
  tft.fillRoundRect(25, 90, 78, 60, 8, ST77XX_WHITE);
  tft.fillRoundRect(39, 98, 20, 45, 5, ST77XX_GREEN);
  tft.fillRoundRect(69, 98, 20, 45, 5, ST77XX_GREEN);
  delay(500);
  // play color
  tft.fillTriangle(42, 20, 42, 60, 90, 40, ST77XX_BLUE);
  delay(50);
  // pause color
  tft.fillRoundRect(39, 98, 20, 45, 5, ST77XX_RED);
  tft.fillRoundRect(69, 98, 20, 45, 5, ST77XX_RED);
  // play color
  tft.fillTriangle(42, 20, 42, 60, 90, 40, ST77XX_GREEN);
}

```

---
Tags: arduino-ide, lcd, esp32, tft
---


title: A4988 Vref too low

text:
# Question
Title: A4988 Vref too low
I'm driving a stepper rated at 5V/1.7A using an A4988-based driver circuit with a 12V power supply. An Arduino controls the stepping sequence.

According to the datasheet for my A4988, I should be calculating Vref as:

Imax = Vref / (8 * Rs) so,

Vref = I * (8 x Rs) (where Rs is 0.1 ohm on this particular board and confirmed with meter).

So, Vref should be (1.7A x .8) or 1.36V to drive 1.7amps.

The problem is, I cannot adjust the A4988 to get Vref up that high.

With the adjustment pot full swing, the best I can get is .9 to 1V. When I energize and hold the motor and use an amp meter, the coil is drawing about .9 amps -- which is still less than the 70% of 1.7 Amps I would like (using full-step mode).

Is Vref potential limited by the input voltage of 12 volts? Is there something else I'm missing?

Thanks in advance.

Added: This is the circuit I am using:

# Answer
You have a 30K resistor divider in series with the trimmer. Change the 30K resistor for one rated at 27K to obtain those higher values. ;)
> 1 votes

---
Tags: stepper, a4988
---


title: Can FastLED be made faster?

text:
# Question
Title: Can FastLED be made faster?
I am using FastLED to drive 16 pixels on an addressable WS2812B RGB LED strip. My application has extremely tight timing constraints. Specifically, I need to turn the LEDs on and off within less than 1 ms. I tried FastLED but it requires a minimum of 2.5 ms to execute the Show command, regardless of the number of LEDs attached. I analyzed another library and that one has the exact same limitation. In fact, I found a snippet of code that said roughly: "if this operation performs in less than 2500 us, then wait idly until the 2500 us have passed. Apparently this wait is necessary due to timing requirements of WS2812x strips. Does anyone have any advise about other addressable RGB LED strips or libraries that can be turned on and off within 1 ms?

# Answer
By default the fastLed is limiting the refresh rate to 400 fps (i.e. 2.5ms).

You can disable that with `FastLED.setMaxRefreshRate(0);`
> 4 votes

---
Tags: arduino-uno, teensy, ws2812
---


# Question
Title: My two slave SPI setup on arduino not working correctly
I am trying to connect a DPS310 and an ADXL345 to my Arduino using 4 wire SPI. When the individually tested (i.e. each has its own script), the output is correct, however when the scripts are combined the ADXL output is garbage, but the DPS functions.

What we expect to see:

```
Temperature = 24.14 *C
Pressure = 857.88 hPa
X: -4  Y: 4  Z: 29

```

What we actually see:

```
Temperature = 24.14 *C
Pressure = 857.88 hPa
X: 0  Y: 0  Z: 0    // and does not change when tilted

```

When the DPS310 line is commented out, the ADXL works fine (this line is indicated in script)

The whole script (with the faulty line indicated):

```
#include <SparkFun_ADXL345.h>
#include <Adafruit_DPS310.h>

// ADXL obj
#define ADXL345_CS   9 // SPI pin
ADXL345 ADXL = ADXL345_CS; // Instantiate obj with CS pin
int x = 0, y = 0, z = 0;

// DPS obj
#define DPS310_CS   10 // SPI pin
Adafruit_DPS310 dps; // Instantiate obj (pin is set in setup)
sensors_event_t temp_event, pressure_event;

void setup() {
   Serial.begin(115200);
   while (!Serial) delay(10);

   // ADXL SETUP
   digitalWrite(ADXL345_CS, LOW); // START COMM
   Serial.print("ADXL345: ");
   ADXL.powerOn();
   delay(50);
   ADXL.setRangeSetting(16);
   ADXL.setSpiBit(0);
   ADXL.set_bw(ADXL345_BW_12_5);
   ADXL.setInterrupt(0x84, true);
   ADXL.setAxisOffset(0, 0, 5);
   ADXL.readAccel(&x, &y, &z);
   if(x != -1 && y != -1 && z != -1) {
     Serial.println("[PASSED]");
   } else {
     Serial.println("[FAILED]");
   }
   digitalWrite(ADXL345_CS, HIGH); // END COMM

   // DPS SETUP
   digitalWrite(DPS310_CS, LOW); // START COMM
   Serial.print("DPS310: ");
   if (! dps.begin_SPI(DPS310_CS)) { /////////////////PROBLEM LIES HERE//////////////////
      Serial.println(" [FAILED]");
   }
   Serial.println(" [PASSED]");

   dps.configurePressure(DPS310_64HZ, DPS310_64SAMPLES);
   dps.configureTemperature(DPS310_64HZ, DPS310_64SAMPLES);
   digitalWrite(DPS310_CS, HIGH); // END COMM
}

void loop() {
    digitalWrite(ADXL345_CS, LOW);
    ADXL.readAccel(&x, &y, &z);
    digitalWrite(ADXL345_CS, HIGH);

    digitalWrite(DPS310_CS, LOW);
    dps.getEvents(&temp_event, &pressure_event);
    digitalWrite(DPS310_CS, HIGH);

    Serial.print("Temperature = ");
    Serial.print(temp_event.temperature);
    Serial.println(" *C");
    Serial.print("Pressure = ");
    Serial.print(pressure_event.pressure);
    Serial.println(" hPa");

    Serial.print("X: ");
    Serial.print(x);
    Serial.print("  Y: ");
    Serial.print(y);
    Serial.print("  Z: ");
    Serial.println(z);

    delay(50);
}

```

I think the fault might lie in the classes written for these devices, for instance maybe they were written for single SPI device or have different frequencies/modes? (I'm probably wrong though XD). I have not yet tried to setup the SPI for each device manually (programming commandment: do no reinvent the wheel), so any help would be greatly appreciated.

# Answer
> 1 votes
The ADXL345 uses SPI\_MODE3 and DPS310 the SPI\_MODE0. The libraries for these devices don't use SPI transactions, but set the settings only in begin(), so they can't be used together.

Your options to solve this is either to put one sensor on software SPI or to put one or both sensors on I2C.

The ADXL345 can be used as I2C device. Its library supports I2C with the constructor when no parameters are provided. Does your module have an option to wire it to I2C?

The Adafruit library for DPS310 has built-in software SPI, so you can use it with any set of pins. And it too supports I2C.

---
Tags: arduino-uno, spi, communication
---


# Question
Title: Help me for interfacing Arduino with AMTP32M VOICE IC
i'm trying to get control an Aplus chip aMTP32M (stores audio samples) with Arduino . this amtp32m ic provide CPU SERIAL MODE its come with DATA and CLOCK pin.i try Spi mode with Amtp32m ic but its not working.

Please help me for this. Link for for DATASHEET of AMTP32M IC -http://www.aplusinc.com.tw/proimages/Mtp%20Vioce%20Ic/aMTP32M/aMTP32M/Datasheet/aMTPxxM-Datasheet\_V1.1\_20141216.pdf

# Answer
> 1 votes
Finely i try the below code for serial mode. it's worked perfectly...

```
type def union
  {
unsigned char BYTE;
struct
{
    unsigned        BIT0:1;
    unsigned        BIT1:1;
    unsigned        BIT2:1;
    unsigned        BIT3:1;
    unsigned        BIT4:1;
    unsigned        BIT5:1;
    unsigned        BIT6:1;
    unsigned        BIT7:1;
};
}ByteToBit;

void Play(unsigned char Val)
{
  ByteToBit SectionNo;

  SectionNo.BYTE = Val;

CLOCK = 1;
DATA  = 0;
CLOCK = 0;

DATA  = SectionNo.BIT0;
CLOCK = 1;
CLOCK = 0;
DATA  = SectionNo.BIT1;
CLOCK = 1;
CLOCK = 0;
DATA  = SectionNo.BIT2;
CLOCK = 1;
CLOCK = 0;
DATA  = SectionNo.BIT3;
CLOCK = 1;
CLOCK = 0;
DATA  = SectionNo.BIT4;
CLOCK = 1;
CLOCK = 0;
DATA  = SectionNo.BIT5;
CLOCK = 1;
CLOCK = 0;
DATA  = SectionNo.BIT6;
CLOCK = 1;
CLOCK = 0;
DATA  = SectionNo.BIT7;
CLOCK = 1;
CLOCK = 0;

DATA  = 0;
CLOCK = 1;
DATA  = 1;

return ;
}

 void main(void)
 {
    unsigned char SectionNo;

CLOCK = 1;
DATA  = 1;

SectionNo = 0x00;
while(1)
{
    Play(SectionNo);
    Delay_1mS();        // Wait for BUSY set up time...
    while(BUSY);        // Voice playing...
    SectionNo++;
}

return ;
}

```

# Answer
> 0 votes
according to this :  it's more similar to I2C than SPI. anyway, it's just 2 wire custom serial interface. you can use any 2 GPIOs for this purpose. for sending a byte, you have to:

1. initialize 2 GPIOS (CLK\_IO and DAT\_IO) to output, high.
2. set DAT\_IO low
3. wait at least 1us (according to datasheet ver 1.1, page 18) then set CLK\_IO low.
4. place the D0 bit value on the DAT\_IO
5. toggle the CLK\_IO (set it high, wait at leas 1us, set it low)
6. do steps 4 and 5 for all the remaining bits.
7. at the end set CLK\_IO high
8. wait for at least 1us and set the DAT\_IO high.

---
Tags: arduino-uno, arduino-ide, spi
---


title: Arduino + Codeblocks C++

text:
# Question
Title: Arduino + Codeblocks C++
I'm writing the code for my Arduino board using Code::Blocks editor. When I create a new project, there is **AVR Project** and **Arduino Project** under Projects category. Which one do I select?

# Answer
> 0 votes
You can select, what you want. If you want to build an Arduino Project, you should choose "Arduino Project". If you don't want to use the Arduino Framework, you can choose "AVR Project".

---
Tags: programming, c++, c
---


title: why is "if" slow?

text:
# Question
Title: why is "if" slow?
I am new to the Arduino world and I hope I can find a solution here. The code below functionally works ok. The problem I have is, at line 45 I've inserted an `if` statement to change `dac_value`. It is very slow while serial and all that is outside `if` works fast/fine... What would be a solution to make it fast? Tried `if` \- `else if` and also `while`... result is the same. Hope someone can help. Thank you.

```
{
#include <Arduino.h>
#include <Wire.h>
// #include <LiquidCrystal_I2C.h>
#define MCP4725 0x61
#define MCP4725B 0x60
unsigned int val;
byte buffer[3];
byte buff[3];

int ClockPinV = PB1;
int ClockPinA = PA6;
const int currsensPin = PA3;
const int voltsensPin = PA2;

void setup()
{
  Serial.begin(115200);
  pinMode(currsensPin , INPUT_ANALOG);
  pinMode(voltsensPin , INPUT_ANALOG);
  pinMode(ClockPinV , INPUT);
  pinMode(ClockPinA , INPUT);
  Wire.begin();
}

int val0 = 1024;
int val1 = 4096;
volatile int dac_value = 0;

void loop()
{
  analogReadResolution(12);

  volatile int svolt = analogRead(ClockPinV);
  volatile int scurr = analogRead(ClockPinA);
  volatile int set_voltage = (3.3/4096)*svolt;
  volatile int set_curr =  (3.3/4096)*scurr;
  volatile int securr = analogRead(currsensPin);
  volatile int real_curr = (3.3/4096)*securr;
  volatile int sevolt= analogRead(voltsensPin);
  volatile int real_output2 = (3.3/4096)*sevolt;

if(real_curr < set_curr){
    if(set_voltage > real_output2)
    {
      dac_value = dac_value + 1;
    }
    if(set_voltage < real_output2)
    {
      dac_value = dac_value - 1;
    }
  }
  else if(real_curr > set_curr)
  {
    dac_value --;
  }

  dac_value = constrain(dac_value, 0, 2673);
  buffer[0] = 0b01000000; //control byte
  buffer[1] = dac_value >> 4; //MSB 11-4 shift right 4 places
  buffer[2] = dac_value << 4; //LSB 3-0 shift left 4 places

  Wire.beginTransmission(MCP4725); //address device
  Wire.write(buffer[0]); //pointer
  Wire.write(buffer[1]); //8 MSB
  Wire.write(buffer[2]); //4 LSB
  Wire.endTransmission();

  // val1 = constrain(val1, 0, 2673);
  buff[0] = 0b01000000; //control byte
  buff[1] = svolt >> 4; //MSB 11-4 shift right 4 places
  buff[2] = svolt << 4; //LSB 3-0 shift left 4 places

  Wire.beginTransmission(MCP4725B); //address device
  Wire.write(buff[0]); //pointer
  Wire.write(buff[1]); //8 MSB
  Wire.write(buff[2]); //4 LSB
  Wire.endTransmission();

  Serial.println("=============================");
  Serial.println("=============================");
  Serial.println("========= Volt Test =========");
  Serial.println("test: " + String(set_voltage));
  Serial.println("      " + String(real_output2));
  Serial.println("======== Current Test =======");
  Serial.println("test: " + String(set_curr));
  Serial.println("      " + String(real_curr));
  Serial.println("=============================");
  Serial.println("=============================");
}
}

```

# Answer
> 4 votes
The `if` statements (plural) you posted on GitHub are a lot different to the one you posted above. They contain a lot of of `print` commands to the LCD, so I think this is what is slowing your code down. It's a fair effort at nicely formatting the output on the display, but is rather convoluted.

Here is a simplified version which writes to the LCD as little as possible (2 cursor moves and 2 prints). The formatting of the string is done in Arduino memory before sending it out to the LCD as one complete string.

I couldn't understand your variable names, so I've renamed them.

# setup()

I moved the `analogReadResolution(12)` from `loop()` to `setup()` for a slight performance gain.

```
void setup()
{
  pinMode(currsensPin , INPUT_ANALOG);
  pinMode(voltsensPin , INPUT_ANALOG);
  pinMode(voltPin, INPUT_ANALOG);
  pinMode(currPin, INPUT_ANALOG);
  Wire.begin();
  lcd0.begin(20, 4);
  lcd0.backlight();

  analogReadResolution(12);  // Moved from loop(). Only need to call it once.

  Serial.begin(115200);
}

```

# loop()

I've grouped the analogue reads together to give a smaller sampling window. Since it's for a control loop, these values should ideally be sampled at exactly the same time and synchronised to a clock (e.g. in hardware).

```
float real_current_offset = 0;

void loop()
{
  //
  // Obtain data samples as close together as possible with no interrupts.
  //
  cli();  // Disable interrupts.
  int svolt = analogRead(voltPin);
  int scurr = analogRead(currPin);
  int raw_voltage = analogRead(voltsensPin);
  int raw_current = analogRead(currsensPin);
  sei();  // Enable interrupts.

  // Calculate set voltage and current.
  float set_voltage = (3.3 / 4096) * svolt;
  float set_current =  (3.3 / 4096) * scurr;

  // Calculate real voltage and current.
  float real_voltage = (3.3 / 4096) * raw_voltage;
  float real_current = raw_current * (3.3 / 4096) - real_current_offset;
  float real_current_ma = real_current * 1000.0;

  int dac_value = dac_value
              + (real_current <= set_current) * (set_voltage > real_voltage)
              - (real_current < set_current) * (set_voltage < real_voltage)
              - (real_current > set_current);

  buffer[0] = 0b01000000;
  buffer[1] = dac_value >> 4;
  buffer[2] = dac_value << 4;
  Wire.beginTransmission(MCP4725);
  Wire.write(buffer[0]);
  Wire.write(buffer[1]);
  Wire.write(buffer[2]);
  Wire.endTransmission();

  DisplayDataOnLcd(set_voltage, set_current, real_voltage, real_current);
}

```

# DisplayDataOnLcd()

I created a new function for displaying the data on the LCD. It's good practice to break the code down into smaller functional blocks.

```
void DisplayDataOnLcd(const int set_voltage, const int set_current, const int real_voltage, const int real_current)
{
  Serial.println("\nLCD Data Display");

  // Define the formats for printing to the LCD.
  const char *data_format_set  = "Set : %s V %s mA";
  const char *data_format_real = "Real: %s V %s mA";
  char voltage_str[10];
  char current_str[10];
  char data_str[30];

  // Format the set voltage and current, and display on the LCD.
  dtostrf(set_voltage, 6, 3, voltage_str);
  dtostrf(set_current, 6, 3, current_str);
  sprintf(data_str, data_format_set, voltage_str, current_str);
  lcd0.setCursor(0, 0);
  lcd0.println(data_str);
  Serial.println(data_str);

  // Format the real voltage and current, and display on the LCD.
  dtostrf(real_voltage, 6, 3, voltage_str);
  dtostrf(real_current, 6, 3, current_str);
  sprintf(data_str, data_format_real, voltage_str, current_str);
  lcd0.setCursor(0, 1);
  lcd0.println(data_str);
  Serial.println(data_str);
}

```

---
Tags: programming, c++
---


# Question
Title: My motor driver gets stuck in either high or low with a certain speed super randomly. Motor output stops going based on accelerometer input
Running a DC motor(6.5A max input), motor driver (MD10C 7Amp peak output), and arduino Mega. Basically, I am creating a stabilized object based on the accelerometer's input. It works great but all of a sudden, very randomly, it glitches and gets stuck in whatever mode it was in last, so if it was motor A HIGH and motor B LOW at speed 200, itll just do that and I have to unplug it, put in a blank code, then my code again, then start it, itll work great then do it all over again. The time it takes for it to glitch out is random, I can't seem to find any patterns to it. here is my code

```
//Code for accelerometer controlling an encoded DC
#include <Encoder.h>
#include <Wire.h>
#include <MPU6050.h>
#include <QueueArray.h>

//Class to read the encoder
Encoder myEnc(19,18);

//I2C address of the MPU-6050
const int MPU_addr=0x68;

const uint16_t t1_load = 0;

// Timer1 compare value:
// Clock frequency / Prescaler / Required frequency = Compare value
// 16 MHz          / 64        / 200 Hz              = 1250
const uint16_t t1_comp = 1250;

// Buffered data for sending/receiving to/from the ISR
volatile bool isr_flag = false;  //Used to flag when the ISR when triggered
volatile unsigned long isr_time = 0;  //Input updated by ISR
volatile byte isr_motor_direction; //Output calculated and updated in loop()
volatile byte isr_motor_speed = 0; // Output calculated and updated in loop()

//initializing the MPU6050 (accel/gyro input)
MPU6050 sensor;

//accerleromter in the y direction
int16_t AcY;
//not using
int16_t AcX, AcZ, GyX, GyY, GyZ, Tmp;

//new varible for mapping the accelerometer to degrees
int yAng;

//Variables to create PID method
int currentTheta;
float error;
int dt = 5;
long integral=0;
long deriv;
int previousError;

//accel on light, always want it at 0
int setpoint = 0;

//change speeds of the motor
#define MOTOR_SPEED_PIN    3
//change direction of the motor
#define MOTOR_DIRECTION_PIN   2
#define MOTOR_DIRECTION_CW    LOW
#define MOTOR_DIRECTION_CCW   HIGH

void setup()
{
  //Disable global interrupt
  cli();

  // Reset Timer1 Control Reg A
  TCCR1A = 0;

  // Set CTC mode
  TCCR1B &= ~(1 << WGM13);
  TCCR1B |= (1 << WGM12);

  // Set to prescalar of 64
  TCCR1B &= ~(1 << CS12);
  TCCR1B |= (1 << CS11);
  TCCR1B |= (1 << CS10);

  // Reset Timer1 and set compare value
  TCNT1 = t1_load;
  OCR1A = t1_comp;

  // Enable Timer1 compare interrupt
  TIMSK1 = (1 << OCIE1A);

  // Enable global interrupt
  sei();

  Wire.begin();
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x6B);
  Wire.write(0);
  Wire.endTransmission(true);

  Serial.begin(9600);

  pinMode(MOTOR_SPEED_PIN, OUTPUT);
  pinMode(MOTOR_DIRECTION_PIN, OUTPUT);

  sensor.initialize();
}

void loop()
{
    //Begin critical section
    //

    cli();
    bool flag = isr_flag; //Copy the ISR flag
    isr_flag = false; //Reset the ISR flag
    sei();

    //
    //End critical section

    if (flag == true)
    {
      DebugMsgTime("PID algorithm begin");

      //Begin critical section
      //

      //Getting a copy of the data that has been modified by the ISR
      cli();
      unsigned long time = isr_time;
      sei();

      //
      //End critical section

      static unsigned long previous_time = 0;
      previous_time = time;

      //Wire reading

      Wire.beginTransmission(MPU_addr);
      Wire.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)
      Wire.endTransmission(false);
      Wire.requestFrom(MPU_addr,14,true);

      //reading each of the 6 axis's of the MPU6050 and the temp
      AcX=Wire.read()<<8|Wire.read();  // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
      //Only using AcY
      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)
      Tmp=Wire.read()<<8|Wire.read();  // 0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_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();

      //mapping AcY to yAng from accel units to degrees
      yAng = map(AcY, -17000, 17000, -90, 90);

      //Calculate motor parameters locally
      long pos = PID(yAng);
      byte motor_direction = pos > 0 ? MOTOR_DIRECTION_CW : MOTOR_DIRECTION_CCW //make sure that this is correct
      pos = abs(pos);
      pos = constrain(pos, 0, 100);
      byte motor_speed = map(pos, 0, 100, 0, 200);

      //Begin Critical Section
      //

      // Update the ISR data ready for output at the next interrupt.
      // This keeps the outputs locked to each other and synchronised to the interrupt.
      cli();
      isr_motor_direction = motor_direction;
      isr_motor_speed = motor_speed;
      sei();

      //
      //End Critical Section

      DebugMsgTime("PID algorithm end");
    }
}

ISR(TIMER1_COMPA_vect)
{
  //Output
  digitalWrite(MOTOR_DIRECTION_PIN, isr_motor_direction);
  analogWrite(MOTOR_SPEED_PIN, isr_motor_speed);

  //Input
  isr_time = micros();
  isr_flag = true;
}

//PID loop to find error between setpoint and currentTheta
long PID(int currentTheta)
{
    error = setpoint - currentTheta;
    integral = integral + error*dt;
    deriv = (error-previousError)/dt;
    long output = 1.9 * error; + .8 * integral + 40 * deriv; //2.8,.7,70 //1.3,.8,40
    previousError = error;
    return output;
}

void DebugMsgTime(const char *msg)
{
  static unsigned long previous_time = 0;
  unsigned long time = micros();
  unsigned long delta_time = time - previous_time;
  previous_time = time;

  Serial.println(msg);
  Serial.println(time);
  Serial.println(delta_time);
}

```

# Answer
What happens if the `while` condition fails? i.e. if `millis() - time` is greater than or equal to 20. Is this what you intended? If there's too much other stuff in the `while` loop, it may quit it **and never re-enter it**.

# loop()

I've added a call to a function that prints debug information.

```
unsigned long time = 0;

void loop()
{
  DebugMsgTime("loop() begin");

  while (millis() - time < 20)
  {
    DebugMsgTime("while begin");

    time = millis();

    //delay(10);  // Short delay OK.
    delay(20);  // Long delay causes while loop to quit.

    DebugMsgTime("while end");
  }
  DebugMsgTime("loop() end");
}

```

# DebugMsgTime()

This function prints a message along with the current time and the delta time since it was last called.

```
void DebugMsgTime(const char *msg)
{
  static unsigned long previous_time = 0;
  unsigned long time = millis();
  unsigned long delta_time = time - previous_time;
  previous_time = time;

  Serial.println(msg);
  Serial.println(time);
  Serial.println(delta_time);
}

```

# Debug Output

> It works great but all of a sudden, very randomly, it glitches and gets stuck in whatever mode it was in last

```
Basic Encoder Test:
loop() begin
0
0
while begin  // It works great...
1
1
while end
2
1
while begin
12
10
while end
34
22           // but all of a sudden, very randomly, it glitches...
loop() end   // and gets stuck in whatever mode it was in last
54
20
loop() begin
74
20
loop() end
97
23
loop() begin
118
21
loop() end

```

As you can see, using this `while` loop is a very inaccurate way to generate regular sampling times.

# loop() FIX

As @FerryBig pointed out in the comments, you need to change the time comparison `<` at the start of the loop. You also don't need the `while` loop because `loop()` is already called cyclically. Instead, put the time comparison in an `if` statement, something like this which gives you a rough 20 ms:

```
void loop()
{
  static unsigned long previous_time = 0;
  unsigned long time = millis();
  unsigned long delta_time = time - previous_time;

  if (delta_time >= 20)
  {
    previous_time = time;

    // Do PID algorithm.
  }
}

```

However, for a PID controller you may need more accuracy.

# Timer Interrupt

A better method would be to use a timer interrupt to call an Interrupt Service Routine (ISR) at regular intervals. This ISR would do two simple things in this order:

1. Output: `digitalWrite(motor_direction);` and `analogWrite(3, mtr2);`
2. Input: set a flag that indicates that the gyro Wire needs reading.

Then, when the flag is set, the main `loop()` would read the gyro Wire, and calculate `motor_direction` and `mtr2` in readiness for the next interrupt.

```
const uint16_t t1_load = 0;

// Timer1 compare value:
// Clock frequency / Prescaler / Required frequency = Compare value
// 16 MHz          / 64        / 10 Hz              = 25000
const uint16_t t1_comp = 25000;

volatile bool isr_flag = false;       // Used to flag when the ISR has updated the data.
volatile unsigned long isr_time = 0;  // The data.

void setup()
{
  // Disable global interrupt
  cli();

  // Reset Timer1 Control Reg A
  TCCR1A = 0;

  // Set CTC mode
  TCCR1B &= ~(1 << WGM13);
  TCCR1B |= (1 << WGM12);

  // Set to prescalar of 64
  TCCR1B &= ~(1 << CS12);
  TCCR1B |= (1 << CS11);
  TCCR1B |= (1 << CS10);

  // Reset Timer1 and set compare value
  TCNT1 = t1_load;
  OCR1A = t1_comp;

  // Enable Timer1 compare interrupt
  TIMSK1 = (1 << OCIE1A);

  // Enable global interrupt
  sei();

  Serial.begin(9600);
}

void loop()
{
  //
  // BEGIN CRITICAL SECTION (Atomic)
  //

  cli();
  bool flag = isr_flag;  // Copy the ISR flag.
  isr_flag = false;      // Reset the ISR flag.
  sei();

  //
  // END CRITICAL SECTION
  //

  Serial.println(flag);

  if (flag == true)
  {
    //
    // BEGIN CRITICAL SECTION (Atomic)
    //

    // Get a copy of the data that has been modified by the ISR.
    cli();
    unsigned long time = isr_time;
    sei();

    //
    // END CRITICAL SECTION
    //

    static unsigned long previous_time = 0;
    Serial.println(time - previous_time);
    previous_time = time;
  }

  delay(25);
}

ISR(TIMER1_COMPA_vect)
{
  //TCNT1 = t1_load;  // No need to reload here because it auto reloads.
  isr_time = micros();
  isr_flag = true;  // Indicate that new data is available.
}

```

# PID Controller

This is the full implementation of the PID controller. It should give you a solid foundation to develop the PID algorithm for your motor, and to filter the gyro inputs.

```
//Code for accelerometer controlling an encoded DC
#include <Encoder.h>
#include <Wire.h>
#include <MPU6050.h>
#include <QueueArray.h>

//Class to read the encoder
Encoder myEnc(19, 18);

//I2C address of the MPU-6050 idk if i need
const int MPU_addr = 0x68;

const uint16_t t1_load = 0;

// Timer1 compare value:
// Clock frequency / Prescaler / Required frequency = Compare value
// 16 MHz          / 64        / 10 Hz              = 25000
//const uint16_t t1_comp = 25000;

// If the PID algorithm takes less than 5 ms, it's possible to run Timer1 at a maximum of about 200 Hz.
// 16 MHz          / 64        / 200 Hz             = 1250
const uint16_t t1_comp = 1250;

// Buffered data for sending/receiving to/from the ISR.
volatile bool          isr_flag = false;            // Used to flag when the ISR has triggered.
volatile unsigned long isr_time = 0;                // Input updated by ISR.
volatile byte          isr_motor_direction = LOW;   // Output calculated and updated in loop().
volatile byte          isr_motor_speed = 0;         // Output calculated and updated in loop().

//initializing the MPU6050 (accel/gyro input)
MPU6050 sensor;

//accerleromter in the y direction
int16_t AcY;
//not using
int16_t AcX, AcZ, GyX, GyY, GyZ, Tmp;

//new varible for mapping the accelerometer to degrees
int yAng;

//Variables to create PID method
int currentTheta;
float error;
int dt = 5;
long integral = 0;
long deriv;
int previousError;

//accel on light, always want it at 0
int setpoint = 0;

//this is the enable pin (PWM) to run speeds to the motor
#define MOTOR_SPEED_PIN         3

//change direction of the motor
// TODO: Check whether LOW and HIGH are correct.
#define MOTOR_DIRECTION_PIN     2
#define MOTOR_DIRECTION_CW      LOW
#define MOTOR_DIRECTION_CCW     HIGH

void setup()
{
  // Disable global interrupt.
  cli();

  // Reset Timer1 Control Reg A
  TCCR1A = 0;

  // Set CTC mode
  TCCR1B &= ~(1 << WGM13);
  TCCR1B |= (1 << WGM12);

  // Set to prescalar of 64
  TCCR1B &= ~(1 << CS12);
  TCCR1B |= (1 << CS11);
  TCCR1B |= (1 << CS10);

  // Reset Timer1 and set compare value
  TCNT1 = t1_load;
  OCR1A = t1_comp;

  // Enable Timer1 compare interrupt
  TIMSK1 = (1 << OCIE1A);

  // Enable global interrupt
  sei();

  Wire.begin();
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x6B);
  Wire.write(0);
  Wire.endTransmission(true);

  Serial.begin(9600);
  Serial.println("Basic Encoder Test:");

  //pinMode(MOTOR_SPEED_PIN, OUTPUT);  // Not needed for analogWrite().
  pinMode(MOTOR_DIRECTION_PIN, OUTPUT);

  sensor.initialize();
}

void loop()
{
  //
  // BEGIN CRITICAL SECTION (Atomic)
  //

  cli();
  bool flag = isr_flag;  // Copy the ISR flag.
  isr_flag = false;      // Reset the ISR flag.
  sei();

  //
  // END CRITICAL SECTION
  //

  //Serial.println(flag);

  if (flag == true)
  {
    DebugMsgTime("PID algorithm begin");

    //
    // BEGIN CRITICAL SECTION (Atomic)
    //

    // Get a copy of the data that has been modified by the ISR.
    cli();
    unsigned long time = isr_time;
    sei();

    //
    // END CRITICAL SECTION
    //

    static unsigned long previous_time = 0;
    //Serial.println(time);
    //Serial.println(time - previous_time);
    previous_time = time;

    //
    // Read gyro Wire.
    //

    Wire.beginTransmission(MPU_addr);
    Wire.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)
    Wire.endTransmission(false);
    Wire.requestFrom(MPU_addr, 14, true);

    //reading each of the 6 axis's of the MPU6050 and the temp
    AcX = Wire.read() << 8 | Wire.read(); // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
    //Only using AcY
    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)
    Tmp = Wire.read() << 8 | Wire.read(); // 0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_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();

    //mapping AcY to yAng from accel units to degrees
    yAng = map(AcY, -17000, 17000, -90, 90);

    //
    // Calculate motor parameters locally.
    //

    long pos = PID(yAng);
    byte motor_direction = pos > 0 ? MOTOR_DIRECTION_CW : MOTOR_DIRECTION_CCW;  // TODO: Check whether defines are correct.
    pos = abs(pos);
    pos = constrain(pos, 0, 100);
    byte motor_speed = map(pos, 0, 100, 0, 200);

    //
    // BEGIN CRITICAL SECTION (Atomic)
    //

    // Update the ISR data ready for output at the next interrupt.
    // This keeps the outputs locked to each other and synchronised to the interrupt.
    cli();
    isr_motor_direction = motor_direction;
    isr_motor_speed = motor_speed;
    sei();

    //
    // END CRITICAL SECTION
    //

    DebugMsgTime("PID algorithm end");
  }

  //delay(1);
}

ISR(TIMER1_COMPA_vect)
{
  // Output.
  digitalWrite(MOTOR_DIRECTION_PIN, isr_motor_direction);
  analogWrite(MOTOR_SPEED_PIN, isr_motor_speed);

  // Input.
  isr_time = micros();
  isr_flag = true;
}

//PID loop to find error between setpoint and currentTheta
long PID(int currentTheta)
{
  error = setpoint - currentTheta;
  integral = integral + error * dt;
  deriv = (error - previousError) / dt;
  long output = 1.9 * error + .8 * integral + 40 * deriv; //2.8,.7,70 //1.3,.8,40
  previousError = error;
  return output;
}

void DebugMsgTime(const char *msg)
{
  static unsigned long previous_time = 0;
  unsigned long time = micros();
  unsigned long delta_time = time - previous_time;
  previous_time = time;

  Serial.println(msg);
  Serial.println(time);
  Serial.println(delta_time);
}

```

And I think there might be a typo in your PID controller:

```
long PID(int currentTheta)
{
    ...
    long output = 1.9*error; + .8*integral + 40*deriv;
                           |
                         typo?

```

This is equivalent to:

```
    long output = 1.9*error;

```

Which is not a PID controller.
> 1 votes

---
Tags: arduino-mega, programming, motor, accelerometer
---


# Question
Title: Converting from Float to Int yielding weird results. What am I doing wrong?
So I am trying to take GPS data with a Neo 6M gpsmodule (that is what is covered up by the square for privacy sake) and process it by adding/multiplying to get large integers representing the GPS data. This is using Arduino nano. When I try and convert the float numbers to integers, it gives me totally different numbers. 1242895 turns into -2289, and 611194 turns into 21370. I have tried so many things, but am stumped as to what is going on. Is it related to pointing? It's been awhile since I learned about pointers in my C++ class. X and Y are initialized as int global variables.

# Answer
On an Arduino board with the 328 processor, an INT is stored as a 2 byte value, so the max number is 32,767.

You want to use a LONG which is a 4 byte number which has a max of 2,147,483,647.

When the variable you are using is not big enough, the number rolls over, which is why you end up getting a negative number.
> 6 votes

---
Tags: arduino-nano, float, convert
---


# Question
Title: Where can I find SerialMonitor.java in installed Arduino IDE 1.8.13?
I have found the git source for SerialMonitor (`Arduino/app/src/processing/app/*`) but unable to find it in the installed Arduino IDE. I am using Ubuntu 20.04 64-bit.

I want to make changes to it, not so much a terminal emulator but just perform simple ASCII control characters like backspace (0x08). Some advice on replacing it would be appreciated too; I guess it involves `jar` files (I am not a java developer).

I have read elsewhere about (and used) various other terminal-type programs, but of course they stop the IDE from uploading sketches. So not much good for development.

Or if anyone knows of an already-improved Serial Monitor, and how to install it for the IDE, then that could be perfect.

# Answer
After some searching, I found that Building Arduino - Steps for First Time Setup was good. It was tricky to find; most searches for 'Build Arduino' assume it's a project with an Arduino, rather than the IDE.

By building this way, I could change the source, then inside the `build` folder run `ant run`. So, no need to actually know where it goes.

I had a problem with it grumbling about `Incorrect IDE installation folder: Your copy of the IDE is installed in a subfolder of your sketchbook. Please move the IDE to another folder.` which would have been more useful if it had said WHAT settings needed changing.

It turns out that `preferences.txt` had a conflict with settings `sketchbook.path` and `runtime.ide.path`. I changed `sketchbook.path`. All is now good.
> 0 votes

# Answer
You can't just "find and replace" that file.

Java isn't distributed as source code. It's compiled "bytecode" that isn't modifiable by a human.

You would need to download *all* the source code, make your changes to it, and then recompile it.

Or, simpler: just use a more capable serial terminal program, such as "Putty" or "TeraTerm" in Windows, or "Minicom" or "Screen" on Linux. I have no idea what is available for OS X.
> 0 votes

---
Tags: serial, ubuntu, installation
---


# Question
Title: Where do I find the enclosures for an Arduino and a bunch of sensors?
I recently started playing with Arduino in order to do several projects, including:

* A system which will measure some characteristics of the indoor air and could alert me if something goes wrong (for instance if the percentage of CH4 goes beyond a threshold).
* A system I can bring with me on a walk which will measure the pollution and other characteristics of the air outdoors.

While the quantity and the diversity of the sensors for such projects, as well as the ease of use is mind blowing, I'm blocked at one aspect: the casing. Both of the projects require to put the electronics within a plastic case with:

* Enough space for not only Arduino, but also the sensors. Some, such as MQ2/MQ5, can be quite large.
* Holes for air flow, which are large enough to let small particles, but small enough to keep insects and large dust out of the electronics.
* A hole for an USB cable and possibly a hole for the LED.

Unfortunately, the popular sites selling Arduino-related stuff have practically nothing when it comes to the cases. In most cases, the choice is limited to (1) the enclosures for Arduino itself (or other boards), with no holes in them and (2) the multicolored modular systems which look like LEGO bricks.

Outside Arduino-related sites, the only idea I have is to buy somewhere an old smoke detector, throw away the electronics and put Arduino and the sensors inside. For now, most smoke detectors I've seen seem too small for the task, and have to be modified in order to accommodate the USB cable.

Am I missing something? How other people do when they need an enclosure which fits Arduino and sensors and doesn't look geeky?

# Answer
I think your problem is that you are looking specifically for Arduino enclosures. Such a search tends to lead you to boxes for just an Arduino and nothing else - maybe with the headers poking out the top.

Instead, you should be looking more generically. There are thousands and thousands of "project enclosures" from many manufacturers (Hammond is a big name in these).

You take a generic project box of the right size and shape for what you want to create and in a material suitable for your needs, and cut / grind / drill / glue it to be what you want.

Most electronics suppliers will have an "Enclosures and Housings" section on their website. Have a browse through your favourite.

As far as air vents go, one good trick I have used is to simply drill holes (with a steady hand so you get them lined up nice and straight) and glue some fine mesh on the inside. One good source of fine mesh is to go to your local smoking supplies reseller (tobacconist) and buy some "pipe meshes" (the flat ones, not bowl shaped ones) - also available from low-cost online resellers of any old junk (eBay, etc), which look like this:

(Also available in brass). They typically come in different mesh sizes to suit your needs.
> 4 votes

# Answer
for many projects i use distribution box like this one:
> 3 votes

# Answer
I just came across your question, and I think this may be useful if you're still interested in project enclosures. I've designed and created stackable, modular and extensible enclosures for Arduino (fits Uno and Mega footprints), Raspberry Pi (three different versions, for A+, B+/4B and Zero (can accommodate up to 4 Zeros), and Breadboard and breadboard-friendly MCUs. All of these enclosures have 4"x2.4"x1.2"(h) space on the inside, enough for one or two shields or hats. They also come with replaceable sides/tops that can allow you to add sensors and peripherals, like a Pi Camera, High Quality Camera, Tripod mount, Ultrasonic sensors (HC-SR04), momentary push button switches, RS232 ports and more. The enclosure is made of acrylic with 6 separate flat pieces, so that means you can also hack it to easily add holes and mounts to customize it yourself.

You can find more details on https://www.protostax.com/

Hope you find it helpful! Let me know if you have any questions. Cheers, and Happy Making! Sridhar Rajagopal
> 1 votes

# Answer
Look into "Really Useful Boxes", found online, or at stores like Office Depot. Lot of sizes available, pretty easy to mount cards & connectors into. I have several projects lower down on this page where you can see how I used them.
> 0 votes

---
Tags: enclosure
---


# Question
Title: For Loop function to iterate through outputs after interrupt
I would like help to continuously loop over my output pins after each sleep cycle. I am trying to increment through each output pin during each successive interrupt. Introducing this myIteration function causes immediate incrementing to final output pin and eliminates sleeping.

**EDIT** To clarify a bit and clean up the code, I am having trouble getting the loop to increment over the output pins each time the interrupt is triggered. It stays on the initialized pin value after each interrupt.

The reason I separate the if (state=HIGH) into two consecutive statements is because when I do not the debug LED remains on.

```
#include <LowPower.h>

const byte interrupt_pin = 2;                             // declare interrupt pin for PIR trigger
int musicPins[] = {3, 4, 5, 6, 7, 8, 9, 10, 11};          // Initialize pins that play music in array, elements from 0 to 8
volatile byte state = LOW;                                // trigger threshold starts low
int pinCount = 9;
int previous = 0;

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);                           // use builtin LED for debug
  pinMode(interrupt_pin, INPUT);                          // set interrupt pin as input

    for (int thisPin = 0; thisPin < pinCount; thisPin++) {      // set all music pins as High to start with no music during sensor initialization
    digitalWrite(musicPins[thisPin], HIGH);
    }
    for (int thisPin = 0; thisPin < pinCount; thisPin++) {      // set all music pins as outputs
    pinMode(musicPins[thisPin], OUTPUT);
    }

  delay(5000);                                            // wait so sensor can initialize
}

void loop() {

  attachInterrupt(digitalPinToInterrupt(interrupt_pin),interrupt_routine,RISING); // must attach each loop
  LowPower.powerDown(SLEEP_FOREVER,ADC_OFF,BOD_OFF);      // MCU sleep until interrupt
  detachInterrupt(digitalPinToInterrupt(interrupt_pin));  // remove interrupt

  if (previous==10){                                      // when variable gets to 10 reset to zero
    previous=0;
  }

  if (state==HIGH){                                       // PIR senses motion, sends high signal
    digitalWrite(LED_BUILTIN,HIGH);                       // debug LED turns on
    myOnIteration();                                      // musicPin number x turns on
    delay(100);                                           // wait to stabilize
    digitalWrite(LED_BUILTIN,LOW);                        // debug LED turns off
  }
  if (state==HIGH){                                       // separate statements to guarantee next steps happen
    myOffIteration();                                     // musicPin number x turns off
    LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);       // sleep for 8s after musicPin plays

  }

  previous++;                                             // increment before attaching next interrupt

}

////////Functions//////////
void interrupt_routine(){
  state = HIGH;
}

void myOnIteration() {                                    // cycle through output pins turning on once per interrupt
for (int count = previous; count < pinCount; count++) {
        digitalWrite(musicPins[count], LOW);
      }
}

void myOffIteration() {                                   // cycle through output pins turning off once per interrupt
for (int count = previous; count < pinCount; count++) {
        digitalWrite(musicPins[count], HIGH);
      }
}

```

# Answer
> 1 votes
Original code is updated with final version. A motion sensing interrupt iterates over multiple voice playback output pins and sleeps at low power for rest of time.

---
Tags: interrupt, loop
---


# Question
Title: Problem with programming digispark ATtiny85 board with Arduino IDE
I have bought a Digispark ATtiny85 board to learn about that microcontroller. So I tried using internal register names in the code rather than using Arduino in built functions. I can get the board to work when comes just input and output operations. For example the below code works and I can get the on board LED to turn ON and OFF

```
#include<avr/io.h>
void setup()
{
  DDRB |=(1 << PB1);  //set PB1 as output
}
void loop() {
 PORTB |= (1 << PB1);    // Turning ON LED connected to PB1
 delay(1000);            //Using Arduino IDE inbuilt delay function to generate delay of 1 second
 PORTB &= ~(1 << PB1);   //Turning the LED off
 delay(1000);

```

}

I have tried using Timer0 of ATtiny85 module to generate time delay of one second. But unfortunately I couldn't get it to work.

```
#include<avr/io.h>
#define F_CPU 16500000UL
#include<util/delay.h>

void timer_config()
{
 DDRB =0b00000010; // set PB1 as output
 GTCCR|= (1<<TSM);      ///Halt the timer for configuration
 TCCR0A=0x00;             //Normal mode
 TCCR0B=0x00;
 TCCR0B |= (1<<CS00)|(1<<CS02);   //prescaling with 1024
 TCNT0=0;
 GTCCR&=~(1<<TSM); //Start the timer
}

void tmdel()
{
 int i=0;
 while(i<=6)
 {
  while((TIFR & (1 << TOV0) )==0);        //Waiting for 0-255 and flag to raise
  TIFR|=(1<<TOV0);      //Clear the flag
  i=i++;                          //increment by one
 }
}

int main()
{
 timer_config();
 while(1)
 {
  PORTB|=(1<<PB1);     //PortB1 high
  tmdel();                         //Delay of 1 second
  PORTB&=~(1<<PB1);     //PORTB1 low
  tmdel();
 }
}

```

I have used the overflow flag to identify TCNT0 register status. I have uploaded the above code but the LED isn't responding as anticipated.

When searching the internet I have got few suggestions that this might be because Arduino IDE uses timer registers for delay function. When user attempts to access timer registers it might not work as intended.

But am not sure about the validity of above opinion. Can anyone help me with it? Since am learning this controller, practicing core programming is quite important. If I cannot program ATtiny85 using Arduino IDE this way, can someone suggest a way or alternate hardware setup to program ATtiny85 and access its registers without a problem.

# Answer
> 6 votes
> ```
>  i=i++;                          //increment by one
>
> ```

The result of the above statement is **not defined**. That is, it is not necessarily "i + 1".

See:

Instead use:

```
i++;

```

Or:

```
i = i + 1;

```

A note about "undefined behavior":

http://en.wikipedia.org/wiki/Undefined\_behavior

> When an instance of undefined behavior occurs, so far as the language specification is concerned anything could happen, maybe nothing at all.

---
Tags: arduino-ide, timers, avr, attiny85, digispark
---


# Question
Title: Maintain constant PWM voltage with changing Vcc
I am making an arduino project with a single lithium ion battery, and want to be able to maintain a constant PWM voltage, even when the battery goes from 4.2-3.2v. I have been able to read the Vcc using the internal 1.1v reference, so I am wondering if I can make some sort of feedback system to increase the duty cycle when the battery discharges, in order to keep the same average voltage on the PWM. I want to be able to make it 3.2v constant, which should be attainable on Vcc from 4.2-3.2, with 100% duty cycle when the battery is at 3.2v.

# Answer
Simple: `duty = (3.2 / vcc) * 255;`
> 1 votes

---
Tags: pwm, battery, project
---


# Question
Title: Error "cstddef: No such file or directory" on use AzureIoTHub
Good Morning I'm trying to integrate with Azure IoT with Arduino Mega 2560. I imported the AzureIoTHub and AzureIoTUtility lib.

I just created this part of the code

```
 #include <AzureIoTHub.h>

void setup() {
  // put your setup code here, to run once:

}

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

}

```

however, when I compile, I get the following error message.

> In file included from C:\Users\MercurioNote\Documents\Arduino\libraries\AzureIoTUtility\src/azure\_c\_shared\_utility/platform.h:7:0, from C:\Users\MercurioNote\Documents\Arduino\libraries\AzureIoTUtility\src/AzureIoTUtility.h:7, from C:\Users\MercurioNote\Documents\Arduino\libraries\AzureIoTHub\src/AzureIoTHub.h:7, from D:\Documents\Dev\Pocos\Arduino\ArduinoSolution\ArduinoSolution.ino\WiFiPoco\RoboCore\azureHub\azureHub.ino:3: C:\Users\MercurioNote\Documents\Arduino\libraries\AzureIoTUtility\src/azure\_c\_shared\_utility/strings.h:8:10: fatal error: cstddef: No such file or directory #include

I imported ArduinoStl and the problem continued.

what am i doing wrong in this case?

thanks

# Answer
Azure IoT is only supported on ESP8266 and ESP32. As stated in the README for the library:

> Currently supported hardware:
> 0 votes

---
Tags: arduino-mega, iot
---


# Question
Title: How do I resolve "avrdude: stk500_recv(): programmer is not responding"?
Whenever I try to program my Arduino UNO Rev.3, I'm seeing the following error

```
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 3 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 4 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 5 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 6 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 7 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 8 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0x00

```

When I plug this in, I do see a power light. There are no cables whatsoever connected other than the USB. I have another Arduino UNO which works fine when I upload the sketch (I'm using the basic blink sketch). How do I resolve this? What kind of problem can it be?

# Answer
> 27 votes
After trying numerous suggestions, 2 different boards, 3 different cables on a WinXP and a Win7 machine, I finally got things working by going to "Tools -\> Processors -\> ATmega 328P Old Bootloader"

# Answer
> 4 votes
I had this problem when working with Arduino IDE and XOD running on top of it. What I found; looked like **baud rates were being set differently at different stages in the setup**. I compared Windows 'device settings', arduino IDE settings and XOD settings...and they are not the same and seem to change ? ...hence the 'avrdude:stk500\_\**** errors!

**To demonstrate**

Connect an Arduino board to a PC USB socket.

1. On Windows 7; Control Panel\ System and Security\System\ Device Manager... then double-click on 'Ports (COM & LPT)

You should see FTDI

or

USB-SERIAL CH340(COM7) ... for a chinese serial com chip on the arduino board. Right-click on this and check 'Properties\ Port Settings' and note the 'Bits per second' value : e.g. 57600 ... (write it down !)
2. Open the arduino IDE and click on File\Preferences and tick the option ;'**Show verbose output during: 'upload**'.Then close the 'Preferences' screen.
3. Load a small program that works. e.g. File\Examples\01.Blink
4. In the for your arduino board setup in the Arduino IDE;

Tools\Board ... such as *Arduino Nano*

Tools\Processor ... such as *ATmega328P*

Tools\Port:COM7 for example ... make sure a tick is selected.

Tools\Get Board Info ... will show info from the arduino serial chip (**a good sign your usb cable works!**)
5. On the IDE toolbar select;

* 'Verify' and shortly it should show 'Done Compiling'
    * Click 'Upload' and the *Blink* program should load into the arduino chip.
6. Now here is the interesting observation; The 'verbose message at the bottom of the IDE screen will indicate what '**Overriding Baud Rate : XXXXX'** is being used! Write this number down next to the value you found on the Windows devices setting.
7. Now, if you are a XOD man, leave the arduino IDE running and run XOD.
8. Open the XOD IDE and open (Deploy) say the *01-hello* program and load it into your arduino board.
9. Select'welcome-xod' and select 01-hello program on left-side menu.
10. Select 'Deploy\Upload to Arduino ...'
11. select 'Board model:' and 'Serial port:' ... eg COM7
12. Scroll up in the 'Deployment ' window and there will be another value labeled **'Overriding Baud Rate : e.g.115200'**

I HAVE FOUND THESE BAUD RATE SETTINGS CHANGE INEXPLICABLY !

I hope my observations will throw some light on your problem of erratic uploads.

# Answer
> 1 votes
Have you already tried this? https://stackoverflow.com/a/20735393/5507619

> I had this problem with a Crowduino, running the Arduino IDE on OSX. The solution for me was to switch on verbose output during upload (in the arduino IDE preferences pane).
>
> Then, when uploading, you can see avrdude sending three packets avrdude: Send: 0 \[30\] \[20\] (with corresponding RX flashes on the board) right before the avrdude: ser\_recv(): programmer is not responding error.
>
> The trick is to hit the reset button on the board immediately before these three packets are sent. Then the program will be uploaded successfully.

# Answer
> 1 votes
I had periodically encountered this as well and was stumped after I had tried all the recommended solutions I could find. In my particular case it turned out to be the cable I was using.

# Answer
> 1 votes
I was having the same problem, however I was able to solve as follows,

* rebooting my computer
* or, changing the cable, basically switching between 2 USB cables (may be it just needed to unplug the USB and plug it in again).
* or, resetting the COM port

1. closing the Arduino IDE
    2. disabling the COM port
    3. enabling the COM port
    4. opening the Arduino IDE

# Answer
> 0 votes
For me it was a matter of `-B 10` instead of `-b xxxx`. So:

```
sudo ~/arduino-1.8.12/hardware/tools/avr/bin/avrdude -P /dev/ttyACM0 -B 10 -c arduino -p m328p -C ~/.arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17/etc/avrdude.conf -U eeprom:r:eeprom.hex:r

```

---
Tags: arduino-uno, debugging
---


# Question
Title: Will Setting Interrupt Pin High Damage Bluetooth Module?
I want my HC05 Bluetooth Module to trigger an interrupt when it receives a signal. So I've followed suggestions from the Arduino Forum and connected the Bluetooth TXD pin to the Arduino RX Pin and the Interrupt Pin (2), which I set to high. It is set to detect a `FALLING` voltage, presumably when BT transfers data. When I connected it this way a funny thing happens. I can clearly see that the interrupt is being called because power consumptions goes way up when Android sends a message to BT module, meaning the device wakes up. However the serial port no longer appears to work on the Nano. I think I narrowed down the possible cause to me damaging the board by removing lineage regulator or damaging serial port somehow with the interrupt. Is the way I wired up the interrupt pin as described correct? Your help would really help me narrow down my problem.

```
#include <avr/sleep.h>

#define ledPin 7
#define intPin 3
int state = 0;
int stateData = 0;
int ultraPin = 10;
int trigPin = 11;    // Trigger
int echoPin = 12;    // Echo
long duration, cm;
unsigned char inches;
unsigned long timer;

void setup() {
  pinMode(ultraPin, OUTPUT);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  pinMode(intPin, INPUT);
  digitalWrite(intPin, HIGH);
  attachInterrupt(digitalPinToInterrupt(intPin), interrupt, FALLING);
  digitalWrite(ultraPin, LOW);
  Serial.begin(9600); // Default communication rate of the Bluetooth module
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_enable();
  sleep_cpu();
}

void interrupt(){
  Serial.println("interrupted");
  sleep_disable();
  Serial.write(50);
  delay(500);
  timer = millis();
  digitalWrite(ultraPin, HIGH);
  while (true){
      digitalWrite(trigPin, LOW);
      delayMicroseconds(2);
      digitalWrite(trigPin, HIGH);
      delayMicroseconds(10);
      digitalWrite(trigPin, LOW);
      pinMode(echoPin, INPUT);
      duration = pulseIn(echoPin, HIGH);
      cm = (duration / 2) / 29.1;   // Divide by 29.1 or multiply by 0.0343
      inches = (duration / 2) / 74; // Divide by 74 or multiply by 0.0135
      Serial.write(inches);
      delay(50);
      stateData = Serial.read();
      if (stateData != 49){
        // receipt from android
        unsigned long timeElapse = millis() - timer;
        if (timeElapse > 5000) {
          break; // exit and SLEEP
        }
      }
      else {
          // reset the timer
          timer = millis();
        }
      }
    sleep_enable();
    sleep_cpu();
}

void loop() {

}

```

# Answer
> 1 votes
I'm not sure, if you can rule out the hardware damage (you wrote, that you removed the linear voltage regulator, but didn't explain more there). But with that code you won't get what you want.

I see multiple issues, all boiling down to the same problem: You cannot do that inside of an ISR:

* `delay()` relies on interrupts to happen during its execution. As of my knowledge this leads to `delay()` never ending, blocking your code. Also it is very bad design to have a long running ISR. So much is depending on interrupts to work and when you have something long running, you can just easily do that inside the main code, triggered by an interrupt flag variable.
* `millis()` will not increment during the run of the ISR.
* `delayMicroseconds()` will work, but you still should keep the ISR very short. Reading an ultrasonic sensor is a no-go.
* `Serial.write()` will fill the libraries internal TX buffer, but the actual transmission of the data also relies on interrupts. You won't get your data that way.

Instead of doing all that inside the ISR, you should just let the Arduino wake up, then set a (single byte) flag variable. In your main code you need to check for that flag with an if statement. In that if statement, you are doing all what you need to do and at the end you are resetting the flag and going to sleep again.

---
Tags: arduino-nano, hc-05
---


title: Sketches won't upload to Uno

text:
# Question
Title: Sketches won't upload to Uno
Today I tried to update the sketch on my Arduino Uno, but was unable to due to this error:

```
Sketch uses 1,870 bytes (5%) of program storage space. Maximum is 32,256 bytes.
Global variables use 188 bytes (9%) of dynamic memory, leaving 1,860 bytes for local variables. Maximum is 2,048 bytes.
D:\Users\User\Desktop\arduino-1.6.10\hardware\tools\avr/bin/avrdude -CD:\Users\User\Desktop\arduino-1.6.10\hardware\tools\avr/etc/avrdude.conf -v -patmega328p -carduino -PCOM4 -b115200 -D -Uflash:w:C:\Users\User\AppData\Local\Temp\build2f7b4a32c3810b2d8e42648954faba05.tmp/nes_controller.ino.hex:i
An error occurred while uploading the sketch

```

Nothing will upload to the board now. I tried uploading a simple sketch with empty setup() and loop() functions, I've tried different PCs and gotten the same error, I've swapped USB cables, I've double-checked that I'm using the right COM port, I've disconnected every wire from the Arduino pins - nothing has helped.

The old sketch is still running fine on the Uno. It was uploaded a few days ago using the exact same setup I'm trying right now.

The Arduino IDE doesn't even indicate any errors, everything compiles and looks good until "An error occurred while uploading the sketch"

# Answer
> 3 votes
You can set the verbosity level in the Arduino IDE:

* File menu
* Preferences
* Settings tab
* "Show verbose output during" =\> check "upload"
* Click OK

Upload again, and note the additional output telling you what is wrong.

It should also point you to this URL, which points out the most occurring issues.

The issue I have most, is that I forget to switch between Micro and Uno board (as I deploy my sketch on both boards).

# Answer
> 1 votes
assumption is windows, so with the old ide's a reboot to free up the usb ports, or sometimes simply swapping the usb port, and changing the port in the tools \> port menu.

does it identify the board you are using when you choose the port? (Genuino / Arduino)

# Answer
> 0 votes
In my experience, sketch upload error occurred due to 4 different mistakes: (1) Silly mistake: did not connect the serial cable to the PC (2) I did not choose the right com port (Tools/port). (3) I chose the wrong board type (Tools/board). connected a Nano, but selected Uno while uploading. (4) While updating my Arduino IDE to the a version, I failed to select 'download USB drivers' option. There are 2 or 3 of them.

# Answer
> 0 votes
This is a guess based on what I have encountered previously. With all the information given remember I just took a guess!

Is it possible you are experiencing a serial flood, ie it is constantly sending something to the console. Take these steps several tries may be needed:

1. Power off the board completely
2. Remove the USB cable
3. Hold down the Reset button
4. keep it held down (or, run a jumper wire from the RESET pin to the GND pin).
5. Still holding down Reset reconnect the USB cable.
6. Start uploading a sketch that does not have this problem (I use the Blink sketch).
7. When you see the Receive light blink, release the Reset button Note: I have seen this happen several times when I flood the serial output. An indication is the tx light is on.

You can check the hardware as follows. Here is a trick I use on some boards but first be the baud rate is the same in the terminal as in the sketch (Serial.begin(115200). If so then remove everything then put a jumper between ground and reset. Then put a jumper between TX and RX (pin o and pin 1 on uno). launch the IDE and what you type in the console should be echoed back to you. If this works the hardware is connected fine.

# Answer
> -1 votes
right click on computer, manage, device manager and disable the usb driver and enable it again.

---
Tags: arduino-uno, uploading
---


# Question
Title: How to rotate servo every 12 hours using RTC module?
I am trying to make a auto fish feeder to feed my fish every 6hours. I want to implement RTC module to my code. So far I've been using only an arduino and a servo using this as a code:

```
#include <Servo.h>

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

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

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

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

```

The RTC module I have is the DS1302. It's library cn be downloaded here The code for the clock is this:

```
// DS1302_Serial_Hard
// Copyright (C)2015 Rinky-Dink Electronics, Henning Karlsen. All right reserved
// web: http://www.RinkyDinkElectronics.com/
//
// A quick demo of how to use my DS1302-library to
// retrieve time- and date-date for you to manipulate.
//
// I assume you know how to connect the DS1302.
// DS1302:  CE pin    -> Arduino Digital 2
//          I/O pin   -> Arduino Digital 3
//          SCLK pin  -> Arduino Digital 4

#include <DS1302.h>

// Init the DS1302
DS1302 rtc(2, 3, 4);

// Init a Time-data structure
Time t;

void setup()
{
  // Set the clock to run-mode, and disable the write protection
  rtc.halt(false);
  rtc.writeProtect(false);

  // Setup Serial connection
  Serial.begin(9600);

  // The following lines can be commented out to use the values already stored in the DS1302
  rtc.setDOW(FRIDAY);        // Set Day-of-Week to FRIDAY
  rtc.setTime(12, 0, 0);     // Set the time to 12:00:00 (24hr format)
  rtc.setDate(6, 8, 2010);   // Set the date to August 6th, 2010
}

void loop()
{
  // Get data from the DS1302
  t = rtc.getTime();

  // Send date over serial connection
  Serial.print("Today is the ");
  Serial.print(t.date, DEC);
  Serial.print(". day of ");
  Serial.print(rtc.getMonthStr());
  Serial.print(" in the year ");
  Serial.print(t.year, DEC);
  Serial.println(".");

  // Send Day-of-Week and time
  Serial.print("It is the ");
  Serial.print(t.dow, DEC);
  Serial.print(". day of the week (counting monday as the 1th), and it has passed ");
  Serial.print(t.hour, DEC);
  Serial.print(" hour(s), ");
  Serial.print(t.min, DEC);
  Serial.print(" minute(s) and ");
  Serial.print(t.sec, DEC);
  Serial.println(" second(s) since midnight.");

  // Send a divider for readability
  Serial.println("  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -");

  // Wait one second before repeating :)
  delay (1000);
}

```

So the question here is, how can I set up my code to work with RTC, in order to move the servo every 6 hours?

# Answer
You have to spend some time and practice coding, it does not come over night. As far as your timing look up for an alarm clock sketch that will do what you want. Once you understand that you should only have to add a few lines of code. As far as open source the tools you are using are open source. Remember there are people out there that are expertes and there people just starting so expect what you find to fall some in that range of quality.
> 1 votes

---
Tags: arduino-uno, servo, rtc, home-automation, automatization
---


title: RDM6300 library not working on ESP8266

text:
# Question
Title: RDM6300 library not working on ESP8266
I have a RDM6300 RFID module which I am trying to connect to an ESP8266 by using rdm6300.h library.

I had it all up an running all along with other components but we had connected to the ESP8266 but we had to move from the breadboard to an actual wired setup. Everything kept on working except for the RFID reader. The way I used to do it was by making a reference to this approach (more or less):

```
#include <rdm6300.h>

#define RDM6300_RX_PIN 4
#define READ_LED_PIN 13

Rdm6300 rdm6300;

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

    pinMode(READ_LED_PIN, OUTPUT);
    digitalWrite(READ_LED_PIN, LOW);

    rdm6300.begin(RDM6300_RX_PIN);

    Serial.println("\nPlace RFID tag near the rdm6300...");
}

void loop()
{
    /* if non-zero tag_id, update() returns true- a new tag is near! */
    if (rdm6300.update())
        Serial.println(rdm6300.get_tag_id(), HEX);

    digitalWrite(READ_LED_PIN, rdm6300.is_tag_near());

    delay(10);
}

```

but now, after the re-arrangement it just stopped reading tags. What I did was to disconnect everything from the ESP and leave only the RDM6300 connected to it with the sample code. Unfortunately, it doesn't seem to detect any tags.

In order to test if the components are failing for some reason, I decided to test it by using **SoftwareSerial.h** library on it like this:

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

int i;

void setup()
{
  RFID.begin(9600);    // start serial to RFID reader
  Serial.begin(9600);  // start serial to PC
}

void loop()
{
  if (RFID.available() > 0)
  {
     i = RFID.read();
     Serial.print(i, DEC);
     Serial.print(" ");
  }
}

```

and it worked perfectly fine. I was able to read the payload coming from the chip:

> 2 30 31 30 46 33 46 38 44 39 31 32 44 3

But, since I don't want to implement everything related to decoding this serial stream I decided to ask for your opinion what could be wrong here. It used to work without any problem but now it doesn't.

There is something interesting which I also noticed. When I run the first code snipped and change the ESP8266 pin used from 4 to 16(D0) and I upload it, once I move the tag close to the antenna the hardware light related to this pin starts flashing and when I bring the tag back (away from the antenna) it stops flashing.

This makes me thing that on a hardware level everything is fine but some software issues are happening.

# Answer
> 0 votes
What fixed the issue for me was to go to Boards manager on Arduino IDE and update to latest version:

Then I got the following error when compiling:

> Board generic (platform esp8266, package esp8266) is unknown

In order to fix that, I followed these instructions.

And, I also removed rdm6300 library from **C:\Program Files\Arduino\libraries** and moved it in **C:\Users\myusername\Documents\Arduino\libraries**

---
Tags: esp8266, softwareserial, rfid
---