# Question
Title: Arduino crashed my computer when I plug in the USB cable
I have a 2008 Mac that hardly ever crashes. But from time to time (not always) it crashes (the whole computer shuts down as if the power has been cut off) when I plug in an Arduino via USB.

What could cause this?

---

I've done some testing and the constant in when this occurs seems to be a cheap PIR sensor from eBay. It works some of the time.

Should I get another sensor? Or is there something about PIR sensors that makes them prone to this? It has a lot of caps... Is there another kind of motion sensor?

# Answer
> 2 votes
It could possibly be that there is a fault that is causing a short circuit. This short circuit could be in the board itself or the USB cable that connects the Arduino. The USB port on the Mac should have protection to protect against a short circuit. Your comments have indicated that you have tested for a short and found none - but this is helpful for others that are looking for a solution.

In your comments you mention that you solved this by changing the positive rail of your potentiometer from 3.3V rail to the 5V rail.

# Answer
> 1 votes
I had this problem with a Chinese knock-off of an Arduino Nano -- looks like it was actually because I had previously installed some CH341 drivers that no longer work with Sierra.

Removing those drivers (`sudo rm -r /Library/Extensions/usbserial.kext`) stopped the crash (full computer shutdown when I plugged in the Arduino, even through an externally powered USB hub), but unfortunately my Mac doesn't seem to recognize the Arduino.

It looks like there is a newer version of the driver (1.4, 2017-01-11, downloadable from here), or the 1.3 version is available as a homebrew cask if you tap that repo.

I am a little wary about installing a driver from a random Chinese site. If you want, you can unzip the driver and unpackage the `.pkg` file with `pkgutil --expand package-name.pkg destination-folder`. There are a couple subfolders including a `Payload` that you can inspect a little with `zcat` -- way over my head.

Alternatively, it looks like this repo may have a C++ driver that may work.

# Answer
> 0 votes
As n8henrie said this is an issue regarding drivers with Mac OS. I updated to Mac OS Mojave (Full disclosure I run a Hackintosh system) and plugging in the arduino nana would cause a massive kept stall causing my computer to loop (if playing a video it would loop back and forth) and I’d need to turn off the PSU in order to successfully boot. However by deleting the current drive I used (CH341) the board would no longer do this (note- I tried 3 boards from different sellers, with 1 genuine and 2 Chinese) in High Sierra this did not happen however

---
Tags: usb, mac-os
---


title: Reading setting from microSD

text:
# Question
Title: Reading setting from microSD
I modified the SD sketch for `ESP8266` to read `WIFI` setting from a file named `CONFIG.TXT`. The text file's content format is `SETTING=VALUE`. Ex.

```
SSID=AP001
KEY=AP001

```

I manage to separate the `SETTING` and `VALUE` My code:

```
#include <SPI.h>
#include <SD.h>

File myFile;

void readWifiConfig() {
  Serial.println("Initializing SD card...");
  char temp;
  bool isSetting = true;
  if (!SD.begin(4)) {
    Serial.println("Initialization failed!");
    return;
  }
  Serial.println("Initialization done.");
  myFile = SD.open("CONFIG.TXT");
  if (myFile) {
    Serial.println("CONFIG.TXT");
    while (myFile.available()) {
      temp = myFile.read();
      if (isSetting == true) {
        if (temp == '=') {
          Serial.print("="); //Writes '=' to console
          isSetting  = false;
        }
        else {
          Serial.print(temp); //Writes SETTING part to console
        }
      }
      else {
        if (temp == '\n' || temp == '\r') {
          isSetting = true;
          }
        else {
          Serial.print(temp); //Writes VALUE part to console
          }
        }
    }
    myFile.close();
  } else {
    Serial.println("Can't open CONFIG.TXT");
  }
}

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  delay(10);
  readWifiConfig();
}

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

}

```

Output:

```
Initializing SD card...
Initialization done.
CONFIG.TXT
SSID=AP001
KEY=AP001

```

I want to write the values to their corresponding variables and I don't know how.

```
char* ssid;
char* key;

```

# Answer
> 0 votes
New and improved code.

File format:

```
$SETTINGNAME=SETTINGVALUE;

```

New code:

```
#include <SPI.h>
#include <SD.h>

File configFile;
uint8_t filePosition;
uint8_t workingIndex = 0;
uint8_t settingNameValuePositions[16][3];
uint8_t temporaryBufferPosition = 0;
char temporaryBuffer[32];

void setPosition(uint8_t mrk) {
  settingNameValuePositions[workingIndex][mrk] = filePosition;
}

uint8_t getPosition(uint8_t idx, uint8_t mrk) {
  return settingNameValuePositions[idx][mrk];
}

void addToBuffer(char inp) {
  temporaryBuffer[temporaryBufferPosition] = inp;
  temporaryBufferPosition++;
}

void resetBuffer() {
  temporaryBufferPosition = 0;
  memset(temporaryBuffer, 0, sizeof(temporaryBuffer));
}

char* requestSetting(char *settingName) {
  for (int i = 0; i < workingIndex; i++) {
    uint8_t nS = getPosition(i,0); //$
    uint8_t eQ = getPosition(i,1); //=
    uint8_t vE = getPosition(i,2); //;
    bool isFound = false;
    resetBuffer();
    for (int g = nS; g < eQ - 1; g++) {
      configFile.seek(g);
      addToBuffer(configFile.read());
    }
    if (strcmp(temporaryBuffer,settingName) == 0) {
      isFound = true;
      resetBuffer();
    }
    for (int g = eQ; g < vE - 1; g++) {
      configFile.seek(g);
      addToBuffer(configFile.read());
    }
    if (isFound) {
      isFound = false;
      return temporaryBuffer;
    }
  }
  return "0";
}

bool readConfigFile(char* fileName) {
  //Serial.println("INITIALIZING SD CARD");
  if (!SD.begin()) {
    //Serial.println("INITIALIZING SD CARD FAILED");
    return false;
  }
  else {
    //Serial.println("INITIALIZING SD CARD COMPLETED");
    //Serial.println("OPENING FILE: " + String(fileName));
    configFile = SD.open(fileName);
    if (!configFile) {
      //Serial.println("ERROR OPENING FILE: " + String(fileName));
      return false;
    }
    else {
      //Serial.println("FILE " + fileName + " OPENED");
      //Serial.println("SEARCHING FOR MARKER POSITIONS");
      while (configFile.available()) {
        char fileChar = configFile.read();
        filePosition = configFile.position();
        switch (fileChar) {
          case '$':
            setPosition(0);
            break;
          case '=':
            setPosition(1);
            break;
          case ';':
            setPosition(2);
            workingIndex++;
        }
      }
    }
    return true;
  }
}

void setup() {
  Serial.begin(115200);
  readConfigFile("CONFIG.TXT"); //FILE NAME
  Serial.println(requestSetting("SETTINGNAME"));
}
void loop() {
}

```

# Answer
> 0 votes
Somehow I managed to do it but my code is un-optimized. Please let me now if I've done something that isn't good.

I changed the content format to this so it's much easier for me. (CONFIG.TXT)

```
SSID%&WIFIAP001&%KEY%&PASS1234&

```

New Code.

```
#include <SPI.h>
#include <SD.h>

File myFile;
char wifiSsid[63];
char wifiKey[63];
char temp;
char settingSsid[5] = "SSID";
char settingKey[4] = "KEY";
char settingTemp[10];
char valueTemp[63];
int settingTempLastPos = 0;
int valueTempLastPos = 0;
int percentCount = 0;
int andCount = 0;
bool isSetting = true;
bool ssidValueFound = false;
bool keyValueFound = false;

void readWifiConfig() {
  Serial.println("Initializing SD card...");

  if (!SD.begin(4)) {
    Serial.println("Initialization failed!");
    return;
  }
  Serial.println("Initialization done.");
  myFile = SD.open("CONFIG.TXT");
  if (myFile) {
    Serial.println("CONFIG.TXT");
    while (myFile.available()) {
      temp = myFile.read();
      if (temp == '%') {
        percentCount++;
        isSetting = true;
        if (percentCount == 2) {
          //Serial.println(settingTemp);
          if (strcmp(settingSsid,settingTemp) == 0) {
            Serial.println("SSID SETTING FOUND");
            //IF FOUND RAISE FLAG FOR ADDING VALUE TO SSID CHAR ARRAY
            ssidValueFound = true;
            }
          else if (strcmp(settingKey,settingTemp) == 0) {
            Serial.println("KEY SETTING FOUND");
            //IF FOUND RAISE FLAG FOR ADDING VALUE TO SSID CHAR ARRAY
            keyValueFound = true;
            }
          memset(&settingTemp[0], 0, sizeof(settingTemp));
          settingTempLastPos = 0;
          percentCount = 0;
        }
      }
      else if (temp == '&') {
        andCount++;
        isSetting = false;
        if (andCount == 2) {
          //Serial.println(valueTemp);
          if (ssidValueFound) {
            //Serial.println(valueTemp);
            memcpy(wifiSsid,valueTemp,63);
            //Serial.println(wifiSsid);
            ssidValueFound = false;
            }
          else if (keyValueFound) {
            //Serial.println(valueTemp);
            memcpy(wifiKey,valueTemp,63);
            //Serial.println(wifiKey);
            keyValueFound = false;
            }
          memset(&valueTemp[0], 0, sizeof(valueTemp));
          valueTempLastPos = 0;
          andCount = 0;
        }
      }
      else {
        if (isSetting == true) { //setting
          settingTemp[settingTempLastPos] = temp;
          settingTempLastPos++;
        }
        else if (isSetting == false) { //value
          valueTemp[valueTempLastPos] = temp;
          valueTempLastPos++;
        }
      }
    }
    //Serial.println(settingTemp);
    myFile.close();
  } else {
    Serial.println("Can't open CONFIG.TXT");
  }
}

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  delay(10);
  readWifiConfig();
  Serial.println(wifiSsid);
  Serial.println(wifiKey);
}

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

}

```

Output:

```
Initializing SD card...
Initialization done.
CONFIG.TXT
SSID SETTING FOUND
KEY SETTING FOUND
WIFIAP001
PASS1234

```

# Answer
> 0 votes
```
uint8_t settingNameValuePositions[16][3];

```

If you have more than 16 variables it's going to crash your webserver.

If your config file has more than 256 characters, then you should use short instead of uint8\_t.

---
Tags: esp8266, sd-card
---


# Question
Title: Same output on displays with different I2C-addresses (AdaFruit library, ESP32)
I've got two displays hooked up to a ESP32 via I2C and I'm using the AdaFruit library. All handling display output is packed in a own library. As I was testing I only had one display set up and everything looked fine. Now, in my actual setup with two displays, I only get the output of the first display on both screens. The displays are running on the same I2C-bus, different addresses are set. I also ran a address/portscanner that confirmed the different addresses (0x3C and 0x3D).

I have used separate displays with the AdaFruit library in such a setup before, but only on an Arduino uno and without having code moved to own libraries. So I can't tell if the ESP32 or having multiple files is messing things up or I'm missing something.

Here are parts of code in the cpp-file I used to initialize the displays and some functions I call:

```
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Wire.h>
#include <gfxfont.h>
#include <SPI.h>
#include "DisplayOut.h"
#include "Game.h"

    /* -------------esp32 Pin setup --------------------- */
    const byte displayData = 21;    // I2C SDA
    const byte displayClock = 23;   // I2C SCL
    /* --------------------------------------------------- */

// Define OLED
#define OLED_RESET displayData
Adafruit_SSD1306 display1(OLED_RESET);
Adafruit_SSD1306 display2(OLED_RESET);

/* some variables */

void DisplayOutClass::init()
{
    // Initialize each display with i2c-address

    display1.begin(SSD1306_SWITCHCAPVCC, 0x3C);
    display2.begin(SSD1306_SWITCHCAPVCC, 0x3D);
    display1.setTextWrap(false);
    display2.setTextWrap(false);
}

void DisplayOutClass::scorePlayer1(int score1)
{
    display1.clearDisplay();

    if (gameMode == 2)
    {
        display1.clearDisplay();
        display1.setCursor(0, 0);
        display1.setTextSize(2);
        display1.setTextColor(WHITE);
        display1.print(playerName[player1]);
    }

    display1.setTextSize(4);
    display1.setTextColor(WHITE);
    display1.setCursor(getCenteredPosX(3, String(score1)), 24);
    display1.print(score1);
}

void DisplayOutClass::scorePlayer2(int score2)
{
    display2.clearDisplay();

    if (gameMode == 2)
    {
        display2.clearDisplay();
        display2.setCursor(0, 0);
        display2.setTextSize(2);
        display2.setTextColor(WHITE);
        display2.print(playerName[player2]);
    }

    display2.setTextSize(4);
    display2.setTextColor(WHITE);
    display2.setCursor(getCenteredPosX(3, String(score2)), 24);
    display2.print(score2);
}

/* some more Functions */

DisplayOutClass DisplayOut;

```

I didn't post the complete code or the header file, because it exceeds a few hundred lines. But this should show how the I2C-addresses are used. If necessary, I of course can post the rest of the code.

My next approach would be either trying the U8g2 library or trying start a second I2C bus. Since I already have a finished circuit board, so this would be my least preferred option.

# Answer
Try the new constructors (old ones are deprecated):

```
Wire.begin(21, 23); // SDA, SCL

Adafruit_SSD1306 display1(SSD1306_LCDWIDTH, SSD1306_LCDHEIGHT);
Adafruit_SSD1306 display2(SSD1306_LCDWIDTH, SSD1306_LCDHEIGHT);

display1.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display2.begin(SSD1306_SWITCHCAPVCC, 0x3D);

```
> 0 votes

---
Tags: i2c, adafruit, esp32, wire-library, ssd1306
---


# Question
Title: SIM900 AT command HTTP GET request not show the web page
I build a simple HTTP GET request by SIM900. Here is it:

```
-----1-----
AT+CSQ

+CSQ: 25,0

OK

-----2-----
AT+CGATT?

+CGATT: 1

OK

-----3-----
AT+SAPBR=3,1,"CONTYPE","GPRS"

OK

-----4-----
AT+SAPBR=3,1,"APN","indosatgprs"

OK

-----5-----
AT+SAPBR=1,1

OK

-----6-----
AT+HTTPINIT

ERROR

-----6.1-----
AT+HTTPPARA="CID",1

OK

-----7-----
AT+HTTPPARA="URL","http://www.minimalsites.com"

OK

-----8-----
AT+HTTPACTION=0

OK

-----9-----
AT+HTTPREAD

OK

-----10-----
AT+HTTPTERM

ERROR

+HTTPACTION:0,200,1240

-----10.0-----
AT+SAPBR=0,1

OK

```

The step 9 AT+HTTPREAD I supposed to see some html from http://www.minimalsites.com. But i dont see anything, What wrong with me?

# Answer
> 2 votes
From what I can see in your results, it seems `AT+HTTPINIT` returned an error. This means the HTTP service wasn't even successfully activated. So there's no way the commands you issued later would have been successful. From the AT command manual, AT+HTTPINIT is necessary before you can do any HTTP-related stuff. You need to run the command `AT+CGATT=1` to attach GPRS, even if your query shows its value is already 1. It could also be that your APN requires authentication, using a username and password. So once you find out the username and password authorized by 'indosatgprs' (customer care?), you can use them in the following commands.

```
    AT+SAPBR=3,1,"USER","Enter the username here"
    AT+SAPBR=3,1,"PWD","Enter password"

```

Both commands should return OK if successful. To view all the parameters you have set, you can use `AT+SAPBR=4,1`. If all the parameters are satisfactory, and you have sufficient airtime in the SIM, then you can attempt `AT+HTTPINIT`. Only if this command returns OK, should you proceed to run `AT+HTTPPARA`-related commands.

# Answer
> 0 votes
Check Your Connection Try Pinging the IP of Your Arduino and INstead of Using the AT commands use this library its easier and Nice https://github.com/amcewen/HttpClient

# Answer
> 0 votes
You have to wait after `AT+HTTPACTION=0` for a while until you see something like `+HTTPACTION:0,200,1240`

Then continue to `AT+HTTPREAD`, you will see the result.

Finally, terminate HTTP.

# Answer
> 0 votes
after days fighting with asynchronous and limit serial buffer size (64Bytes). I found this one.

this link help me out, it uses the standard library SoftwareSerial and my big txt file 1100 bytes or my html file (5814bytes) are download again & again with no issue!!

https://www.youtube.com/watch?v=cpgQOmQwUL8&t=1263s http://www.iforce2d.net/sketches/gsm\_HTTPGet.zip nb: I change it to AltSoftSerial, no problem neither. Thanks iforce2d

ps: you can also use the "ModuleSerial-master" library, but I need to save the space for other code (which already uses 74% of 2KB RAM) so I stick to AltSoftSerial which already found in my sketch

---
Tags: gsm
---


title: 'RtcDateTime' does not name a type

text:
# Question
Title: 'RtcDateTime' does not name a type
I've tested a code that compiles successfully.

But after i merged it to another code, here it shown an error says RtcDateTime doesn't name a type.

Used library : https://github.com/Makuna/Rtc

Some notes : \- RtcDateTime instances are being used in setup() and loop() without a problem. \- RtcDS3231 header file is included (which includes RtcDateTime.h inside it). \- Tried to include RtcDateTime.h in my sketch, doesn't work !

Code : (Contains combination of 3 devices : RTC , I2C Ultrasonic and HX711 loadcell)

```
/*
Below, I define the SCL and SDA pins by their ATMEGA pins I have included links to common mappings below.
    UNO:  http://arduino.cc/en/Hacking/PinMapping168
    NANO: (matches UNO but has fewer pins)
    MEGA 2560: http://arduino.cc/en/Hacking/PinMapping2560
The current data matches the setup for the Arduino Uno -- they may need to be changed if the hardware changes.
You can also switch the I2C interface
to any of the tristate pins that you want (not just the SDA or SCL pins).
*/
#define SCL_PIN D2              //Default SDA is Pin5 PORTC for the UNO -- you can set this to any tristate pin
#define SDA_PIN D1              //Default SCL is Pin4 PORTC for the UNO -- you can set this to any tristate pin
#define I2C_TIMEOUT 100        //Define a timeout of 100 ms -- do not wait for clock stretching longer than this time

#include "HX711.h"  //You must have this library in your arduino library folder

#define DOUT  D1
#define CLK  D2

HX711 scale(DOUT, CLK);
float calibration_factor = -10060; //-106600 worked for my 40Kg max scale setup

/*
I have included a couple of extra useful settings for easy reference.
//#define I2C_CPUFREQ (F_CPU/8)//Useful if you plan on doing any clock switching
#define I2C_FASTMODE 1         //Run in fast mode (400 kHz)
#define I2C_SLOWMODE 1         //If you do not define the mode it will run at 100kHz with this define set to 1 it will run at 25kHz
*/
#include <SlowSoftI2CMaster.h>     //You will need to install this library
// create new instance with A4 as SDA, A5 as SCL and enable internal pullups
SlowSoftI2CMaster si = SlowSoftI2CMaster(SDA_PIN, SCL_PIN);

/*
 *  RTC Code starts here
 */

#include <Wire.h> // must be included here so that Arduino library object file references work
#include <RtcDS3231.h>
RtcDS3231<TwoWire> Rtc(Wire);
/*
 *  RTC Headers Ending
 */

void setup(){
  // Initialize both the serial and I2C bus
  Serial.begin(9600);
  Serial.println("Press T to tare");
  scale.set_scale(calibration_factor);  //Calibration Factor obtained from first sketch
  scale.tare();             //Reset the scale to 0

if (!si.i2c_init()) // initialize I2C module
        Serial.println("I2C init failed");

    /*
     *  RTC Setup :
     */
     Rtc.Begin(SDA_PIN,SCL_PIN);

    RtcDateTime compiled = RtcDateTime(__DATE__, __TIME__);
    printDateTime(compiled);
    Serial.println();

    if (!Rtc.IsDateTimeValid())
    {
        // Common Cuases:
        //    1) first time you ran and the device wasn't running yet
        //    2) the battery on the device is low or even missing

        Serial.println("RTC lost confidence in the DateTime!");

        // following line sets the RTC to the date & time this sketch was compiled
        // it will also reset the valid flag internally unless the Rtc device is
        // having an issue

        Rtc.SetDateTime(compiled);
    }

    if (!Rtc.GetIsRunning())
    {
        Serial.println("RTC was not actively running, starting now");
        Rtc.SetIsRunning(true);
    }

    RtcDateTime now = Rtc.GetDateTime();
    if (now < compiled)
    {
        Serial.println("RTC is older than compile time!  (Updating DateTime)");
        Rtc.SetDateTime(compiled);
    }
    else if (now > compiled)
    {
        Serial.println("RTC is newer than compile time. (this is expected)");
    }
    else if (now == compiled)
    {
        Serial.println("RTC is the same as compile time! (not expected but all is fine)");
    }

    // never assume the Rtc was last configured by you, so
    // just clear them to your needed state
    Rtc.Enable32kHzPin(false);
    Rtc.SetSquareWavePin(DS3231SquareWavePin_ModeNone);

    /*
     *  RTC Setup Ending
     */
}
#define countof(a) (sizeof(a) / sizeof(a[0]))

void loop()
{
  if (!si.i2c_init()) // initialize I2C module
        Serial.println("I2C init failed");
  // (OPTIONAL) Read a sensor at the default address
  read_the_sensor_example();

  scale.begin(SDA_PIN,SCL_PIN);
  Serial.print("Weight: ");
  Serial.print(scale.get_units(), 5);  //Up to 3 decimal points
  Serial.println(" kg"); //Change this to kg and re-adjust the calibration factor if you follow lbs

  if(Serial.available())
  {
    char temp = Serial.read();
    if(temp == 't' || temp == 'T')
      scale.tare();  //Reset the scale to zero
  }

  /*
   *  RTC Loop Start
   */
  if (!Rtc.IsDateTimeValid())
    {
        // Common Cuases:
        //    1) the battery on the device is low or even missing and the power line was disconnected
        Serial.println("RTC lost confidence in the DateTime!");
    }

    RtcDateTime now = Rtc.GetDateTime();

    Serial.println();
    // String date = dateS(now);
    // String time = timeS(now);

  RtcTemperature temp = Rtc.GetTemperature();
  temp.Print(Serial);
  // you may also get the temperature as a float and print it
    // Serial.print(temp.AsFloatDegC());
    Serial.println("C");

  /*
   *    RTC loop Ending
   */
}

void printDateTime(const RtcDateTime& dt)
{
    char datestring[20];

    snprintf_P(datestring,
            countof(datestring),
            PSTR("%02u/%02u/%04u %02u:%02u:%02u"),
            dt.Month(),
            dt.Day(),
            dt.Year(),
            dt.Hour(),
            dt.Minute(),
            dt.Second() );
    Serial.print(datestring);
}

///////////////////////////////////////////////////
// Function: Start a range reading on the sensor //
///////////////////////////////////////////////////
//Uses the I2C library to start a sensor at the given address
//Collects and reports an error bit where: 1 = there was an error or 0 = there was no error.
//INPUTS: byte bit8address = the address of the sensor that we want to command a range reading
//OUPUTS: bit  errorlevel = reports if the function was successful in taking a range reading: 1 = the function
//  had an error, 0 = the function was successful
boolean start_sensor(byte bit8address){
  boolean errorlevel = 0;
  bit8address = bit8address & B11111110;               //Do a bitwise 'and' operation to force the last bit to be zero -- we are writing to the address.
  errorlevel = !si.i2c_start(bit8address) | errorlevel;   //Run i2c_start(address) while doing so, collect any errors where 1 = there was an error.
  errorlevel = !si.i2c_write(81) | errorlevel;            //Send the 'take range reading' command. (notice how the library has error = 0 so I had to use "!" (not) to invert the error)
  si.i2c_stop();
  return errorlevel;
}

///////////////////////////////////////////////////////////////////////
// Function: Read the range from the sensor at the specified address //
///////////////////////////////////////////////////////////////////////
//Uses the I2C library to read a sensor at the given address
//Collects errors and reports an invalid range of "0" if there was a problem.
//INPUTS: byte  bit8address = the address of the sensor to read from
//OUPUTS: int   range = the distance in cm that the sensor reported; if "0" there was a communication error
int read_sensor(byte bit8address){
  boolean errorlevel = 0;
  int range = 0;
  byte range_highbyte = 0;
  byte range_lowbyte = 0;
  bit8address = bit8address | B00000001;  //Do a bitwise 'or' operation to force the last bit to be 'one' -- we are reading from the address.
  errorlevel = !si.i2c_start(bit8address) | errorlevel;
  range_highbyte = si.i2c_read(0);           //Read a byte and send an ACK (acknowledge)
  range_lowbyte  = si.i2c_read(1);           //Read a byte and send a NACK to terminate the transmission
  si.i2c_stop();
  range = (range_highbyte * 256) + range_lowbyte;  //compile the range integer from the two bytes received.
  if(errorlevel){
    return 0;
  }
  else{
    return range;
  }
}

/////////////////////////////////////////
// Function: Change the sensor address //
/////////////////////////////////////////
//Uses the I2C library to change the address of a sensor at a given address
//Collects and reports an error bit where: 1 = there was an error or 0 = there was no error.
//INPUTS: byte oldaddress = the current address of the sensor that we want to change
//INPUTS: byte newddress  = the address that we want to change the sensor to
//OUPUTS: bit  errorlevel = reports if the function was successful in changing the address: 1 = the function had an
//      error, 0 = the function was successful
boolean change_address(byte oldaddress,byte newaddress){
  //note that the new address will only work as an even number (odd numbers will round down)
  boolean errorlevel = 0;
  oldaddress = oldaddress & B11111110;  //Do a bitwise 'and' operation to force the last bit to be zero -- we are writing to the address.
  errorlevel = !si.i2c_start(oldaddress) | errorlevel; //Start communication at the new address and track error codes
  errorlevel = !si.i2c_write(170) | errorlevel;        //Send the unlock code and track the error codes
  errorlevel = !si.i2c_write(165) | errorlevel;        //Send the unlock code and track the error codes
  errorlevel = !si.i2c_write(newaddress) | errorlevel; //Send the new address
//  si.i2c_stop();
  return errorlevel;
}

//////////////////////////////////////////////////////////
// Code Example: Read the sensor at the default address //
//////////////////////////////////////////////////////////
void read_the_sensor_example(){
  boolean error = 0;  //Create a bit to check for catch errors as needed.
  int range;

  //Take a range reading at the default address of 224
  error = start_sensor(224);    //Start the sensor and collect any error codes.
  if (!error){                  //If you had an error starting the sensor there is little point in reading it as you will get old data.
    delay(100);
    range = read_sensor(224);   //reading the sensor will return an integer value -- if this value is 0 there was an error
    Serial.print("R:");Serial.println(range);
  }
}

////////////////////////////////////////////////////////////////
// Code Example: Poll all possible addresses to find a sensor //
////////////////////////////////////////////////////////////////
void address_polling_example(){
  boolean error = 0;  //Create a bit to check for catch errors as needed.
  int range = 0;
  Serial.println("Polling addresses...");

  //Walk through all possible addresses and check for a device that can receive the range command and will
  //    return two bytes.
  for (byte i=2; i!=0; i+=2){   //start at 2 and count up by 2 until wrapping to 0. Checks all addresses (2-254) except 0 (which cannot be used by a device)
    error = 0;
    error = start_sensor(i);    //Start the sensor and collect any error codes.
    if (!error){                //If you had an error starting the sensor there is little point in reading it.
      delay(100);
      range = read_sensor(i);   //reading the sensor will return an integer value -- if this value is 0 there was an error
      Serial.println(i);
      if (range != 0){
        Serial.print("Device found at:");Serial.print(i);Serial.print(" Reported value of:");Serial.println(range);
      }
    }
    else{
      Serial.print("Couldn't start:");Serial.println(i);
    }
  }

  Serial.println("Address polling complete.");
}

//////////////////////////////////////////////
// Code Example: Change the default address //
//////////////////////////////////////////////
void default_address_change_example(){
  boolean error = 0;  //Create a bit to check for catch errors as needed.
  int range;

  Serial.println("Take a reading at the default address");

  //Take a range reading at the default address of 224
  error = start_sensor(224);    //Start the sensor and collect any error codes.
  if (!error){                  //If you had an error starting the sensor there is little point in reading it.
    delay(100);
    range = read_sensor(224);   //reading the sensor will return an integer value -- if this value is 0 there was an error
    Serial.print("R:");Serial.println(range);
  }

   Serial.println("Change the sensor at the default address to 222");
  //Change the address from 224 to 222
  error = 0;
  error = change_address(224,222);  //Change the address -- I don't do anything with the error handler at this point but you can if you want.
  delay(200);    //Wait 125ms for the sensor to save the new address and reset

   Serial.println("Take a reading at the new address");

  //Take a range reading at the new address of 222
  error = 0;
  error = start_sensor(222);     //Same as above but at the new address
  if (!error){
    delay(100);
    range = read_sensor(222);
    Serial.print("N:");Serial.println(range);
  }

   Serial.println("Change the sensor back to the default address");

  //Change the address from 222 to 224
  error = 0;
  error = change_address(222,224);
  delay(200);    //Wait 125ms for the sensor to save the new address and reset

}

```

So i have no idea why this happens .

Any help ?

# Answer
I was also getting the same problem, place the printDateTime function on the first page or the page where the headers and declaration's available

below function

```
#define countof(a) (sizeof(a) / sizeof(a[0]))
void printDateTime(const RtcDateTime& dt)
{
    char datestring[20];

    snprintf_P(datestring,
            countof(datestring),
            PSTR("%02u/%02u/%04u %02u:%02u:%02u"),
            dt.Month(),
            dt.Day(),
            dt.Year(),
            dt.Hour(),
            dt.Minute(),
            dt.Second() );
    Serial.print(datestring);
}

```
> 1 votes

---
Tags: arduino-ide, c++, c, rtc, ds3231-alarms
---


title: Accelstepper run stepper backward

text:
# Question
Title: Accelstepper run stepper backward
**Update:**

Below I implemented how I understood your suggestions. And it still does only turn in one direction (forward). Curiously if I entered M\_DEST in the stepperOneForward() function it turned forward very long but smooth. The code below made it rotate as usual very jittery. Is this the acceleration part and if so how can I change that ? Ideally I would be able to tell the stepper go to position X and return to start and that in constant speed.

```
 #include <AccelStepper.h>

const int stepPin = 5;
const int dirPin = 4;
const int enPin = 12;

unsigned int DEST = 800;
unsigned int M_DEST = -800;
unsigned int SPD = 1600;
unsigned int ACCEL = 800;

AccelStepper stepper1(1,stepPin,dirPin);

void setup() {

  pinMode(stepPin,OUTPUT);
  pinMode(dirPin,OUTPUT);
  pinMode(enPin,OUTPUT);

  stepper1.setEnablePin(enPin);
  stepper1.setPinsInverted(false, false, true);
  Serial.begin(9600);  // Start Serial
}

void loop() {

stepperOneForward();
Serial.println("Stepper1 turned forward.");
delay(1000);
stepperOneBackward();
Serial.println("Stepper1 turned backward.");
}

void stepperOneForward() {

  stepper1.enableOutputs();
  stepper1.setMaxSpeed(SPD);
  stepper1.setAcceleration(ACCEL);
  stepper1.move(DEST);
  if (DEST > 0) {
    while ( stepper1.distanceToGo() > 0) {
      stepper1.run();
      }
  //stepper1.disableOutputs();
  }
 }

 void stepperOneBackward() {

  stepper1.enableOutputs();
  stepper1.setMaxSpeed(SPD);
  stepper1.setAcceleration(ACCEL);
  stepper1.move(M_DEST);
  if (M_DEST < 0) {
    while ( stepper1.distanceToGo() > 0) {
      stepper1.run();
      }
  //stepper1.disableOutputs();
  }
 }

```

I have multiple steppers that I would like to run forward until they hit a microswitch and backwards to the initial position. But to simplify things I would like to control one stepper going forward and then backward. The code below always just turns clockwise.

I tried to set the dirPin to low, which did not work. I tried to reverse the `setMaxSpeed` (by putting a minus in front of it). I found the "enum AccelStepper::Direction" class in Accelstepper that did not explain how to to set `DIRECTION_CCW` or `DIRECTION_CW`.

What I would like to achieve is control these steppers so they move smoothly forward, wait and then backwards. This should be very easy, but has frustrated me now for too long. I would use any library at this point that can do this and control more than 1 stepper.

The SPD and ACCEL values are so high because I use microstepping (6400 is a full cycle).

```
#include <AccelStepper.h>

const int stepPin = 5;
const int dirPin = 4;
const int enPin = 12;

unsigned int DEST = 6400;
unsigned int SPD = 1600;
unsigned int ACCEL = 800;

void setup() {

  pinMode(stepPin,OUTPUT);
  pinMode(dirPin,OUTPUT);
  pinMode(enPin,OUTPUT);
  Serial.begin(9600);  // Start Serial
}

void loop() {

stepperOneForward();
Serial.println("Stepper1 turned forward.");
stepperOneBackward();
Serial.println("Stepper1 turned backward.");
}

void stepperOneForward() {

  AccelStepper stepper1(1,stepPin,dirPin);
  digitalWrite(enPin,LOW);
  stepper1.setMaxSpeed(SPD);
  stepper1.setAcceleration(ACCEL);
  stepper1.move(DEST);
  if (DEST > 0) {
    while ( stepper1.distanceToGo() > 0) {
      stepper1.run();
      }
  digitalWrite(enPin,HIGH);
  }
 }

 void stepperOneBackward() {

  AccelStepper stepper1(1,stepPin,dirPin);
  digitalWrite(enPin,LOW);
  stepper1.setMaxSpeed(-SPD);
  stepper1.setAcceleration(ACCEL);
  stepper1.move(DEST);
  if (DEST < 0) {
    while ( stepper1.distanceToGo() > 0) {
      stepper1.run();
      }
  digitalWrite(enPin,HIGH);
  }
 }

```

# Answer
First, you are creating/destroying the `AccelStepper stepper1()` object at every call. This is not right, as the library can no longer keep track of the stepper position and state.

The stepper object should be created in the global scope (that is, outside of `setup()` or `loop()`).

Second, you can call `stepper1.setEnablePin(enPin)` and `stepper1.setPinsInverted(false, false, true)` after you create the object to have the AccelStepper library control the enable pin and to set the enable pin to operate active-low. Then the driver is enabled or disabled with calls to `stepper1.enableOutputs()` and `stepper1.disableOutputs()`. In practice, you would not disable the driver except for power saving, as the stepper can no longer hold it's position when the outputs are not enabled. It will lose it's position.

Third, do not set the speed to a negative value. The direction of the stepper is determined by the library based on the current position and the desired end position. When the library is created, the position is zero. You can set the new position in several ways:

* `stepper1.move()`: Set the target position **relative to the current position**. This means to go *backwards* you pass this function a negative value. It will add this (negative) number to the internal target position, and then `run()` will work to get it there.
* `stepper1.moveTo()`: Set a new absolute position. If you initially set the position to 100 and move there, then set it to 50, the stepper will run in reverse to be able to reach position 50. If you start in position 0 and run to 50, it will run forward. If you start at 0 and set to -50, it will run in reverse to get there, and so on.
> 3 votes

---
Tags: stepper-motor
---


# Question
Title: Safe place to download CH340G drivers from
I am working with an Arduino Uno clone that uses the CH340G USB to TTL converter in lieu of the 16U2 found on the Uno. I see that most tutorials suggest downloading the CH340G drivers from what they call "a chinese website". I don't quite trust that site, is there any more trustworthy website where one might be able to acquire CH340G drivers for a modern Linux distro (preferably CentOS or Debian).

I ask here because devices with that chip seem to be popular in the Arduino community. If the unix stackexchange site would be a better place to ask then the question can be moved. Thank you.

**EDIT:** Apparently my system is having an issue with recognizing the device. Here are some specs:

```
$ lsusb
Bus 002 Device 002: ID 8087:8000 Intel Corp.
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 002: ID 8087:8008 Intel Corp.
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 003 Device 004: ID 04d9:3015 Holtek Semiconductor, Inc.
Bus 003 Device 003: ID 0cf3:9271 Atheros Communications, Inc. AR9271 802.11n
Bus 003 Device 012: ID 045e:0040 Microsoft Corp. Wheel Mouse Optical
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

$ lsusb | wc -l
9

$ # Now I plug in the Uno clone
$ # Wait about a minute just to be sure...
$ lsusb
Bus 002 Device 002: ID 8087:8000 Intel Corp.
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 002: ID 8087:8008 Intel Corp.
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 003 Device 004: ID 04d9:3015 Holtek Semiconductor, Inc.
Bus 003 Device 003: ID 0cf3:9271 Atheros Communications, Inc. AR9271 802.11n
Bus 003 Device 012: ID 045e:0040 Microsoft Corp. Wheel Mouse Optical
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
$ lsusb | wc -l
9

$ uname -a
Linux happiness 4.4.0-47-generic #68-Ubuntu SMP Wed Oct 26 19:39:52 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux

$ cat /etc/issue
Ubuntu 16.04.1 LTS \n \l

```

My entire `dmesg` file can be found on pastebin, here is the end of it:

```
[37253.943739] usb 3-6: device descriptor read/64, error -71
[37254.159669] usb 3-6: new full-speed USB device number 15 using xhci_hcd
[37254.159841] usb 3-6: Device not responding to setup address.
[37254.363858] usb 3-6: Device not responding to setup address.
[37254.567744] usb 3-6: device not accepting address 15, error -71
[37254.679654] usb 3-6: new full-speed USB device number 16 using xhci_hcd
[37254.679756] usb 3-6: Device not responding to setup address.
[37254.883917] usb 3-6: Device not responding to setup address.
[37255.087716] usb 3-6: device not accepting address 16, error -71
[37255.087749] usb usb3-port6: unable to enumerate USB device

```

# Answer
Linux doesn't need drivers (indeed, the whole concept is pretty alien to Linux users).

The CH340G is fully supported by the default kernel in all distros I have ever used. On my Ubuntu machine the CH340G on my NodeMCU is detected automatically:

```
[ 8195.450566] usb 4-1: new full-speed USB device number 2 using uhci_hcd
[ 8195.630710] usb 4-1: New USB device found, idVendor=1a86, idProduct=7523
[ 8195.630714] usb 4-1: New USB device strings: Mfr=0, Product=2, SerialNumber=0
[ 8195.630716] usb 4-1: Product: USB2.0-Serial
[ 8196.675137] usbcore: registered new interface driver usbserial
[ 8196.675153] usbcore: registered new interface driver usbserial_generic
[ 8196.675166] usbserial: USB Serial support registered for generic
[ 8196.677581] usbcore: registered new interface driver ch341
[ 8196.677600] usbserial: USB Serial support registered for ch341-uart
[ 8196.677620] ch341 4-1:1.0: ch341-uart converter detected
[ 8196.690670] usb 4-1: ch341-uart converter now attached to ttyUSB0

```

Nothing to download, nothing to install, nothing to risk the security of your system with.
> 5 votes

# Answer
"Linux doesn't need drivers (indeed, the whole concept is pretty alien to Linux users)."

I feel alienated, however this information is incorrect. I have at least two Ubuntu machines that did not recognize the CH340g chip. One is Linux Mint 18.2 32bit the other is a Linux Mint 19 64bit. I used the 'driver' that I downloaded from the site in question and guess what? It is the exact same driver that NodeMCU uses. For those that want or need to download the driver, but don't want to visit a 'suspicious site' just go here nodemcu-dev and you will find three flavors: Linux, MAC and Windows. Strange that they have an MIT license for their own software.

For Linux, just extract the archive CH341SER\_LINUX.ZIP, then open a terminal in the directory and use `make && sudo make` then load the module ahem.. driver with (may need to use sudo) `insmod /{path-to-your-extracted-folder}/ch34x.ko` or reboot.

Now, I am not arguing whether or not Linux comes with the module, because I see two (one for each kernel) on just one of my systems located at /lib/modules/{x.x.x-xx}-generic/kernel/drivers/usb/serial/ch341.ko, however the one that is needed comes from the Chinese site in question that happens to be the same place where NodeMCU got theirs (or possibly some other site) for it to be recognized.

Also, I don't get how someone can buy Chinese products (or from anywhere else) and be afraid to visit their site.
> 1 votes

---
Tags: ch340
---


# Question
Title: Why does a 4 digit 7 segment cathode display wired to an Arduino not need to be connected to ground?
As a circuit neophyte I thought for a circuit to conduct current it had to be grounded.

# Answer
The Uno is grounded. Current flows *into* the A-G and DP pins (that is: D2, D3, D4, D5, D6, D6, D8, and D9 on the Uno) when one of those pins is `LOW` and one of the display's digit pins is also low.

There is one "Common" pin for each of the 4 digits, labeled D1, D2, D3, and D4 on the display. Those common pins are connected to the Anodes (positive pin) of all segments in the specified digit. When 5V is applied to the base of the transistor, the NPN transistor is off. When 0V is applied to the base of the NPN transistor, current flows from the 5V source, through the transistor, and into the Anode of the digit.

When a segment pin (A-G, DP) is `HIGH`, it is at 5V. The Anode is also at 5V, so no current flows. When a segment pin in `LOW`, it s at 0V, and current flows from the Anode to Ground through the segment pin into the Uno.

This kind of display is meant to be multiplexed by digit. To light the first digit, The D1 transistor is turned on, and the segments to light up are set to `LOW`. All other transistors are off. Then, the first digit transistor is turned off and the 2nd digit transistor is turned on, and the segment pins are re-adjusted so that the desired output on the 2nd digit is displayed. Each digit is only on for a fraction of a second, but they are rotated through all 4 so quickly, that it gives the appearance of all 4 digits being on at the same time, without requiring 8x4=32 IO pins. Multiplexing means you only need 8+4=12 IO pins.

Search "multiplexed common anode 7-segment display" for more info.
> 3 votes

# Answer
Current limit resistors are needed, one for each segment (A-G, DP) to avoid burning out the LEDs or uC IO pins:

```
(5V - Vce of transistor - Vf of the LED)/current = resistor value

```

So making some assumptions:

```
Vce = 0.7V in saturation (full on)

Vf = 2.5V (approx. for Red, check your datasheet)

10mA (so not blinding bright to start)

```

Then

```
(5V - 0.7V - 2.5V)/.01 = 180 ohm

```
> 0 votes

---
Tags: arduino-uno
---


# Question
Title: How to read Output data from SPI connector using Arduino Uno?
I am having **main controller circuit board that give the data such as ("HAI", "HELLO") to 5 pin SPI Connector mounted on the same board**. In that 5 pin SPI connector I could connect separate circuit board which has *SPI based 5 SEVEN segment LED* to see the output for e.g. ("HAI", "HELLO").

Pin configuration for **5 pin SPI connector on main circuit board.**

* Pin 1 - VCC
* Pin 2 - GND
* Pin 3 - CS (chip selection)
* Pin 4 - CLK (clock)
* Pin 5 - D IN (Data).

**Everything working fine** and also I can see the output data on the SEVEN-segment display such as "HAI" and "HELLO" **through my naked eye.**

But **I need the same data to display in my PC/Laptop console** so I used Arduino uno controller setup.

*So I did connecting wire from Arduino controller to 5 pin connector of main controller circuit board.*

*Connections below.*

```
Arduino controller                 Main controller ckt board
(Digital pins)                      (5 Pin connector)
PIN 7 (D IN) --------------------------->   PIN 5 (D IN)
PIN 6 (CS)   --------------------------->   PIN 3 (CS)
PIN 5 (CLK)  --------------------------->   PIN 4  (CLK)

```

I connected USB cable to my PC and I installed arduino driver and also configured COM PORT (COM5 my-case).

I opened **Hyper-terminal console** in that I chosen COM5 and baud rate 9600. But still **I did not get the output** ("HELLO", "HAI") on the console because the Arduino controller **does not have source code for reading the output string("HELLO", "HAI") from the 5-pin SPI connector on main ckt controller board.**

**What I need exactly?**

1. I **need a source code** that for reading the output from 5 pin connector through SPI and should display on my console.

*Can anyone share the full source code for do that above operation ?*

# Answer
Need to start with the correct pins.

With Uno, SCK is 13, MISO is 12, MOSI is 11, and typically 10 is used for slave select.

To read from a slave device, some setup is needed, then the command is run. Here's a very simple example:

```
byte ssPin = 10;
byte incomingByte;
byte addressToRead = 0x00; // or what is needed, if needed.

void setup(){
Serial.begin(9600);
pinMode (ssPin, OUTPUT);
digitalWrite (ssPin, HIGH); // most devices expect a LOW for slave select
// the code in behind SPI.transfer may do this already, I put it in anyway as
// sometimes I use different pins.  10 needs to be an output for the
// Atmega to be the SPI bus master

SPI.begin(); // uses default values: SCK of 4 MHz, MSBFIRST, Mode 0 for
//              initial signal levels
}

void loop(){
digitalWrite (ssPin, LOW); // select the device
SPI.transfer (addressToRead); // may be needed for your device
incomingByte = SPI.transfer(0); // read a byte from the slave
digitalWrite (ssPin, HIGH); // deselect the device

Serial.print(incomingByte); // may need some manipulation to make this
//                             a printable character - see
//                             www.asciitable.com
delay(500); // keep from flooding the PC screeen
}

```
> -1 votes

---
Tags: arduino-uno, spi, 7-segment
---


title: Do all pins of Arduino Uno output 5V?

text:
# Question
Title: Do all pins of Arduino Uno output 5V?
I am currently working on a project which uses PIR motion sensor and 5V relay. Since you might be familiar that both the motion sensor and the relay requires a 5V connection.

My problem is, I don't want messy connections (parallel and series) and want to use any other pin for power and ground.

Also, can you suggest which resistor I might require for the motion sensor and relay?

Thanks for any help.

# Answer
You might get away with powering a PIR sensor from a logic line. Check the specs. If it draws less ≤20mA you'd be fine. If you nee to drive more current than that you can use a CMOS TTL Driver or a properly selected N-channel MOSFET. Adafruit sells **these**, for example.

A relay is another matter. If you this is one of those optically isolated relays and all you're driving is the optioisolator then you might get away with that too if you only need ≤20mA. If you're looking to actually power the relay coils with your Arduino, forget it. it's a bad idea to even have the relay driven from the 5V line on the Arduino. Relays take quite a bit of current, and their load is quite "dirty" and likely to cause problems.

As to "which resistor I might require for the motion sensor & relay", I'm not sure what you mean. You shouldn't need any resistors. If the relay draws more current than the Arduino can supply, a current limiting resistor might protect the Arduino from damage but the relay won't work correctly.

What resistors are you referring to?
> 2 votes

---
Tags: arduino-uno, sensors, relay, resistor
---


title: SoftPWM update limitations

text:
# Question
Title: SoftPWM update limitations
i'm using arduino to dimmer 9 led strips with different output pins after an FFT audio analysis gives results at 60Hz = 16ms. \[FFT is performed by a PC and sent to arduino using a RF24 module\]

I started the project using SoftPWM on pins D2-\>D9 & A4 with a lower frequency update but now i'm having problems increasing the frequency update. I have already wired 6 copies of that board and i'm looking for a software solution

To diagnose the problem i performed a test sending a pwm value and zero at a certain frequency, if the frequency is high you can only see a lower emitted power

If I set the pwm once I have a stable signal (led intensity) If I set the pwm every ~10ms (10ms on @ certain pwm, 10ms at pwm=0) I have an unstable intensity, repeating the test on the pin 6 with a normal analogWrite i don't have the problem. With 10ms i clearly see it blinking at a random frequency (~20Hz=50ms), with 15ms I only see it random fluctuating

I'm using arduino Pro mini - 5V - 2kB Without signals arduino performs 16k cycles/second (most without changing anything), with a 10ms signal it runs at 14k cycles/second so it seems not a load problem.

Can someone help me regarding this problem?

* Should I change library
* Should I move to a lower level to rewrite a more performing library
* Should I use only 6 std pwm, draw again the board, print them again, weld all components again, and test it again?

Thanks!

PS: I can't create the SoftPWM tag for a reputation problem, can a moderator do that?

# Answer
> 0 votes
The problem is not a SoftPWM limitation but a physical one. SoftPWM have a PWM cycle at 60Hz, that makes impossible to update output faster than 34mS and that explain why I see low frequency trying to change the state with every 10 ms.

Hardcoding the IRS I can reach a much faster PWM cycle, keeping the same PWM frequency I have roughly 60% less of CPU used. With a full CPU load and latest version of the code I can reach ~600Hz PWM cycle. I decided to use a ~300PWM cycle to have enough CPU to perform other tasks (mainly handle RF24 to receive packets @ 60Hz and, if needed, forward them too other bases)

Even at higher frequencies average intensity is not stable, but higher the frequency more stable the result. That can be explained because the eye "average" incoming light and that average is not very stable

Since leds are used to produce visual effects I don't need a very accurate output, and 300Hz are enough. (I also don't have big mosfets and I don't want to stress them with higher frequencies)

---
Tags: library, pwm
---


title: Multiple .ino files in the same sketch

text:
# Question
Title: Multiple .ino files in the same sketch
Yeah yeah, I know people ask this type of thing a lot, but I couldn't find an answer *anywhere*.

I understand that you can have multiple `.ino` files in one sketch, but I don't just want functions and variables separated, *I want functionality*.

I am writing a Braille program for the NodeMCU -- It takes a message from a served website and moves servos to emulate the appropriate Braille. I want to have 2 files: one to serve the website and get input from it (`website.ino`), and the other one to manipulate the servos(`braille.ino`). The only problem is, I can't figure out where to declare/attach the servos.

I plan to have a list of servos in `braille.ino` that will be looped over with each servo being set to a different value. If I declare them in `website.ino` (my "main" file, ie, with a `setup` and `loop`), I will have to pass them to my `braille` function every time. On the other hand, if I choose to declare them as globals in my `braille.ino`, where would I attach them? Can I have *another* `setup` in `braille.ino`?

# Answer
What isn't obvious is that with Arduino, you can have normal C and C++ files in the same directory as the `.ino` file. These can have functions and variables inside them, and Arduino will link them into the main program too. You only need one `.ino` file - all the rest can be in modules with a `.c` or `.cpp` (for C++) extension.

That way, you can group "helper" functions in different files by category - for example, a `BrailleServo.c` file. These contain the functions and variables for just that category.

If you haven't programmed native C/C++:

* Put the functions and variables in the `BrailleServo.c` file, and then *repeat* the functions' header in the `BrailleServo.h` file.
* Inside the `BrailleServo.c` file, at the top, put the following line:

```
#include "BrailleServo.h"

```

Note the quotes (`" "`), not angle brackets (`< >`)
* Inside the `.ino` file, put the same `#include` line. That tells the module that "there are other functions elsewhere, and these are their definitions".

The only problem? Getting the silly Arduino environment to let you add `.c` and `.h` files to that directory. You could just use Notepad, but there's a trick (if you're using Windows):

1. Choose `File`|`Open…`
2. Right-click the pane with the files in it, and choose `New >`|`Text Document`
3. Give it a complete name, and make sure you replace the `.txt` part of the name too with `.c` or `.h`. You may get the "If you change the extension, the file may be unusable" warning - just click `OK`.
4. Select the new (blank) file in the file pane, and a new tab will appear.

> Note that 3. above assumes that you've told Windows File Explorer to NOT hide the extensions of known file types. I always do that - if you haven't, you'll need to. With:
>
> * **Windows 10**: In any folder's `View` tab, tick the `File name extensions` checkbox;
> * **Windows 7**: In `Control Panel` | `Appearance and Personalization` | `Folder Options`' `View` tab, **un**tick `Hide extensions for known file types`

---

Here are three examples:

`BrailleServo.h`

```
//
// BrailleServo.h
//

// Call this function once in setup()
void BrailleInit();

// This function activates the six servos to form the passed-in pattern.
void BrailleShow(byte pattern);

```

`BrailleServo.c`

```
//
// BrailleServo.c
//

#include "BrailleServo.h"

// The number of servos
const byte NumServos = 6;

// These are the pins for the six servos
const byte servo[NumServos] = { 3, 4, 6, 7, 9, 10 };

// This initialises the six servos
void BrailleInit() {
   for (byte i=0; i<NumServos; ++i) {
      pinMode(servo[i], OUTPUT);
      // Do what else you need to do with servo[i]
   } // for
} // BrailleInit()

// This is how to use the six servos to form the passed-in pattern
void BrailleShow(byte pattern) {
   // … Complicated code here …
} // BrailleShow(pattern)

```

`Main.ino`

```
//
// Main.ino
//

#include "BrailleServo.h"

void setup() {
   BrailleInit();
   // Other stuff
} // setup()

void loop() {
   BrailleShow('A');
   delay(1000);
   BrailleShow('B');
   delay(1000);
} // loop()

```

Incidentally, for ideas you may want to check out my answer to a more generic Braille question.
> 13 votes

# Answer
It is important to know that the tabs/ino files are concatenate into one by the builder. The order of the concatenation is the same as the order of tabs in IDE. First is the main ino file with the same name as the project. The rest of the files is concatenated in alphabetical order.

The concatenated ino file determines the visibility of variables. All ino files 'see' the variables in the main ino file, but variables in other ino files are visible only in ino file with names later in alphabetical order.

For functions the builder generates function prototypes to the beginning of the resulting cpp file, so as usual all functions are visible everywhere in all ino files.

One way to work with additional tabs is group is to write xySetup() and xyLoop() functions in the xy.ino file and then call this functions from the main setup() and loop(). My main Arduino project is created this way, so it is a big and complex example of this approach.

To illustrate, this is the resulting cpp file entering the cpp part of the build toolchain (scroll it to end):

```
#include "Arduino.h"
#define I2C_ADC121         0x50
#include <Wire.h>
extern const unsigned long EVENTS_SAVE_INTERVAL_SEC;
extern const char eventLabels[];
extern const char* eventLongLabels[];
extern const char* eventLongLabels[];
#define EVENTS_FILENAME "EVENTS.DAT"
#include <Grove_LED_Bar.h>
#include <StreamLib.h>
#include <TimeLib.h>
#include <MemoryFree.h>
#include <UIPEthernet.h>
#define ETHERNET
#include <ArduinoOTA.h>
#include <SD.h>
#define FS SD
#define Serial SerialUSB
#include "consts.h"
#define BLYNK_PRINT Serial
#define BLYNK_NO_BUILTIN // Blynk doesn't handle pins
#include <BlynkSimpleUIPEthernet.h>
#include <RTCZero.h>
#define STATS_FILENAME "STATS.DAT"

void balboaSetup() ;
void balboaReset() ;
void balboaLoop() ;
void battSettLoop() ;
boolean battSettRead(FormattedPrint& out) ;
const char* bit2s(int value, byte mask) ;
int battSettControl(boolean chargeControlOn, boolean dischargeControlOn) ;
int battSettSetLimit(byte reg, int limit) ;
void beeperLoop() ;
void alarmSound() ;
void beep() ;
void beeperTone(int freq, uint32_t time) ;
void blynkSetup() ;
void blynkLoop() ;
void updateWidgets() ;
void buttonSetup() ;
void buttonLoop() ;
void csvLogSetup() ;
void csvLogLoop() ;
void csvLogPrintJson(FormattedPrint& out) ;
void elsensSetup() ;
void elsensLoop() ;
boolean elsensCheckPump() ;
byte overheatedSecondsLeft() ;
int readElSens() ;
unsigned short elsensAnalogRead() ;
void eventsSetup() ;
void eventsLoop() ;
void eventsWrite(int newEvent, int value1, int value2) ;
boolean eventsSaved() ;
void eventsSave() ;
byte eventsRealCount() ;
void eventsPrint(FormattedPrint& stream) ;
void eventsPrint(FormattedPrint& s, int ix) ;
void eventsPrintJson(FormattedPrint& stream) ;
void eventsPrintJson(FormattedPrint& stream, int ix) ;
void eventsBlynk() ;
int eventsCompare(const void * elem1, const void * elem2) ;
void ledBarSetup() ;
void ledBarLoop() ;
void manualRunLoop() ;
byte manualRunMinutesLeft() ;
void modbusSetup() ;
boolean modbusLoop() ;
void modbusClearData() ;
boolean requestSymoRTC() ;
boolean requestInverter() ;
boolean requestMeter() ;
boolean requestBattery() ;
boolean modbusError(int err) ;
int modbusRequest(byte uid, unsigned int addr, byte len, short *regs) ;
int modbusWriteSingle(unsigned int address, int val) ;
int modbusConnection() ;
void pilotLoop() ;
unsigned short power2pwm(int power) ;
void setup() ;
void loop() ;
void shutdown() ;
void handleSuspendAndOff() ;
void clearData() ;
boolean handleAlarm() ;
boolean restHours() ;
boolean turnMainRelayOn() ;
boolean networkConnected() ;
void statsSetup() ;
void statsLoop() ;
int statsEvalCurrentPower() ;
void statsAddMilliwats() ;
void statsSave() ;
int statsConsumedPowerToday() ;
void statsPrint(FormattedPrint& out) ;
void statsPrint(FormattedPrint& out, const char *label, Stats &stats) ;
void statsPrintJson(FormattedPrint& out) ;
void statusLedSetup() ;
void statusLedLopp() ;
void statusLedShortBlink() ;
void susCalibLoop() ;
void telnetSetup() ;
void telnetLoop(boolean log) ;
void valvesBackSetup() ;
void valvesBackReset() ;
void valvesBackLoop() ;
void valvesBackStart(int v) ;
boolean valvesBackExecuted() ;
unsigned short valvesBackTempSensRead() ;
void watchdogSetup() ;
void watchdogLoop() ;
void WDT_Handler(void) ;
void webServerSetup() ;
void webServerLoop() ;
void webServerRestRequest(char cmd, ChunkedPrint& chunked) ;
void webServerServeFile(const char *fn, BufferedPrint& bp) ;
void printValuesJson(FormattedPrint& client) ;
void printAlarmJson(FormattedPrint& client) ;
const char* getContentType(const char* ext);
void wemoLoop() ;
boolean wemoPowerUsage() ;
int wemoRequest(const char* service, const char* action, const char* param, const char* value, char* response, size_t size) ;

#include "Regulator.ino"

#include "Balboa.ino"
#include "BattSett.ino"
#include "Beeper.ino"
#include "Blynk.ino"
#include "Button.ino"
#include "CsvLog.ino"
#include "ElSens.ino"
#include "Events.ino"
#include "LedBar.ino"
#include "ManualRun.ino"
#include "Modbus.ino"
#include "PowerPilot.ino"
#include "Stats.ino"
#include "StatusLed.ino"
#include "SusCalib.ino"
#include "Telnet.ino"
#include "ValvesBack.ino"
#include "Watchdog.ino"
#include "WebServer.ino"
#include "WemoInsight.ino"

```
> 4 votes

---
Tags: arduino-setup
---


title: Using Sleep AND LowPower.h

text:
# Question
Title: Using Sleep AND LowPower.h
I am trying to set up the low power module for an instance case, I have installed the low power library but when I am using the line

```
LowPower.powerDown (SlEEP_5S, ADC_OFF, BOD_OFF) ;

```

It is throwing an error stating that the 'SLEEP' was not declared in the scope. Any suggestion for that ? Do I have to include a library for sleep too ?

```
#include "LowPower.h"
  /// DON' t worry about the setup and loop, i have defined all those.

```

This set of code is in

```
  void Loop()
    ...
    else
    {
       LowPower.powerDown (SLEEP_10S, ADC_OFF, BOD_OFF) ;

```

# Answer
There is no 5 or 10 second sleep. You can't just arbitrarily choose how long to sleep for. The watchdog timer only has specific periods (defined by dividing the clock by a set amount) that it can sleep for:

```
enum period_t
{
    SLEEP_15MS,
    SLEEP_30MS,
    SLEEP_60MS,
    SLEEP_120MS,
    SLEEP_250MS,
    SLEEP_500MS,
    SLEEP_1S,
    SLEEP_2S,
    SLEEP_4S,
    SLEEP_8S,
    SLEEP_FOREVER
};

```

To sleep for 5 seconds you would need to sleep first for 4 seconds, then wake up, and then sleep for a further 1 second after that. For 10 seconds sleep for 8 seconds followed by 2 seconds.

Note that they aren't exact values, however, since the watchdog oscillator is very crude and varies wildly in frequency with both temperature and power supply voltage.
> 1 votes

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


# Question
Title: Wemos D1 mini not being shown when connected to macbook
I have multiple Wemos d1 mini lying around, but can't seem to get them connected to my macbook, to they do not show up in my /dev/tty?

I tried updating the driver, both using home-brew and installing the driver manually - as suggested here

https://github.com/adrianmihalko/ch340g-ch34g-ch34x-mac-os-x-driver

but nothing seem to work? I tried different cables? no way to connect to it?

# Answer
> 1 votes
All of the cables I tried don't have a data line

---
Tags: esp8266, usb, ch340
---


# Question
Title: Replace digitalWrite with a selective bitwise operation
I have the following code with digitalWrite I aim to write with bitwise operation only. No portability concerns here whatsoever. (for atmega328p here)

```
#define DATAOUT 11//MOSI
byte commandbits = B11000000;
for (int i = 7; i >= 3; i--) {
    digitalWrite(DATAOUT, commandbits & (1 << i));
}

```

I came up with something like this below which works.

```
#define DATAOUT 11//MOSI
byte commandbits = B11000000;
for (int i = 7; i >= 3; i--) {
    PORTB = (PORTB &(~(1<<3))) | (((commandbits &(1 << i))>>i) << 3);
}

```

Is this the most concise way. Is there a way to simplify it?

# Answer
> 2 votes
Personally I'd expand it out a little:

```
if (commandbits & (1 << i)) {
    PORTB |= (1<<3);
} else {
    PORTB &= ~(1<<3);
}

```

It's far more readable, and there are less shifts to mess around with. Plus the AVR has bit set and bit clear operations which that will make use of, especially since it's now using literal values. You could actually replace those values with literals:

```
if (commandbits & (1 << i)) {
    PORTB |= 0x08;
} else {
    PORTB &= 0xF7;
}

```

# Answer
> 1 votes
If you like both portability, readability and performance there are a few libraries (for instance Arduino-GPIO):

```
#include "GPIO.h"

GPIO<BOARD::D11> data;

// Setup
data.output();

// Manual loop unrolling for speed. Could ask the compiler to do this
// Member function write()
data.write(commandbits & 0x80);
data.write(commandbits & 0x40);
data.write(commandbits & 0x20);
data.write(commandbits & 0x10);
data.write(commandbits & 0x08);

// Or using the assignment operator
data = commandbits & 0x80;
data = commandbits & 0x40;
data = commandbits & 0x20;
data = commandbits & 0x10;
data = commandbits & 0x08;

```

And it is as fast as manually written direct port access.

---
Tags: digitalwrite, bit
---


title: Run code once after programming

text:
# Question
Title: Run code once after programming
I'm using EEPROM to store project settings non-volatile. After reuploading the sketch to my board (over SPI via ArduinoISP), the EEPROM is reset to full `0xFF`s and I have to manually do a "software reset" with a second switch, which initializes the EEPROM with its default values.

**Is it possible to run a segment of code once, and only once, after booting up the first time after being programmed?**

I'm working around it by checking whether a piece of EEPROM is `1` at startup when it would always be `0` after the initialization and during usage, but surely there's a cleaner alternative than checking for an EEPROM bit each time.

# Answer
> 8 votes
This is a X-\>Y problem. Here is a solution for X:

Bit 3 of high fuse of the ATmega328p controls if EEPROM memory is preserved through the chip erase. You can change the high fuse setting in boards.txt. Restart the IDE to apply the new setting.

The fuses are written when you select the "burn bootloader" option in the Arduino IDE.

# Answer
> 2 votes
I've actually done some tinkering with this sort of thing, or alternatively how to ensure previous EEPROM (or similar) settings are formatted on upload of a new sketch.

There are two values (C macros, in this case) that are baked into a program when it is compiled (for Arduino, the program is recompiled on each upload) that can be used to tell if the programming is "fresh."

The values you'd want are `__DATE__` and `__TIME__`. They are converted to char arrays (strings, basically) at the time the compiler is run. You can store them directly to EEPROM, or use some sort of hash to convert it to a convenient number to store instead. Then, whenever the code boots, compare the stored value with the one computed from the values coded into the program. If they *differ*, overwrite the stored value with the new one and execute the run-once code.

Something along the lines of

```
byte i=0;
char checkVal[]=__TIME__ __DATE__;
for (int j=0; j<strlen(checkVal); j++){
  i+=(byte)checkVal[j];//Creates a modulo 256 sum of the ASCII values of the chars (really poor hash)
}
if(EEPROM.read(26)!=i){//stored EEPROM location (arbitrary) -- feel free to use wear leveling, though, or some other method
  //DO RUN-ONCE CODE HERE
  EEPROM.write(26,i);//store the new value to stop it running again
}

```

---
Tags: arduino-uno, atmega328, eeprom, startup
---


# Question
Title: Arduino Uno: external power supply +5V and serial communication with pc over USB
I have connected to my Arduino Uno outputs relay module. Relay module has 16 relays (5VDC) which are controlled by transoptors pins (HIGH from Arduino = specific relay is off).

Link to relay module (lang: polish): https://botland.com.pl/pl/przekazniki/6940-modul-przekaznikow-16-kanalow-z-optoizolacja-styki-7a240vac-cewka-5v.html?search\_query=modul+przekazniko&results=75 (SRD-05VDC-SL-C relays).

Arduino is supplied by +5V pin and GND pins with external power supply MDR-5-10. Relay module is supplied with the same power supply.

I control Arduino from PC using serial communication over USB (I send a command eg. 1;1;1;1;1;1;, then 6 outputs goes to HIGH). And now there is a problem. When I disconnect relay module control pins from Arduino outputs everything works fine. But when it is connected, I get serial com. error "device not found" (after some switches: sometimes it works for about 20 output switches, sometimes for 1 output switch) and I have to open serial communication again. Probably error appears only when I'm switching outputs.

I think the problem is because my external power supply +5V drops for a while when switching and then Arduino switches to +5V from USB (which doesn't drop), which has not enough power and then error occurs.

Am I right? Any suggestions to fix the problem?

**EDIT #1:** Thank you for help. Answers:

@**Jot**, after disconnecting +5V Arduino pin, but with connected relay module, I get serial error immediately with first relay switch. If i dosconnect both +5V pin and relay module control pin, my application works fine. My wires: external power supply - Arduino: 0,5 mm2; Arduino - relay module control pins: 23 AWG (~0,25 mm2); external power supply - relay module +5V and GND: 1,5 mm2. It flows through relays: 24VDC \<30W or 230VAC ~20mA.

@**CrossRoads**, no I use A0-A4 and Q3-Q12 (for relay module: Q3-Q7, Q9-Q11, Q13).

@**Duncan C**: Currently, I use only 9 relays, other control pins are disconnected and off. Here - http://botland.com.pl/index.php?controller=attachment&id\_attachment=244 (power consumption per relay - 0,36W 5VDC) - you can see relay datasheet. Relays are isolated from Arduino with opto-isolators (signal HIGH from Arduino = relay is off). I never switch them all at once. In specific function I never use more then 5 relays together.

@**Majenko**, thank you, I'll give it a try in Tuesday!

Further informations:

1. *Probably* problems occur more often when I connect wires to relays pins (I use them all as NO: 7x 30W 24VDC - coils, 2x 230VAC ~20mA - contactor).
2. Serial communication error can occur during both reading or writing to serial.

# Answer
I have a similar rig using a 4-channel optically isolated relay, but I use different power supplies for the Arduino and for the relay. (It works perfectly.) My guess is that the relays are causing the voltage on your arduino to droop when they switch on. I suggest using separate power supplies.

As @Majenko suggests, you might try adding a filtering cap (capacitor) between +5V and ground very near the Arduino. The cap should slow the drop in voltage to the Arduino long enough for the power supply to recover, but separate power supplies is the surest fix.
> 1 votes

---
Tags: serial, usb
---


# Question
Title: 28 BYJ stepper motor runs faster using delay() and little slower using millis(), why?
I'm working to develop a code for the stepper motor to use it in a project. And since using delay() isn't as efficient as millis(). So I first developed the code that use delay with 1ms delay between the steps which is the fastest I could do with this stepper motor.

Then I developed similar code using millis() with same 1ms delay but it didn't feel as smooth/fast as the one with delay() function.

So what's the reason for that?

These are the code:

1. With delay():

```
    void clockwise(void){
        digitalWrite(in4, HIGH);
        digitalWrite(in3, LOW);
        digitalWrite(in2, LOW);
        digitalWrite(in1, LOW);
    delay(1);
        digitalWrite(in4, HIGH);
        digitalWrite(in3, HIGH);
        digitalWrite(in2, LOW);
        digitalWrite(in1, LOW);
    delay(1);
        digitalWrite(in4, LOW);
        digitalWrite(in3, HIGH);
        digitalWrite(in2, LOW);
        digitalWrite(in1, LOW);
    delay(1);
        digitalWrite(in4, LOW);
        digitalWrite(in3, HIGH);
        digitalWrite(in2, HIGH);
        digitalWrite(in1, LOW);
    delay(1);
        digitalWrite(in4, LOW);
        digitalWrite(in3, LOW);
        digitalWrite(in2, HIGH);
        digitalWrite(in1, LOW);
    delay(1);
        digitalWrite(in4, LOW);
        digitalWrite(in3, LOW);
        digitalWrite(in2, HIGH);
        digitalWrite(in1, HIGH);
    delay(1);
        digitalWrite(in4, LOW);
        digitalWrite(in3, LOW);
        digitalWrite(in2, LOW);
        digitalWrite(in1, HIGH);
    delay(1);
        digitalWrite(in4, HIGH);
        digitalWrite(in3, LOW);
        digitalWrite(in2, LOW);
        digitalWrite(in1, HIGH);
    delay(1);
}

```
2. With millis():

```
  void stepper_run_cw(void){
  stepper_step_cw(1,0,0,0,1);
  stepper_step_cw(1,1,0,0,1);
  stepper_step_cw(0,1,0,0,1);
  stepper_step_cw(0,1,1,0,1);
  stepper_step_cw(0,0,1,0,1);
  stepper_step_cw(0,0,1,1,1);
  stepper_step_cw(0,0,0,1,1);
  stepper_step_cw(1,0,0,1,1);
}

void stepper_step_cw(uint8_t m_in1, uint8_t m_in2, uint8_t m_in3, uint8_t m_in4, uint8_t delay_time){
  if (!stepper_run){
    digitalWrite(in1, m_in1);
    digitalWrite(in2, m_in2);
    digitalWrite(in3, m_in3);
    digitalWrite(in4, m_in4);
    stepper_start = millis();
    stepper_run = 1;
  }

  if(stepper_run){
    stepper_current = millis();
    if(stepper_current - stepper_start >= delay_time){
      stepper_run = 0;
    }
  }
}

```

# Answer
> 1 votes
Maybe for the second function you want something like this:

```
 void stepper_run_cw(void){
  stepper_step_cw(1,0,0,0,1);
  stepper_step_cw(1,1,0,0,1);
  stepper_step_cw(0,1,0,0,1);
  stepper_step_cw(0,1,1,0,1);
  stepper_step_cw(0,0,1,0,1);
  stepper_step_cw(0,0,1,1,1);
  stepper_step_cw(0,0,0,1,1);
  stepper_step_cw(1,0,0,1,1);
}

void stepper_step_cw(uint8_t m_in1, uint8_t m_in2, uint8_t m_in3, uint8_t m_in4, uint8_t delay_time){
  unsigned long temp, i;
  for (i=0;i<delay_time;i++){
    temp = millis();
    while (temp == millis){};//wait for millis to change
  }
    digitalWrite(in1, m_in1);
    digitalWrite(in2, m_in2);
    digitalWrite(in3, m_in3);
    digitalWrite(in4, m_in4);
}

```

This code is also avoiding the millis overflow issue if you run your board for a long time.

Still, apart for a improved timing, there is no gain in using millis(), you still have to wait for millis to change, you might want to use a timer interrupt to do the job in background.

# Answer
> 0 votes
After working on developing the function couple times, I got a way with this function and runs smoothly too :)

Hope anyone find it useful.

```
// this library is for the 28BYJ stepper motor

  #define in1 6
  #define in2 7
  #define in3 8
  #define in4 9

  // blink
  unsigned long blink_start_millis;
  unsigned long blink_current_millis;
  unsigned long blink_period = 100;

  uint8_t stepper_masks[] = {0x80,0xc0,0x40,0x60,0x20,0x30,0x10,0x90};
  int8_t s=0;
  uint32_t stepper_start;
  uint32_t stepper_current;
  uint32_t stepper_period;
  byte stepper_run;

  void blink_pin13(void);
  void stepper_step(uint8_t *mask, uint8_t delay_time, uint8_t dir);

  void setup() {
    Serial.begin(9600);// put your setup code here, to run once:
    for(byte i=in1;i<=in4;i++){
      pinMode(i,OUTPUT);}

    pinMode(13,OUTPUT);

  }

  void loop() {
   stepper_step(stepper_masks,1,0);
    blink_pin13();

  }

  void blink_pin13(void){
      blink_current_millis = millis();
      if(blink_current_millis - blink_start_millis >= blink_period){
      digitalWrite(13, !digitalRead(13));
      blink_start_millis = blink_current_millis;
    }
  }

  void stepper_step(uint8_t *mask, uint8_t delay_time, uint8_t dir){
    if (!stepper_run){
      for(byte i=6;i<10;i++){
        digitalWrite(i, 0<(mask[s]&0x80>>i-6));
      }
      if(!dir){s++;if(s>7)s=0;}
      else {s--;if(s<0)s=7;}
      stepper_start = millis();
      stepper_run = 1;
    }

    if(stepper_run){
      stepper_current = millis();
      if(stepper_current - stepper_start >= delay_time){
        stepper_run = 0;
      }
    }
  }

```

---
Tags: code-optimization, speed, stepper-motor
---


title: ESP8266 Flash - Maximize SPIFFS size

text:
# Question
Title: ESP8266 Flash - Maximize SPIFFS size
the board i use has **1MB Flash Size**. My program however downloads 512K+ of data for processing.

Arduino Options i see are:

Ideally i would like to use 1MB of SPIFFS, is this even possible?

I don't use OTA, and compile with:

To minimise the footprint of the main sketch.

Thanks in advance.

# Answer
> 2 votes
No.

Even if you don't use OTA, your program is stored in flash. If you have 1MB of flash, there's no way you can use all 1MB for SPIFFS; that would leave no space for your program.

Here's a page showing how flash is divided up in an Arduino environment.

Even if you eliminate space for OTA images and the EEPROM, the Arduino environment will still reserve space for the sketch itself and for its wifi config and possibly a little more data.

You can never use 100% of the flash storage for SPIFFS.

---
Tags: esp8266
---


# Question
Title: How ro re-enable 32u4 USB controller after sleep mode?
I've run into quite the problem with my 32u4, I can't get it to reconnect to the computer upon wakeup from a sleep mode!

So I have an Arduino Pro Micro featuring the 32u4, and I'm also designing a project with a standalone 32u4 (I'm using the Pro Micro as a test platform before I begin building my project). It is a battery operated device with a soft-start, so I need power consumption to be a miniscule as possible (hence the sleep modes).

After learning about the registers and brushing up on some binary, putting the chip to sleep was fairly straight forward, however, I cannot get the USB interface internal to the 32u4 to 'wake back up' or reconnect to the computer. I've attached my code below. I also tested this code on my Arduino Nano and it works just fine, however with added USB features of the 32u4, I cannot get it to reconnect to the computer, and I have to reset the chip a million times to get the IDE to finally recognise it and upload something else to it.

Here is my lovely code below. All it does it upon startup, go sleep, and when interrupt on pin 2 goes low, wake the chip back up and run the blink sketch. It goes to sleep, and wakes up and runs the sketch, it just won't ever reconnect to my computer, until I do a hardware reset.

```
int btn1Pin = 2;
int led1 = 9;

// these are the 'standard' register configurations
byte _SMCR = 0; // disable sleep mode
byte _ADCSRA = 0b10000111; // re-enable ADC

int interval = 500;
int ledState = true;
unsigned long ct1 = 0;
unsigned long pt1 = 0;

void setup()
{
  pinMode(led1, OUTPUT);
  attachInterrupt(digitalPinToInterrupt(btn1Pin), wakeUp, FALLING);
  sleep();
}

void loop()
{
  ct1 = millis(); // blink something so I know you're working
  if (ct1 - pt1 >= interval)
   {
     digitalWrite(led1, ledState);
     ledState = !ledState;
     pt1 = ct1;
   }
}

void wakeUp()
{
  SMCR = _SMCR; // disable sleep mode
  ADCSRA = _ADCSRA; // re-enable ADC
}

void sleep()
{
  ADCSRA &= ~(1 << 7); // disable ADC
  SMCR |= ( 1<<2 );    // power down mode
  SMCR |= 1;           // enable sleep
  __asm__ __volatile__("sleep"); // hypnotist snaps fingers, chip is out cold!
}

```

---

**Inside AJ's brain (more research):** 32u4 Datasheet for quick reference

I added a quick led turn on in the wakeUp() ISR to ensure it was actually getting executed, and indeed it was.

The description of the USBCON register (Page 267 - 21.13.1) claims that clearing bit 7 disables and resets the USB controller. I tried another iteration of code where in sleep() I cleared bit 7, hoping that reset the controller, and in wakeUp() I set the bit to turn it back on after reset, but that didn't work. In fact, it gave me a really tough time when trying to reprogram (even though I KNOW that the wakeUp() ISR is executing and the bit had to have been reset).

After some more reading, I saw (Page 262 - 21.7.2) says that in power down mode (the sleep mode I'm using), *"the oscillator is stopped and halts all the clocks (CPU and peripherals). The USB controller 'wakes up' when:*

* *the WAKEUPI interrupt is triggered*
* *the VBUSTI interrupt is triggered."*

Okay so this makes sense, in power down mode the USB controller is stopped due to the lack of an oscillator, cool! I understand that to mean I need to trigger one of those interrupts to re-enable the USB controller. So I searched around for the first interrupt "WAKEUPI", and it appears this bit is set by hardware (Page 282), I'm guessing this means when you plug in the USB cable? I wrote a sketch to read that register, and it returned with 00010000, so I'm assumed the above statement is true. It also says setting it with software has no effect, so I left this one to explore the next interrupt, VBUSTI, which seems to be part of the automatic USB plug in detection based off of the VBUS pad. Maybe something here needs to be changed but I can't tell.

Page 266 - 21.12 talks about software USB operating modes, and the last one is "Resuming the USB interface." The 4 bullets provide to wake up are as such:

* Enable PLL
* Wait PLL lock
* Unfreeze USB clock
* Clear Resume information

I tried to do all of the above by adding this code to the wakeUp() ISR. It still didn't work :(. I know it's brutal and ISRs should be as short as possible but I gave it a go anyways.

```
  PLLCSR = _PLLCSR; // enable PLL clock
  var = bitRead(PLLCSR, 0);
  while (var != 1) {} // wait for clock to lock

  USBCON = _USBCON; // unfreeze USB clock
  UDINT = 0; // clear resume flag

```

Maybe I'm making all of this more complicated than it needs to be, I don't know! I can't get this thing to reconnect.

# Answer
You're making it too hard on yourself.

There is a method to re-start the USB, but it only works if the USB has been properly stopped - and the method that is supposed to do that is empty.

This is a little sketch that works on my Leonardo:

```
#include <LowPower.h>

void setup() {
}

void loop() {
    USBCON = 0;
    LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);

    USBDevice.attach();

    pinMode(13, OUTPUT);
    digitalWrite(13, HIGH);

    delay(10000);
    digitalWrite(13, LOW);
}

```

It disables the USB (`USBCON = 0;`), sleeps for 8 seconds, then starts the USB up again from scratch (`USBDevice.attach();`). 10 seconds later it sleeps again.

At the computer end, you get (on Linux):

```
[1242489.000014] usb 2-1.5.2: Product: USB IO Board
[1242489.000015] usb 2-1.5.2: Manufacturer: Arduino LLC
[1242489.000316] cdc_acm 2-1.5.2:1.0: ttyACM0: USB ACM device
[1242498.631563] usb 2-1.5.2: USB disconnect, device number 69
[1242507.068078] usb 2-1.5.2: new full-speed USB device number 70 using ehci-pci
[1242507.199628] usb 2-1.5.2: New USB device found, idVendor=2341, idProduct=0036
[1242507.199630] usb 2-1.5.2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[1242507.199631] usb 2-1.5.2: Product: USB IO Board
[1242507.199633] usb 2-1.5.2: Manufacturer: Arduino LLC
[1242507.200256] cdc_acm 2-1.5.2:1.0: ttyACM0: USB ACM device
[1242517.063425] usb 2-1.5.2: USB disconnect, device number 70
[1242525.495729] usb 2-1.5.2: new full-speed USB device number 71 using ehci-pci
[1242525.627634] usb 2-1.5.2: New USB device found, idVendor=2341, idProduct=0036
.... etc ....

```
> 3 votes

---
Tags: usb, sleep, arduino-pro-micro
---


# Question
Title: Can I read using an analog pin on an arduino Mega whether or not there is a high (5v) voltage on a wire from another board's digital pin?
I am making a peer-to-peer network of initiating devices and a common hub, which controls most of the hardware. It sends a number over `Serial` to Mega's `Serial1` (Mega's `Serial` is used for communicating to the computer), but as a fallback it initiates a general alarm by sending a 5v signal (using `digitalWrite(pin, HIGH)`) to the main board. In order to complete the circuit and get the read, how would I do this?

Thanks!

# Answer
> 1 votes
Yes of course you can. Better to use `digitalRead()` than `analogRead()` however.

You just need to tie the grounds of the 2 Arduinos together, and set up the pin on the Arduino you want to sense the input as INPUT or INPUT\_PULLUP. Then do a digitalRead on the pin. It will return `LOW` if the other Arduino is setting the pin LOW, and `HIGH` if the other Arduino is setting it HIGH.

And, as Juraj points out in their comment, CMOS devices like Arduinos respond to voltage, not current. Their inputs are capacitive. They react to a voltage potential, not current. (When you initially change a CMOS input from one state to another a small amount of current flows in to change the state of the capacitor and after that the only current that flows is a **very** tiny amount of leakage current through the capacitor on the input.)

---
Tags: communication, analogread, wires, digital
---


title: sensor for illegal parking detection

text:
# Question
Title: sensor for illegal parking detection
I want to create a system that will detect illegal parking. I will place the sensor s to specific locations and when a car parks there the system will send a message to local authorities. My question is if a PIR is the suitable sensor for this project.

thanks in advance.

# Answer
Don't get discouraged, there are many ways to do this, but I would rate a PIR as being one of the worst options because even a bird or a squirrel could set it off. Plus, once the car has stopped you can't detect it's presence anymore with a PIR sensor, it has to be moving. I would recommend either using something like a webcam and OpenCV for this or if you're set on using an Arduino and physical sensors, multiple laser or multiple ultrasonic sensors placed 5-10 feet apart so that they both have to trip at once for positive detection of a vehicle instead of something else. You're going to have to spend some time experimenting and tuning. If you want something very reliable and you own the place, you could always do what the public street works does and cut a loop into the pavement and install a large steel cable and use inductance, but that may be overkill. ;)

Some other ideas:

* Paint a pattern on the ground using high contrast paint and detect when the pattern is completely covered. Maybe there is something you can do with IR reflective paint and use a camera with no IR filter, this way you could make a pattern invisible to the eyes.
* A carbon monoxide detector - Detects dinosaur powered vehicles, but is nice to the environmentally conscious.

About a decade ago now I created my own parking detection using a Raspberry Pi and a webcam and some Perl code I wrote (non-opencv). I basically just detected the shadow contrast under the car and it worked very well. Originally I tried detecting red colors in the tail lights, but this was more troublesome due to other lighting in the environment. Especially at night. In my case, I didn't have direct access to set up physical sensors and lasers would have been too intrusive, so visual analysis made sense.
> 2 votes

---
Tags: arduino-uno, sensors
---


title: Arduino for loop

text:
# Question
Title: Arduino for loop
I am a beginner in Arduino programming. This is my program for 5 LEDs and 1 Button. The LEDs are supposed to light before I press the button. But the LEDs start immediately, even without pressing the button. How is it possible?

```
int sw7=7;
int timer=500;
int start=0;
int stopp=100;
void setup()
{
  for (int opin=1;opin<6;opin++)
  {
    pinMode(opin,OUTPUT);
    pinMode(sw7,INPUT);
  }
}

void loop()
{
  if (digitalRead (sw7)==LOW)
  {
    while (start<=stopp);
  }
  {
    for (int opin=1;opin<=5;opin++)
    {
      digitalWrite(opin,HIGH);
      delay(timer);
      digitalWrite(opin,LOW);
     }
  }
}

```

# Answer
> 2 votes
Several things:

You need to explicitly set your output pins to `LOW` in your setup method.

The code to set the sw7 to input should not be inside the loop.

You should probably connect your switch between sw7 and ground and use `INPUT_PULLUP` mode (in `INPUT_PULLUP` mode the line is connected to +5V through a "pull-up resistor" so that it reads HIGH until you press the button, and then it reads LOW. If you don't use either an input pull-up or pull-down resistor then the input tends to "float" and give bad readings.)

You say "The LEDs are supposed to light before I press the button. But the LEDs start immediately, even without pressing the button."

I'm not sure what you mean. What do you want to happen, exactly? Do you want the LEDs to be lit steadily, and then turn off or flash when you press the button?

The code below will turn off all the LEDs initially, then toggle between off and flashing on each (debounced) button press. Switch the value of `idleLEDState` to HIGH if you want the LEDs to be lit when they are not flashing.

```
#define flashDelay 50 //Delay between on and off state for LEDs
#define switchBounceDelay 100

uint8_t idleLEDState = LOW; //Change to HIGH
                            //if you want the LEDs to be lit when not flashing
bool flashLEDs = false;
bool ledsOn = false;
unsigned long nextFlashTime = 0;
unsigned long nextSwitchCheckTime = 0;

void setup() {
  pinMode(sw7, INPUT_PULLUP); //Connect the switch between sw7 and ground
  for (int opin=1;opin<6;opin++)
  {
    pinMode(opin,OUTPUT);
    digitalWrite(opin, idleLEDState);
  }
}

void loop() {

  //If it's time to check the switch, and it's being pulled LOW, toggle flashLEDs
  if (mills() > nextSwitchCheckTime && digitalRead(sw7) == LOW) {
    flashLEDs = !flashLEDs;
    nextSwitchCheckTime = millis() + switchBounceDelay;
  }

  if (!flashLEDs) {
    //IF we're not supposed to flash the LEDs, set them to their idle state
    for (int opin=1;opin<6;opin++) {
        digitalWrite(opin, idleLEDState);
     }
  } else if millis() > nextFlashTime {
    nextTime = millis() + flashDelay;
    ledsOn = !ledsOn;
    for (int opin=1;opin<6;opin++) {
        uint8_t newState = ledsOn ? HIGH : LOW;
        digitalWrite(opin, newState);
     }
}

```

I banged out the code above in the Stack Exchange editor. It likely contains a few typos. Please exert some effort to fix it and adapt it to your needs before posting back "Your code didn't work. I got error XYZ."

# Answer
> 0 votes
This is a sketch according to your requirements:

```
// pin mapping
int pin_map[] = {
  1,  // 0: led in pin 1
  2,  // 1: led in pin 2
  3,  // 2: led in pin 3
  4,  // 3: led in pin 4
  5,  // 4: led in pin 5
  7   // 5: button (pull-up)
};

int timeout_ms = 500;
int blink_ms = 100;

void setup()
{
  // setup pins
  for (int opin = 0; opin < 5; opin++) pinMode(pin_map[opin], OUTPUT);
  pinMode(pin_map[5], INPUT_PULLUP);

  // wait for activation
  while (millis() < timeout_ms)
  {
    // activate by button (off:pull-up on:GND)
    if (digitalRead (pin_map[5]) == LOW) break;
  }
}

void loop()
{
  for (int opin = 0; opin < 5; opin++)
  {
    // toggle LED
    int pin = pin_map[opin];
    pinMode(pin, !digitalRead(pin));
  }

  delay(blink_ms);
}

```

You will need avoid delay() usage if you need asynchronous tasks. Probably, you should study C language and practice with some hundred of sketchs to improve your code skills.

---
Tags: arduino-uno
---


title: ATtiny85 LM75 I2C

text:
# Question
Title: ATtiny85 LM75 I2C
I would like to read temperature from a LM75 using the **ATtiny85** running a core by SpenceKonde and utilizing the TinyWireM library.

My Logic Analyzer does not pick up any I2C communication, when I connect it to an Arduino Nano, it works fine. On the Nano, there is no need for **TinyWireM** so that's a big difference.

Therefore I conclude that the ATtiny85 is not speaking the right I2C slang to the device.

I also use SoftwareSerial and this works fine. It is visible on the Logic Analyzer.

The LM75 library is not made for ATtiny or TinyWireM, I replace the `Wire` references in-place by `TinyWireM` reference.

Should it be possible to 'just' replace Wire by TineWireM in the library and could I expect some meaningful data this way?

**\[updated code\]**

```
#include <Arduino.h>
#include <TinyWireM.h>
#include <LM75.h>
#include <SoftwareSerial.h>

#define SOFTWARE_SERIAL_TX_PIN 3
#define SOFTWARE_SERIAL_RX_PIN -1

LM75 sensor;
SoftwareSerial mySerial(SOFTWARE_SERIAL_RX_PIN, SOFTWARE_SERIAL_TX_PIN);

void setup() {
  TinyWireM.begin();
  mySerial.begin(2400);
  mySerial.print("Starting..");
}

void loop() {
delay(1000);
mySerial.println("SO");
mySerial.println(sensor.temp());
delay(1000);
}

```

# Answer
The current ATtiny core includes a Wire library for the USI hardware used in the Tinys. This way you don't need to modify the LM75 library which is error prone.
> 2 votes

# Answer
This is an old post I know but hopefully this information is helpful to someone. I modified the lm75 library by replacing all instances of Wire with TinyWire and as above no go, but turns out a 10k pull up on SCL / SDA is a necessity for the attiny 85. For whatever reason i2c works fine on an arduino UNO without pull ups but not on an attiny 85. So in short, add pull up resistors and it works. Bonus potato grade picture of attiny, LM75 and display module showing temperature.
> 1 votes

---
Tags: i2c, attiny
---


# Question
Title: Motor driver not working properly in case we connect motor to it
We are making a Bluetooth controlled RC car. when we connect our motor (moderate power) to motor driver then Bluetooth module is automatically disconnected after taking initial command from Arduino code ,and if we connect our led (low power) instead of Motors to motor driver then project is working fine. what could be the possible problem?

# Answer
> -1 votes
I used an external battery to supply the motor, and a BJT as a switch to trigger it (Base connected to Arduino).

---
Tags: arduino-uno
---


# Question
Title: Arduino IDE Permision Denied For Upload, Ubuntu
I am having issues uploading to my Arduino from the IDE on Ubuntu 18.04. The error message I have received is:

> Arduino: 1.6.10 (Linux), Board: "Arduino/Genuino Uno" avrdude: ser\_open(): can't open device "/dev/ttyUSB0": Permission denied

I have checked other questions similiar to this one and have tried adding myself to the dialout group running:

```
sudo usermod -a -G dialout username

```

and added permission to write:

```
sudo chmod a+rw /dev/ttyUSB0

```

After, when I run:

```
ls -l /dev/ttyUSB0

```

I get:

```
crw-rw-rw- 1 username dialout 188, 0 jūl  2 16:09 /dev/ttyUSB0

```

However,I still get the same error message from the IDE.

Any help would be greatly appreciated!

# Answer
Arduino has added a script to the install to fix this problem. I found it after much annoyance trying to get it to work with all these suggestions.

In the arduino-1.8.8-linuxarm.tar.xz file that you download is a script called `arduino-linux-setup.sh`

run that from commandline with your user name `./arduino-linux-setup.sh <username>`

It'll ask for the root password, and then ask you to reboot. After that you won't have any more port trouble.
> 5 votes

# Answer
As mentioned on the official guide for Linux, you need to run

`sudo usermod -a -G dialout <username>`

with the `<username>` replaced with the username of your system. After running this, log out and log in (or in some cases reboot the computer) and you should be good to go.
> 4 votes

# Answer
When you run

> ls -l /dev/ttyUSB0

you have

```
crw-rw-rw- 1 username dialout 188, 0 jūl  2 16:09 /dev/ttyUSB0

```

**The Problem** is you have `the dev` as `<username>`, try to change to as root

```
sudo chown root:dialout -R /dev/

```

**Note:**

One thing after your plug your USB, check your port with follow

```
ll /dev/tty*

```

if you can see my port as ttyUSB0 or with difference name (i.g ttyUSBx / ttyACMx ).
and then try to compile your sketch with following,

```
cd /path/your/arduino/installation/
$ARDUINO-DIR(pwd)
cd /path/your/sketch/
$ARDUINO-INO/arduino --verify sketch.ino --board arduino:avr:uno --port /dev/ttyUSB0 --verbose //compile your sketch.ino with arduino uno board.

```

Hope this helps.
> 2 votes

---
Tags: arduino-uno, arduino-ide, linux
---


# Question
Title: Connecting TFT Display MI0283QT-9A to ESP32
I have purchased a MI0283QT-9A TFT display (https://download.mikroe.com/documents/add-on-boards/other/display/tft-proto/tft-proto-manual-v200.pdf) which is driven by the ILI9341 display controller.

I've managed to find the following board specification: http://pub.ucpros.com/download/tft\_320\_240\_mi0283qt\_9a\_v1\_3\_spec.pdf

First of all, the pins are named differently from all the examples I can find for connecting it to my ESP32 microcontroller. For example, the TFT specs describe:

```
33 SDO Serial Output Signal
34 SDI Serial Input Signal
35 RD Read execution control pin
36 WRX(D/CX) Write execution control pin ; Serial Register select s Signal
37 D/CX(SCL) Register select signal; Serial Interface Clock
38 CSX Chip Select Signal
39 TE Tearing effect out pin synchronize MPU to frame writng

```

But this Adafruit ILI9341 example (https://github.com/adafruit/Adafruit\_ILI9341/blob/master/examples/graphicstest/graphicstest.ino) talks about CS, DC, MOSI, CLK, RST, and MISO.

I think these map as follows, **can anyone confirm that**?

```
ESP32 = TFT
--------------
DC    = RS
CLK   = WR, although maybe it should connect to DC???
CS    = CSX
MOSI  = SDI
RST   = RST
MISO  = SDO

```

I'm really unsure about the first two!

Second, in the PDF it refers to note 1 on page 11:

So as far as I can tell, I need to set the voltage high/low on the four IM\* pins, depending upon the interface I want to use. So the second question is **which interface does the Adafruit ILI9341 library use**?

# Answer
It sounds like you want a 4-wire 8-bit serial SPI compatible interface. To get that you have to set the IMx pins to the right state to enable that interface. That means:

* IM0 = LOW
* IM1 = HIGH
* IM2 = HIGH
* IM3 = HIGH

You can hard-wire those to GND for LOW and +3.3V for HIGH.

That will then configure it to work in the right mode for you, where it gives you access to the following pins:

```
| Display  | ESP32   | Function                    |
|----------|---------|-----------------------------|
| SCL (RS) | SCK     | Serial clock                |
| SDI      | MOSI    | Serial data Master -> Slave |
| SDO      | MISO    | Serial data Slave -> Master |
| D/CX (WR)| DC      | Data / Command register sel |
| CSX      | CS      | Chip Select (Active Low)    |
| RST      | RST     | Reset                       |

```
> 1 votes

# Answer
Same (TFT proto board) tested Arduono DUE.

Pins IM1-3 HI, IM0 LO. (4-wire 8-bit data serial interface)

SDI - MOSI, SDO - MISO,RS - CLK, RD - HI, WR - D9, CS - D10, Reset - Reset (D8)

Driver UTFT myGLCD (ILI9341\_S5P, MOSI, SCK, 10,8,9);

or

```
// For the Adafruit shield, these are the default.
#define TFT_DC 9
#define TFT_CS 10
Adafruit_ILI9341 tft = Adafruit_ILI9341 (TFT_CS, TFT_DC);

```

Backlight needs resistor!
> 1 votes

---
Tags: esp32, tft
---