# Question
Title: Keyboard.println missing characters when I print long strings
The topic is pretty straight forward: When I use `Keyboard.println()`, it sends short (up to 30-ish) strings just fine, but when I get up around 100 characters there are random characters missing. "Random" - meaning it is not all the time, it's somewhat consistently the same characters missing though.

I've checked and the data is arriving at the Arduino correctly (over web service), but once it shows back up in the notepad, it's missing random stuff.

Any thoughts or suggestions?

Edit: Examples as requested:
I'm sending...

> cheat SpawnDino Blueprint'/Game/PrimalEarth/Dinos/Pelagornis/PelaCharacter\_BP.Pela\_Character\_BP' 10 1 1 10

And what's printing is...

> cheat SpawnDino Blueprint'/Game/PRIMALEarth/Dinos/Pelgornis/PelaCharacter\_BP.Pela\_Character\_bP' 10 1 1 10

I've actually noticed now that it's changing capitalization too, the BP to bP and Primal to PRIMAL.

# Answer
> 1 votes
I'd bet the issue is overflowing the keyboard buffer of the device you're talking to. On Windows, you can change a registry value to make the buffer larger:

http://www.windowsnetworking.com/kbase/WindowsTips/WindowsNT/RegistryTips/Hardware/KeyboardBufferSize.html

(and in fact, the Windows keyboard buffer is 100 characters by default.)

The reason the capitalization is becoming strange is because the device missed the shift-down or shift-up event, so it's using whatever it would use if the shift key wasn't pressed or released.

The best solution is to avoid sending so much: break it down and send a little at a time as Gerben said.

---
Tags: arduino-leonardo
---


title: Why use a motor driver board?

text:
# Question
Title: Why use a motor driver board?
I'm just getting into electronics in general and I'm confused a bit as to why I'd want/need to use a motor driver board instead of just setting up my own transistor/diode/etc when attempting to power and control a DC motor.

Any chance someone could clarify the point to using a motor driver board instead (assuming there is another option as I think there to be)?

# Answer
A motor driver board is just a convenient way of creating what is known as a "H Bridge". This is an arrangement of 4 (or more, but 4 primary) transistors.

You can make it yourself with discrete transistors, but it is simpler to just use a pre-made chip.

A H Bridge gives you greater control over a motor than a single transistor alone. It allows you to control the direction, which you can't do with a single transistor, and it also gives you access to braking modes where the motor becomes harder to turn thus assisting in slowing down the load.

With a single transistor you can turn the motor on and off (or vary the speed if you use PWM) but that is all.

simulate this circuit – Schematic created using CircuitLab
> 5 votes

# Answer
A couple of extra reasons. If you have low power controllers (like computers), it keep the low power devices away from higher power motor drivers, electronic noise etc.

If you use AC, it can also keep the issues of driving inductive loads away from your micro-electronics (phase and power factor issues).
> 0 votes

---
Tags: arduino-uno
---


title: Temperature sensor and LCD

text:
# Question
Title: Temperature sensor and LCD
I have a project which uses a DS18B20 temperature sensor and an LCD with an I2C interface on it. I have connected the sensor to my micro-controller (the DS18B20 has a 12-bit digital output) to the ATmega16 PD17, but as I try to print my values on the terminal the sensor output a really high value in decimal. Here is part of the code (and yes everything is working fine, this is a home-made Arduino):

```
DDRD &= 0x00;
PORTD |=  0x00;
ds18b20_init(&PORTD, 20, 30, DS18B20_12BIT_RES);
int temperature_sensor_output =  (float)ds18b20_temperature(&PORTD);
printf("Temperature: %d  ", temperature_sensor_output);
delay_ms(500);

```

ds18b20\_init is the Dallas function for initializing the module. ds18b20\_temperature returns a float value of the temperature

From this code it just prints:

> Temperature: 51603

If I change %d to %f it prints:

> Temperature: without any value

I do not understand where I may have missed some things.

# Answer
Without more detail about the system, I won't understand what `printf()` does; in non-embedded systems, `printf()` writes to `stdout` by default, but Arduino systems typically don't use such a device.

That aside, `%d` is the proper format code for printing an integer value, and `%f` is proper for a float or double. If you attempt to print an integer value like `temperature_sensor_output` under a `%f` format code, either the compiler will complain or the integer pattern of bits (plus perhaps two additional random bytes) will be interpreted as if it is a float or double pattern of bits. No type cast occurs within `printf()`. If you want to use a `%f` format code, pair it up with a float-type variable.

If, as you say, `ds18b20_temperature()` returns a float, then the type cast `(float)ds18b20_temperature(&PORTD)` will have no effect. Generally, casts convert data from one form to another, or in some cases declare that data has a given form. Going from float to float doesn't change anything.

In a C statement like `a=b`, if `b` has a type that's different from that of `a`, the `b` value will be cast to the type of `a`. Thus, the float value on the right hand side of

```
int temperature_sensor_output =  (float)ds18b20_temperature(&PORTD);

```

will be converted to an integer value and stored into the integer variable `temperature_sensor_output`.
> 1 votes

# Answer
Have you looked at the raw return value from ds18b20\_temperature(), without casting it to float and then to int, perhaps in hex? It may not be your printing code that's causing trouble but the value returned from the function. If the function *is* returning something equivalent to 51603, it is already bogus. DS18b20s temperature values are in 16-ths of a degree (Celsius, assuming the routine didn't convert it). 51603/16 is still an unreasonable value, not to mention that viewed as as a 16-bit int, the sign bit is set. Is it truly negative? Did something overlow?

I think you need to look at what that function is doing.
> 0 votes

---
Tags: avr, atmega16u2, ds18b20
---


# Question
Title: Can I detect with software when a PIR sensor is physically connected to Arduino?
I'm creating a circuit using an Arduino Nano + ESP8266 to allow LED remote (via mobile app) activation and configuration (RGB colour, timeout, etc.). The circuit also has an optional PIR sensor to switch on the LED when someone enters the room.

I'd like the circuit to behave differently when the PIR is physically connected to the Arduino (i.e. to light the LED in a different colour) but I have no idea of how detect if the sensor is physically connected to the circuit.

I tried reading the value of the Arduino PIN but (obviously) the signal is LOW whether nothing is detected by the PIR or is not physically connected.

I have two different PIR detectors that I can use for the project:

1. Arduino Compatible PIR Motion Detector (Description)
2. DFRobot PIR Detector (Description, Schematic)

Thank you for your time. If there is missing information in my question, please tell me and I will add it.

# Answer
The PIR sensor I have will overpower the internal pull-up resistor of the ATmega328P used on the Arduino Nano. This means if you turn on the pull-up and then get a read of LOW you know something is connected to that pin because the unconnected pin will always read HIGH with the pull-up on. With this approach you can get false negatives because the pin will also read HIGH if the PIR is triggered but you won't ever get false positives for PIR sensor detection. This means you can't rely on just doing a single test in `setup()` because the PIR might be triggered then so you will need to repeatedly run the test until the PIR sensor is detected. Example sketch:

```
int PIRpin = 2;    //the input pin for the PIR sensor
boolean PIRconnected = false;

void setup() {
  Serial.begin(9600);
  pinMode(PIRpin, INPUT);
}

void loop() {
  if (PIRconnected == false) {
    pinMode(PIRpin, INPUT_PULLUP);
    if (digitalRead(PIRpin) == LOW) {
      Serial.println(F("PIR sensor detected"));
      PIRconnected = true;
    }
    pinMode(PIRpin, INPUT);  //turn off the internal pull-up to reduce power consumption
  }
  Serial.println(digitalRead(PIRpin));
  delay(500);
}

```
> 2 votes

---
Tags: sensors, arduino-nano
---


# Question
Title: Why are my sensors not working (the reaction time is so slow)?
```
//testing the light sensor;
int sensor=A0; // setting as input is by default;
int sensorval;
int pin=13;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(pin,OUTPUT);
  pinMode(sensor,INPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
  sensorval=analogRead(sensor);
  Serial.println(sensorval);
  if(sensorval>900)
    digitalWrite(pin,HIGH);
  else  digitalWrite(pin,LOW);
    delay(1000);
}

```

I am using a photocell, a temperature sensor and a potentiometer with an Arduino Uno and it always gives me `1023 0 1023 0 1023 0 1023 ......`. All my wires are connected properly and I tried all this stuff online and they are working correctly.

# Answer
> 1 votes
Have you tried with a different trimmer?

I dont seem to be able to find any issue with your code or your schematic, so can you please cross verify that the trimmer is not spoilt.

Can you also check if, when A0 is left floating (nothing connected) it give a random value.

# Answer
> 1 votes
you should internalize value of sensorval equal to zero. You do not require set analog pin. you want get data quickly then reduce delay time because 1 second quite high.So, make it **500** mili second.

---
Tags: arduino-uno, sensors, potentiometer, photoresistor
---


title: Servo control using DIP switch

text:
# Question
Title: Servo control using DIP switch
I am pretty new to Arduino and programming too. I want to sweep a servo using DIP switch. At the moment, I use 4 position DIP switch. To each of the switches, I want to set the number of times the servo has to run. Eg., Pos 1 of DIP switch says, sweep for 5 times. Pos 2 says, sweeps for 10 times etc.

I wrote the following code:

```
#include <Servo.h>

Servo myservo;
int pos = 0;
int count = 0;   // might need later
int runXTimes = 0;

#define S1 2
#define S2 3
#define S3 4
#define S4 5

int s1state = HIGH;
int s2state = HIGH;
int s3state = HIGH;
int s4state = HIGH;

void setup() {
   myservo.attach(9);
   pinMode(S1, INPUT_PULLUP);
   pinMode(S2, INPUT_PULLUP);
   pinMode(S3, INPUT_PULLUP);
   pinMode(S4, INPUT_PULLUP);
   pinMode(9, OUTPUT);
}

void loop() {

   s1state = digitalRead(S1);
   s2state = digitalRead(S2);
   s3state = digitalRead(S3);
   s4state = digitalRead(S4);

   // Servo control through Switch 1
   if (s1state == LOW) {     // read the input pin
      for (int runXTimes = 0; runXTimes < 5; runXTimes++) {    // Servo to     sweep for 5 times
         for (pos = 0; pos <= 80; pos += 1)  // goes from 0 degrees to 80 degrees in steps of  degree

         {
            myservo.write(pos);              // tell servo to go to position in variable 'pos'
            delay(5);
         }

         for(pos = 80; pos>=0; pos-=1)     // goes from 80 degrees to 0 degrees
         {
            myservo.write(pos);              // tell servo to go to position in variable 'pos'
            delay(5);
         }

      }

   }

   // Servo control through Switch 2. Used servo detach here
   else if (s2state == LOW) {  // read the input pin
      for (int runXTimes = 0; runXTimes < 10; runXTimes++) {  // Servo to sweep for 10 times
         for (pos = 0; pos <= 80; pos += 1)  // goes from 0 degrees to 80 degrees in steps of  degree
         {
            myservo.write(pos);              // tell servo to go to position in variable 'pos'
            delay(5);
         }

         for(pos = 80; pos>=0; pos-=1)     // goes from 80 degrees to 0 degrees
         {
            myservo.write(pos);              // tell servo to go to position in variable 'pos'
            delay(5);
         }

      }
      myservo.detach();
   }

   // Servo control through Switch 3
   else if (s3state == LOW) {  // read the input pin
      for (pos = 0; pos <= 80; pos += 1)  // goes from 0 degrees to 80 degrees in steps of  degree
      {                                  //
         myservo.write(pos);              // tell servo to go to position in variable 'pos'
         delay(5);
      }

      for(pos = 80; pos>=0; pos-=1)     // goes from 80 degrees to 0 degrees
      {
         myservo.write(pos);              // tell servo to go to position in variable 'pos'
         delay(5);
      }
   }

   // Servo control through Switch 4
   else if (s4state == LOW) {  // read the input pin
      for (pos = 0; pos <= 80; pos += 1)  // goes from 0 degrees to 80 degrees  in steps of  degree
      {
         myservo.write(pos);              // tell servo to go to position in variable 'pos'

         delay(5);
      }

      for(pos = 80; pos>=0; pos-=1)     // goes from 80 degrees to 0 degrees
      {
         myservo.write(pos);              // tell servo to go to position in variable 'pos'
         delay(5);
      }

   }
}

```

The actions that happen with the above code are: 1) Servo control through Switch 1 - If I switch ON (0) and then OFF (1) immediately, the servo sweeps for 5 times. Works more like a button switch. If I switch ON and OFF (immediately) again, I am able to sweep 5 times again. But, if I leave the switch in 1, the sweep does not stop after 5 times.
2) Servo control through Switch 2: If I switch ON, the servo sweeps for 10 times and stops as per my interest. But, if I change the switch to 0 and 1 again, the sequence does not start. In fact, no other switch works. I need to power OFF the Arduino to run the program again. 3) Servo control through Switch 3 (= switch 4): If my switch is 1, the servo sweeps. If my switch is 0, the servo stops.

Could you please suggest: 1) How to write the code so that my servo sweeps only for the set number of times even when the switch is in 1 always or whenever I toggle between 0 and 1? 2) I do not want to use serial communication (or typically a PC). Is it possible to interface a 7-segment or LCD to display the number of sweeps completed or still left.

Thank you in advance.

# Answer
This is imagination-based since I can't test it myself at this moment, but feel free to ask if something is not right.

```
int readswitch()
{
 int S1,S2,S3,S4;
 uint8_t data = 255;
 data |= digitalRead(S4)<<3;
 data |= digitalRead(S3)<<2;
 data |= digitalRead(S2)<<1;
 data |= digitalRead(S1)<<0;

  if (data==0b11111110) return 1; else
  if (data==0b11111101) return 2; else
  if (data==0b11111011) return 3; else
  if (data==0b11110111) return 4; else
  //add another condition here if you want
  return 0;
}

int laststate = 0;
int state = 0;
int rotation;

void setup()
{
  //setup here, including LCD initialization
  //..
  //..
  //..
}

void updateLCD(int x,int y)
{
  lcd.clear();
  //displaying pin status
  lcd.print("dip : ");
  lcd.print(x,DEC);
  lcd.print(" rot : ");
  lcd.print(y,DEC);
}

void loop()
{
  state = readswitch();
  if (state!=laststate)
  {
    if (state == 1)
    {
      rotation = 5;
      for (int i = 0; i< rotation; i++)
        {
         //update lcd
         updateLCD(state,(rotation-i));

         //.. servo rotation
         //..
        }
      //...
    } else

    if (state == 2)
    {
      //do what you want here if switch 2 == LOW
      //...
    } else

    if (state == 3) //switch 1 == LOW
    {
      //do what you want here if switch 3 == LOW
      //...
    } else

    if (state == 4) //switch 1 == LOW
    {
      //do what you want here if switch 4 == LOW
      //...
    }
  }
  laststate = state;

}

```

For more information about LCD, you can refer to this documentation
> 1 votes

# Answer
If you put the sweep-code in the setup function, it would execute once (because setup() is only called once) and you would see what you expected.

But, as it is in the loop() function, it executes each time the loop() function executes - that is the point of the loop() function. As another alternative, you could put an infinite- or forever loop

```
for(;;)
   ;    // program hangs here forever

```

at the end of the loop() function to prevent it returning and getting called again. Either way, you would see a single pass over the steps you coded.
> 0 votes

# Answer
Your switch 2 code includes a myservo.detach() at the end which prevents any further server code from operating.

If you want the switch 1 code to execute only once, you could add a myservo.detach() to the block.

You also seem to want to recycle for the appropriate number of times if you clear the switch. For this, you may want to myservo.attach(9) when all the switches are open.

Alternately, you could avoide the detach() and attach() by adding a one-shot flag to the conditionals, set it inside the conditional, and clear it when the switches are clear.

For example:

```
   if (!s1state & !s2state & !s3state & !s4state) armed = 1;
   ...

   if (armed & s1state == LOW) {     // read the stored input pin value
       armed = 0;
       ...

```
> 0 votes

---
Tags: programming, servo
---


# Question
Title: Using MMA8451 accelerometer to count steps
I'm trying to use an Adafruit MMA8451 accelerometer to create a pedometer-type device that counts steps. I'd like to initiate a counter that says "if the x-axis readout is \> some threshold, add 1 to the counter" so that once the counter reaches a certain point, I'll be able to trigger a separate event (like an LED turning on). I'm an Arduino beginner, and would appreciate any pointers in the right direction as I work through this.

I'm using the Sparkfun Redboard and the Adafruit MMA8451, and wrote a loop to check whether the x-axis readout was over 5. If it's over 5, I want it to add 1 to the accumulator. However, it's accumulating 1 each readout regardless of what the 'x' reading actually is. Can anyone tell what I'm doing wrong? A nudge in the right direction would be much appreciated.

Code is here:

```
/**************************************************************************/
int lastStepCount = 0;
int accum = 0;

#include <Wire.h>
#include <Adafruit_MMA8451.h>
#include <Adafruit_Sensor.h>

Adafruit_MMA8451 mma = Adafruit_MMA8451();

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

  Serial.println("Adafruit MMA8451 test!");

  if (! mma.begin()) {
    Serial.println("Couldnt start");
    while (1);
  }
  Serial.println("MMA8451 found!");

  mma.setRange(MMA8451_RANGE_2_G);

  Serial.print("Range = "); Serial.print(2 << mma.getRange());
  Serial.println("G");

}

void loop() {
  // Read the 'raw' data in 14-bit counts
  mma.read();
  Serial.print("X:\t"); Serial.print(mma.x);
  Serial.print("\tY:\t"); Serial.print(mma.y);
  Serial.print("\tZ:\t"); Serial.print(mma.z);
  Serial.println();

  /* Get a new sensor event */
  sensors_event_t event;
  mma.getEvent(&event);

  /* Display the results (acceleration is measured in m/s^2) */
  Serial.print("X: \t"); Serial.print(event.acceleration.x); Serial.print("\t");
  Serial.print("Y: \t"); Serial.print(event.acceleration.y); Serial.print("\t");
  Serial.print("Z: \t"); Serial.print(event.acceleration.z); Serial.print("\t");
  Serial.println("m/s^2 ");

  /* initiate for loop to count movement— this is the piece I'm having trouble with */
  if (event.acceleration.x >= 5);
    accum = accum + 1;
  Serial.print("X Counter: "); Serial.print(accum);

  /* Get the orientation of the sensor */
  uint8_t o = mma.getOrientation();

  switch (o) {
    case MMA8451_PL_PUF:
      Serial.println("Portrait Up Front");
      break;
    case MMA8451_PL_PUB:
      Serial.println("Portrait Up Back");
      break;
    case MMA8451_PL_PDF:
      Serial.println("Portrait Down Front");
      break;
    case MMA8451_PL_PDB:
      Serial.println("Portrait Down Back");
      break;
    case MMA8451_PL_LRF:
      Serial.println("Landscape Right Front");
      break;
    case MMA8451_PL_LRB:
      Serial.println("Landscape Right Back");
      break;
    case MMA8451_PL_LLF:
      Serial.println("Landscape Left Front");
      break;
    case MMA8451_PL_LLB:
      Serial.println("Landscape Left Back");
      break;
  }
  Serial.println();
  delay(500);

}

```

\**Update: the output I'm getting is as follows. The "X Counter" accumulates even when the x-reading is well below 5...not sure what's going on:

```
X:  1Adafruit MMA8451 test!
MMA8451 found!
Range = 2G
X:  144 Y:  50  Z:  4052
X:  0.34    Y:  0.11    Z:  9.66    m/s^2
X Counter: 1Portrait Up Front

X:  138 Y:  62  Z:  4052
X:  0.34    Y:  0.11    Z:  9.70    m/s^2
X Counter: 2Portrait Up Front

X:  0   Y:  48  Z:  4040
X:  -0.02   Y:  0.11    Z:  9.67    m/s^2
X Counter: 3Portrait Up Front

X:  -780    Y:  106 Z:  3814
X:  -1.80   Y:  0.25    Z:  9.11    m/s^2
X Counter: 4Portrait Up Front

X:  -510    Y:  106 Z:  4008
X:  -1.46   Y:  0.20    Z:  9.68    m/s^2

```

# Answer
Change your `if` statement - remove `;` (semicolon) from the end.

Use this:

```
if (event.acceleration.x >= 5)
accum = accum + 1;

```

Notice there is no semicolon after if statement
> 2 votes

---
Tags: programming, sensors, sketch, adafruit, accelerometer
---


# Question
Title: ESP8266 sends webpage to client, but html codes appears in browser instead of webpage?
I am using ESP8266 with Arduino MEGA. ESP8266 is powered 3.3v via voltage divider, which is taking 5v from arduino and converting it down to 3.3v with the help of 5K and 10K resistors. AT commands seems to be working OK. I am using SD\_card reader and kept my index.html file in SD\_card. I am able to make a successful connection and esp also sends the whole index.html file, But the issue is my browser does not shows the page in html format, instead the whole html code appears on the browser. Can anyone help me to sort this issue ? Herez the whole code;

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

     #define SSID "Maxcotec"   // change this to match your WiFi SSID
     #define PASS "qamar0334" // change this to match your WiFi password
     #define PORT "80"      // using port 80 by default
    #define DEBUG true
     #define BUFFER_SIZE 1024
     char buffer[BUFFER_SIZE];
    //SoftwareSerial Serial2(2,3); // make RX Arduino line is pin 2, make TX Arduino line is pin 3.
                                 // This means that you need to connect the TX line from the esp to the Arduino's pin 2
                                 // and the RX line from the esp to the Arduino's pin 3
    File webFile, CSS_file;
    String webpage;
     // By default we are looking for OK\r\n
     char OKrn[] = "OK\r\n";
     byte wait_for_esp_response(int timeout, char* term=OKrn) {
      unsigned long t=millis();
      bool found=false;
      int i=0;
      int len=strlen(term);
      // wait for at most timeout milliseconds
      // or if OK\r\n is found
      while(millis()<t+timeout) {
       if(Serial2.available()) {
        buffer[i++]=Serial2.read();
        if(i>=len) {
         if(strncmp(buffer+i-len, term, len)==0) {
          found=true;
          break;
         }
        }
       }
      }
      buffer[i]=0;
      Serial.print(buffer);
      return found;
     }

    void setup()
    {
      Serial.begin(9600);
      Serial2.begin(115200); // your esp's baud rate might be different

       setupWiFi();
      // print device IP address
      Serial.print("device ip addr:");
      //esp.println("AT+CIFSR");

      //sendData("AT+RST\r\n",2000,DEBUG); // reset module
      //sendData("AT+CWMODE=2\r\n",1000,DEBUG); // configure as access point
      sendData("AT+CIFSR\r",1000,DEBUG); // get ip address
      sendData("AT+CIPMUX=1\r",1000,DEBUG); // configure for multiple connections
      sendData("AT+CIPSERVER=1,80\r",1000,DEBUG); // turn on server on port 80

        // initialize SD card
        Serial.println("Initializing SD card...");
        if (!SD.begin(53)) {
            Serial.println("ERROR - SD card initialization failed!");
            return;    // init failed
        }
        Serial.println("SUCCESS - SD card initialized.");
        // check for index.htm file
        if (!SD.exists("index.htm")) {
            Serial.println("ERROR - Can't find index.htm file!");
            return;  // can't find index file
        }
        Serial.println("SUCCESS - Found index.htm file.");

             // send web page
        webFile = SD.open("index.htm");        // open web page file
        if (webFile) {
            while(webFile.available()> 0) {
                //client.write(webFile.read()); // send web page to client
               char ch = webFile.read(); // Read a character
               webpage += ch; // Add it
            }
            webFile.close();
        }
         Serial.print("file contents>>>");
         //Serial.println(webpage);
         //delay(20000);
    }

    void loop()
    {
      if(Serial2.available()) // check if the esp is sending a message
      {
        /*
        while(Serial2.available())
        {
          // The esp has data so display its output to the serial window
          char c = Serial2.read(); // read the next character.
          Serial.write(c);
        } */

        if(Serial2.find("+IPD,"))
        {
         delay(1000);

         int connectionId = Serial2.read()-48; // subtract 48 because the read() function returns
                                               // the ASCII decimal value and 0 (the first decimal number) starts at 48

         //String webpage = "<h1>Hello</h1><h2>World!</h2><button id=\"11\">Toggle Pin 11</button>";//<button>LED1</button>";

         //Serial.print("file contents>>>");
         //Serial.println(webpage);
         //delay(20000);
         String cipSend = "AT+CIPSEND=";
         cipSend += connectionId;
         cipSend += ",";
         cipSend +=webpage.length();
         cipSend +="\r\n";

         sendData(cipSend,1000,DEBUG);
         sendData(webpage,1000,DEBUG);

         //webpage="<button>LED2</button>";

    //     cipSend = "AT+CIPSEND=";
    //     cipSend += connectionId;
    //     cipSend += ",";
    //     cipSend +=webpage.length();
    //     cipSend +="\r\n";
    //
    //     sendData(cipSend,1000,DEBUG);
    //     sendData(webpage,1000,DEBUG);

         String closeCommand = "AT+CIPCLOSE=";
         closeCommand+=connectionId; // append connection id
         closeCommand+="\r\n";

         sendData(closeCommand,3000,DEBUG);
        }
      }
    }

    void setupWiFi() {
      // try empty AT command
      Serial2.println("AT");
      wait_for_esp_response(2000);
      // set mode 1 (client)
      Serial2.println("AT+CWMODE=1");
      wait_for_esp_response(2000);
      // reset WiFi module
     /*
      esp.print("AT+RST\r\n");
      wait_for_esp_response(3000);
      delay(5000);
      */
      // join AP
      Serial2.print("AT+CWJAP=\"");
      Serial2.print("xxxxxxx");
      Serial2.print("\",\"");
      Serial2.print("xxxxxxx");
      Serial2.println("\"");
      // this may take a while, so wait for 5 seconds
      wait_for_esp_response(5000);
      Serial2.println("AT+CIPSTO=30");
      wait_for_esp_response(1000);
      // start server
      Serial2.println("AT+CIPMUX=1");
      wait_for_esp_response(1000);
      Serial2.print("AT+CIPSERVER=1,"); // turn on TCP service
      Serial2.println(PORT);
      wait_for_esp_response(1000);
     }

    String sendData(String command, const int timeout, boolean debug)
    {
        String response = "";

        Serial2.print(command); // send the read character to the Serial2

        long int time = millis();

        while( (time+timeout) > millis())
        {
          while(Serial2.available())
          {

            // The esp has data so display its output to the serial window
            char c = Serial2.read(); // read the next character.
            response+=c;
          }
        }

        if(debug)
        {
          Serial.print(response);
        }

        return response;
    }

```

And this is what I am getting in web browser;

I am using Opera browser but I have tried in Chrome and firefox aswell. when I open this index.html page in my laptop with the same browser, it opens perfectly.

# Answer
It looks like you did not send the HTTP headers. Before sending any of the HTML content send following lines:

```
"HTTP/1.1 200 OK\r\n"
"Content-Type: text/html\r\n\r\n"

```

Make sure you send all the `\r\n` !
> 4 votes

# Answer
See the text from "'HTTP/1.1 200 OK'" until "'DOCTYPE html'" in the following couple of links which say the same, and you might like to read the rest of those pages:
> 2 votes

# Answer
Slightly off-topic, as this is not the source of your problem, but as jBot42 says, you need a proper regulator. When you use a voltage divider, your load (the ESP8266) is connected in parallel with one of the resistors (the 10K one) and effectively changes the output voltage of the regulator. As the consumption of power in the ESP8266 changes (e.g. when the wifi circuit transfers data), the voltage will also change.

At the very least you should place an electrolytic capacitor in parallel with the 10K resistor, but even this is not a good solution.
> 2 votes

# Answer
Make sure you save the SD card file as `index.htm`.

That is what you are calling for in your code. Your description has a reference to `index.html`. You will get the result you see.
> -1 votes

---
Tags: arduino-mega, esp8266, web-server, http
---


title: Why declare analog pins as ints?

text:
# Question
Title: Why declare analog pins as ints?
I often see code like this:

```
const int piezo = A0;
const int sensorPin = A1;

```

From my understanding, an int variable can hold things like -123, 0, 1, 456, etc.

How can A0 or A1 be an int?

# Answer
The board definition (pins\_arduino.h) has this:

```
static const uint8_t A0 = 14;
static const uint8_t A1 = 15;
static const uint8_t A2 = 16;
static const uint8_t A3 = 17;
static const uint8_t A4 = 18;
static const uint8_t A5 = 19;
static const uint8_t A6 = 20;
static const uint8_t A7 = 21;

```

Since A0 is a constant variable equal to 14, if you assign that to a variable, it just assigns 14.

In other words:

```
A = 14.
B = A.
Therefore B = 14.

```
> 2 votes

# Answer
They are defined in the Arduino libraries, and the Arduino libraries will translate them into the appropriate pins and registers before they are used. But in the meantime they're numbers.
> 1 votes

---
Tags: pins, variables
---


# Question
Title: Explanation of the formula of the map funtion
Can someone please explain (mathematically) how the formula for the map function actually came to light?
I have given the code of the map function below. You can see that it uses a formula to "map" values in a given range from a certain range. I don't quite understand how it came (not good at maths) :| So, I would like an explanation to how this formula came to light.

```
long map(long x, long in_min, long in_max, long out_min, long out_max)
{
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

```

# Answer
> 1 votes
```
(x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;

```

X is your value. in\_min is the minimum value of X. If you subtract that minimum value from X you re-map X into the range it can be.

For instance if X can be between 10 and 20 the in\_min would be 10 and in the in\_max would be 20. X will be somewhere between the two. Say X is 14. So X is 4 more than the minimum, or X - in\_min = 4.

That gives you how far (in quanta of X) into the range you are.

out\_max - out\_min gives you the range of the output in the same way. If you want to map to 200 to 300, say, the range between the two is 100.

The same with in\_max and in\_min - it gives the size of the input range - 10 in this case (20 - 10 = 10).

So you now have some values:

* 4 is how far through the input range you are
* 100 is how big the output range is
* 10 is how big the input range is

Multiply the first two together and divide by the third and you get how far through the output range the input is. You could also do it the other way around - divide the input offset (4) by the input size (10) to get the percentage (in the range 0 to 1) that you are through the input. Multiply that percentage by the size of the output range to get how far through the output you are. The way it is done avoids the use of any floating point values which makes it faster.

So 4 * 100 = 400. 400 / 10 = 40. Or, 4 / 10 = 0.4, 0.4 * 100 = 40.

Then you just add to that the output minimum values which just gives it an offset. 40 + 200 = 240.

Thus:

```
map(14, 10, 20, 200, 300) == 240.

```

To reiterate the steps:

* 14 - 10 = 4 (input offset)
* 20 - 10 = 10 (input range)
* 300 - 200 = 100 (output range)
* 4 * 100 = 400 (percentage of input range
* 400 / 10 = 40 applied to output range)
* 200 + 40 = 240 (add output offset)

# Answer
> 2 votes
`map()` implements **linear interpolation**.

> In mathematics, linear interpolation is a method of curve fitting using linear polynomials to construct new data points within the range of a discrete set of known data points.

---
Tags: map
---


# Question
Title: How to add Attiny13 to Attiny board profile in Arduino IDE 1.6?
Several months ago, I asked how to add (or where to get) Attiny13 to the list of boards in the Attiny package available in github: https://github.com/damellis/attiny In post 1.5 IDE, the package is installed by adding repo's JSON file to boards manager, as described in this post: https://arduino.stackexchange.com/a/23056/2955

Nowhere it says how to modify the files, not at all. And the package doesnot contain Attiny13 info.

The answer to my question was to do it myself and make a pull request. So ok, but how do I do it? I don't understand those files. The JSON file refferences some SHA-256 named zip files. That's hardly something that can be clearly and simply edited.

Can anyone tell me clearly what do I have to do to get Attiny13 working within that profile?

# Answer
> 1 votes
this is the official Arduino IDE 1.5 3rd party Hardware specification. It is still valid for 1.6.

It is probably lots easier to just copy past a similar board; rename the board ID and try.

Note that for a change in the boards.txt to be seen in the Arduino IDE you need to stop and start the Arduino IDE.

# Answer
> 2 votes
You can easily add entries for the ATTiny13 to the IDE, but won't show in the same listing as damelis's ATTiny cores, as he hasn't added the ATTiny13 yet.

Here is what I have found for ATTiny13 Arduino core files, working with boards.txt, loading them into the IDE, etc. The boards.txt is all laid out, just drop it into your personal workspace per the directions provided.

https://github.com/MCUdude/MicroCore

```
How to install
Boards Manager Installation
This installation method requires Arduino IDE version 1.6.4 or greater.
Open the Arduino IDE.
Open the File > Preferences menu item.
Enter the following URL in Additional Boards Manager URLs: https://mcudude.github.io/MicroCore/package_MCUdude_MicroCore_index.json
Open the Tools > Board > Boards Manager... menu item.
Wait for the platform indexes to finish downloading.
Scroll down until you see the MicroCore entry and click on it.
Note: If you are using Arduino IDE 1.6.6 then you may need to close Boards Manager and then reopen it before the MicroCore entry will appear.
Click Install.
After installation is complete close the Boards Manager window.

```

This will get you quite a lot of functions, configurable clock speeds, etc. The readme for this project helped me quite a lot in understanding what is going on inside the box and how I can enable only the Arduino core functions that I want, to save space.

Microcore is based upon : sourceforge.net/projects/ard-core13/files/latest/

And both projects have code updates as of this summer.

For other ATTiny (I'm using an ATTiny85 sometimes since for some things I ran out of space on the ATTiny13)

github.com/damellis/attiny

This will get you: ATtiny 25 (8 pin)

ATtiny 45 (8 pin)

ATtiny 85 (8 pin)

ATtiny 24 (14 pin)

ATtiny 44 (14 pin)

ATtiny 84 (14 pin)

---
Tags: arduino-ide, attiny13
---


# Question
Title: Is it possible to measure the velocity of a Unmanned Aerial Vehicle using only accelerometer?
Our project is about dropping a payload from a UAV on the specified area. We are using an accelerometer (connected to the Arduino board) to measure the velocity of the plane (assuming the initial velocity to be zero). Is it possible to accurately measure the velocity of a plane moving in the air for a time `t`? Will this method be feasible?

# Answer
> 5 votes
Not with any measure of accuracy, no.

You're basically asking about Dead Reckoning which is problematical at best - and when doing it with just a low-grade accelerometer it can't be anything more than a rough "It's moving quick" or "it's moving slower now" accuracy.

---
Tags: accelerometer
---


title: Stepper motor jittering

text:
# Question
Title: Stepper motor jittering
I'm trying to make a nema17 stepper motor work using ramps1.4 and A4988 driver.
But when I'm trying to rotate motor, it spins with almost no torque and constant shaking.

* Motor 2-phase nema17 , Step Angle 1.8° .
* Power supply 12v/60w.

Here is the sketch:
(I copied it from RepRap wiki , and removed everything except X Motor)

```
#define X_STEP_PIN         54
#define X_DIR_PIN          55
#define X_ENABLE_PIN       38

void setup()
{
  pinMode(X_STEP_PIN       , OUTPUT);
  pinMode(X_DIR_PIN        , OUTPUT);
  pinMode(X_ENABLE_PIN     , OUTPUT);
  digitalWrite(X_ENABLE_PIN, LOW);
}

void loop ()
{
  if (millis() % 10000 < 5000)
  {
    digitalWrite(X_DIR_PIN    , HIGH);
  }
  else
  {
    digitalWrite(X_DIR_PIN    , LOW);
  }

  digitalWrite(X_STEP_PIN     , HIGH);
  delay(1);
  digitalWrite(X_STEP_PIN     , LOW);
}

```

The wiring diagram:
(I have only X Motor plugged in)

and video: (*Google Video link is dead @ 2017-02-09*)

# Answer
> 1 votes
Add a second delay after:

digitalWrite(X\_STEP\_PIN , LOW);

Also try increasing the delay maybe you are pulsing the step pin too fast.

---
Tags: stepper, a4988
---


# Question
Title: How is a local variable address retrieved/returned inside the CPU of Arduino?
How is the address of a local variable retrieved in Arduino's ATMEGA328 micro-controller?

Lets say somewhere inside the main we have lines as:

```
int x = 5; //a variable declared and value of 5 stored in SRAM ??
int  *p; // a pointer is declared
p = &x; // p holds the address of the variable x

```

What happens above is &x retrieves the address of the variable x.

But how does this happen in a lower level? Which function retrieves the address of a variable and how does it do it? How does that function know the address of the variable x? I'm wondering what happens step by step after the instruction comes to the instruction register.

**edit**: Another question for int x = 5; is 5 stored at CPU register or SRAM? .

# Answer
> Another question for int x = 5; is 5 stored at CPU register or SRAM?

That depends entirely on how the compiler optimizes your code. If you never refer to `x` in your code the compiler may discard that statement entirely. Or it might use a CPU register. It might use RAM.
> 1 votes

# Answer
Just as an experiment, I tried the following:

```
void bar(int *);

void foo()
{
    int x = 5;
    int *p;
    p = &x;
    bar(p);
}

```

And here is what gcc translated that into (comments mine):

```
__SP_H__ = 0x3e
__SP_L__ = 0x3d
__tmp_reg__ = 0
foo:
    push r28            ; save r28
    push r29            ; save r29
    rcall .             ; make room on the stack
    in   r28, __SP_L__  ; copy SP into r29:r28 = Y: LSB...
    in   r29, __SP_H__  ; ... and MSB
    ldi  r24, lo8(5)    ; store x in a register: LSB...
    ldi  r25, 0         ; ... and MSB
    std  Y+2, r25       ; copy x into the stack: MSB
    std  Y+1, r24       ; ... and LSB
    movw r24, r28       ; r25:r24 = Y
    adiw r24, 1         ; r25:r24 = Y+1 = &x
    call bar            ; call bar(&x);
    pop  __tmp_reg__    ; release the two bytes...
    pop  __tmp_reg__    ; ... of stack space
    pop  r29            ; restore r29
    pop  r28            ; restore r28
    ret                 ; return

```

Expanded comments:

The instruction `rcall` is normally used to call another function. Here it's calling the following instruction, so it doesn't affect the program flow. It's only a trick: as `rcall` saves the return address into the stack, it makes the stack grow by two bytes, and is used here as an optimized way of reserving to bytes of stack space for storing `x`.

Next you see the stack pointer being copied into the r29:r28 register pair, also known as “Y pointer”. The stack pointer is a CPU register holding the address of the top of the stack, namely of the *first free slot*. As the stack grows towards the bottom of the RAM, at this point it looks like this:

```
address | SP = Y | Y+1 | Y+2  | Y+3 | Y+4 | Y+5  |  Y+6  |...
--------------------------------------------------------------
data    | (free) | room for x |  saved Y  | return addr. | ...

```

Next you see the value of `x` being placed first in a register pair (r25:r24), then on the stack at the addresses Y+1 and Y+2.

The instruction `mowv` copies a register pair, so now you have a copy of the stack pointer in the pair r25:r24. The instruction `adiw` adds an immediate value (here, 1) to a register pair, so that now r25:r24 holds the address of `x`. Finally, the function `bar()` is called: per the calling convention, the argument is to be passed in the r25:r24 pair.

A few final remarks:

* I passed the pointer to another function just to make gcc believe that I am actually *using* that pointer, otherwise it would optimize out the whole code into a function that does noting but return.
* You don't need to create a pointer variable to hold the address of `x`: calling just `bar(&x)` compiles into the very same assembly.
* Most local variables are assigned to CPU registers. Only because I am *using* the address of `x` did this variable get stored in the stack.
* The compiler output is very sensitive to the surrounding code, the compiler version, the optimization options, and so on. So you should consider all this as only an example.
* If you do not completely understand what each instruction is doing, you should now take a look at the AVR Instruction Set Manual
> 1 votes

# Answer
To answer your question you first have to understand what exactly happens when a function is called.

The very first operation, in what is known as the *function prologue*, a *stack frame* is allocated. This stack frame contains, amongst other things:

* The return address of the function
* Copies of any CPU registers that the function uses
* Storage space for any local variables

This may be through the use of a dedicated `PUSH` instruction or by manual manipulation of the *stack pointer* and writing of data direct to memory, depending on the CPU architecture.

During this process the compiler says "This variable is stored at stack offset X" for each variable. From that point on there is no "variable" as such, only a stack offset. All accesses to the variable are actually accesses to the memory at the location it already knows about within the stack frame.

When you then access the address of a variable you are basically saying "instead of getting me the contents of this memory address, just give me the memory address". Since the compiler already knows what that offset is it just adds it to the address of the stack frame and gives you that.

So if your stack frame is at 0x500 (for example) and the variable `x` is at offset 0x004:

* Accessing `x` gives you the contents of address 0x500 + 0x004
* Accessing `&x` gives you the value 0x500 + 0x004

Assigning `p` to `&x` creates another variable in the stack frame (which could be at offset 0x006 say). To that variable is assigned the value 0x500 + 0x004 (or 0x504 of course).

However, that is all from the point of view of a non-optimising compiler. The compiler itself may go "There is no need to store this value in memory, I have enough registers to keep it internally". So it doesn't actually allocate anything on the stack for the variable, it just "remembers" it in a register. That makes the function shorter and faster since there are less memory accesses.

There are a couple of variable attributes that affect how these decisions are made. The first is `volatile` which tells the compiler that "this variable must be stored in RAM and, further to that, don't trust that the value in RAM is the same since I last looked at it". This is essential for variables shared between the main loop and an interrupt context, since the compiler doesn't know if the interrupt is going to change the value of the variable.

```
volatile int foo;

```

The second is the `register` attribute. This suggests to the compiler that it might like to store this variable in a register to make things faster. This flag is seldom seen any more since the optimiser generally does a much better job of working out which variables would fit better in a register than a human can. It's very much a deprecated attribute now.

```
register int foo;

```
> 0 votes

---
Tags: arduino-uno, data-type, pointer
---


# Question
Title: ML8511 Sensor, unable to achieve meaningful results. Output voltages are atypical
Problem: ML8511 Sensor, unable to achieve meaningful results. A mapping to the voltage output yields values that are unrealistically high. Variance is greater than expected \[by me\], and sensitivity, if any is questionable. In essence, the sensor reports high levels of UV whether is a dimly lit room, or exposed to daylight.

Background: The interface is simple enough, and Google Search renders numerous hits, e.g., https://learn.sparkfun.com/tutorials/ml8511-uv-sensor-hookup-guide
All coding examples I have seen are akin to the one shown by Sparkfun.

Prior experience: I have a number of other Arduino devices running my sketches that record, collect, analyse, distribute, transmit and display findings. All of these work as intended.

Observations: I have spent a lot of time trying to make sense of the behaviour i observe with the sensor output, but have been unsuccessful. I have used two different sensors \[same model\], and switched UNO boards. I've removed all other connections to the board, reverted to using the example code, then to code measuring only pinout values. I have also measured pin voltage via voltmeter for both the output signal and the 3.3 volt reference pin.. According to specs, the sensor outputs voltage correlate with UV levels, and calibration is achieved via a known voltage reference level.

Based on a 3.3 volt reference, the sensor should output 1 to 3 volts, which can be mapped to a UV Intensity (mW/sq cm) range of 0 to 15. My output voltages range from 2.8 to 3.2 v, the last of which is seemingly out of specs. I have also used different sample sizes that comprise a data point, but that has little effect, but since the underlying values are out of range, it really would not matter. Although cheap sensors such as this are not known for great accuracy. I find that they generally work rather well.

My supposition is that:
a) I am working with defective \[abeit new\] sensors.
b) This particular model of sensor functions in an atypical manner.
c) Being unexperienced in such, I an overlooking something glaringly obvious to others.
d) Somehow my perception of reality is defective.
e) I have truly entered into the Twilight Zone.

Seeking: Information that supports or refutes my observations. Ideas that I might use to further isolate/ identify the problem. A solution to the problem.

Image of item used

ML8511 UV Intensity Graph from specs

\[

Typical ML8511 Wiring Diagram, the GYML8511 also has an additional connector for 5V, which I have tried both connected and disconnected, not understanding the board behaviour.

# Answer
I found another, third sensor identical to mine and functioning properly. By measuring pin output, then cross swapping with one of my two "supposedly abberant" sensors, I have identified my two as being defective, i.e., the other sketch then failed to function properly with one of those so identified sensors, whilst mine now worked as it should.

I typically buy at least two of everything in an effort to isolate such problems, but if from the same batch, two may not be sufficient in some situations.
> 1 votes

---
Tags: sensors
---


title: Arduino + ESP8266 as Webserver

text:
# Question
Title: Arduino + ESP8266 as Webserver
I want to connect Arduino to my Home Wifi and make it serve as a server to access GPIO pins on Arduino from remote (like controlling LED connected to Arduino from remote).
I am using ESP8266 to connect to my wifi network.
I am facing some issues like:

* sometimes it doesn't connect to my wifi router.
* not connecting to my mobile Hotspot.
* not able to serve default and AP mode.

I am following tutorial from http://allaboutee.com/2014/12/30/esp8266-and-arduino-webserver/
Here is my code:

```
#include <SoftwareSerial.h>
#define DEBUG true

SoftwareSerial esp8266(2,3); // make RX Arduino line is pin 2, make TX Arduino line is pin 3.
                             // This means that you need to connect the TX line from the esp to the Arduino's pin 2
                             // and the RX line from the esp to the Arduino's pin 3
void setup()
{
  Serial.begin(9600);
  esp8266.begin(115200); // your esp's baud rate might be different

  sendData("AT+RST\r\n",2000,DEBUG); // reset module
//  sendData("AT",2000,DEBUG); // send AT command
//  sendData("AT+GMR\r\n",2000,DEBUG); // returns firmware
//  Serial.println("checking mode");
//  sendData("AT+CWMODE=?\r\n",5000,DEBUG); // check supported modes
//
//  Serial.println("scanning APs");
//  sendData("AT+CWLAP\r\n",21000,DEBUG); // scan list of access points

  Serial.println("set mode 1");
  sendData("AT+CWMODE=1\r\n",5000,DEBUG); // configure as both mode

//  Serial.println("joining AP");
  sendData("AT+CWJAP=\"<MY_WIFI_SSID>\",\"<WIFI_PASSWORD>\"\r\n", 16000, DEBUG); // connect to wifi

  Serial.println("Testing CIFSR");
  sendData("AT+CIFSR\r\n",7000,DEBUG); // get ip address

  Serial.println("setting for multiple connection");
  sendData("AT+CIPMUX=1",2000,DEBUG); // configure for multiple connections

  Serial.println("print MAC address");
  sendData("AT+CIPSTAMAC?\r\n",2000,DEBUG); // print current MAC address

  Serial.println("set port 80 for server");
  sendData("AT+CIPSERVER=1\r\n,80",2000,DEBUG); // turn on server on port 80
}

void loop()
{
  if(esp8266.available()) // check if the esp is sending a message
  {

    if(esp8266.find("+IPD,"))
    {
     delay(2000);

     int connectionId = esp8266.read()-48; // subtract 48 because the read() function returns
                                           // the ASCII decimal value and 0 (the first decimal number) starts at 48

     String webpage = "<h1>Tyagi IoT</h1><button>LED1</button>";

     String cipSend = "AT+CIPSEND=";
     cipSend += connectionId;
     cipSend += ",";
     cipSend +=webpage.length();
     cipSend +="\r\n";

     sendData(cipSend,1000,DEBUG);
     sendData(webpage,1000,DEBUG);

     webpage="<button>LED2</button>";

     cipSend = "AT+CIPSEND=";
     cipSend += connectionId;
     cipSend += ",";
     cipSend +=webpage.length();
     cipSend +="\r\n";

     sendData(cipSend,1000,DEBUG);
     sendData(webpage,1000,DEBUG);

     String closeCommand = "AT+CIPCLOSE=";
     closeCommand+=connectionId; // append connection id
     closeCommand+="\r\n";

     sendData(closeCommand,3000,DEBUG);
    }
  }
}

void sendData(String command, const int timeout, boolean debug)
{
    esp8266.print(command); // send the read character to the esp8266
    long int time = millis();

    while( (time+timeout) > millis())
    {
      while(esp8266.available())
      {
        // The esp has data so display its output to the serial window
        Serial.write(esp8266.read());
      }
    }
}

```

# Answer
Are you using an arduino (as in UNO / mini / nano etc.) and communicating with a separate esp8266 via serial? I've found esp8266 module to be more reliable by using a 12e or such like and running arduino boot loader on it. There's more memory to play with, and I tend to formulate the data I need within the ESP8266 and then communicate with that via serial or I2C to get data / requests to and from.

Make sure you're supplying the ESP module with enough current - they're juicy little things, so good 300mA @3.3v and use a good 470uf 10v cap or something too.. They can splurge current on occasion, particularly when scanning networks.

Let me know what set up you're running

Cheers
> 1 votes

---
Tags: arduino-uno, esp8266, wifi, web-server
---


title: Implementing an external ADC in Arduino

text:
# Question
Title: Implementing an external ADC in Arduino
I'm planning to use a ADS1220 4-channel 24 bit adc but I really have no experience with SPI. I have found this library but I can't really understand the code that much and also this is measuring the differential voltage. I want to use this for my accelerometer (x, y and z data) but I can't seem to find how to do read from 3 channels, and I can't understand the code in the library :( I've also found a video for this adc in youtube but he didn't used it for multiple channels. I'm sorry for asking this, I'm just pressured since the deadline is really soon.

## EDITED

---

## sketch

```
#include "Protocentral_ADS1220.h"
#include <SPI.h>

#define PGA 1                 // Programmable Gain = 1
#define VREF 3.3
#define VFSR VREF/PGA
#define FSR (((long int)1<<23)-1)

volatile byte MSB;
volatile byte data;
volatile byte LSB;
//volatile char SPI_RX_Buff[3];
volatile byte *SPI_RX_Buff_Ptr;

long int bit32, data1, data2, data3;
long int bit24;

Protocentral_ADS1220 ADS1220;

void setup() {
  pinMode(ADS1220_CS_PIN, OUTPUT);
  pinMode(ADS1220_DRDY_PIN, INPUT);

  ADS1220.begin();
  //ADS1220.Single_shot_mode_ON();
}

void loop() {

  byte *config_reg;

  data1 = aRead(0x81);
  data2 = aRead(0x91);
  data3 = aRead(0xA1);

  Serial.print(data1);
  Serial.print("    ");
  Serial.print(data2);
  Serial.print("    ");
  Serial.println(data3);
  delay(500);

}

long int aRead(uint8_t config_byte) {
  ADS1220.writeRegister(CONFIG_REG0_ADDRESS , config_byte);
  uint8_t r = ADS1220.readRegister(CONFIG_REG0_ADDRESS);
  //Serial.println(r,HEX);

  ADS1220.SPI_Start();

  while (ADS1220.NewDataAvailable == false) {
    SPI_RX_Buff_Ptr = ADS1220.Read_Data();
  }

  if(ADS1220.NewDataAvailable = true) {
    ADS1220.NewDataAvailable = false;

    MSB = SPI_RX_Buff_Ptr[0];
    data = SPI_RX_Buff_Ptr[1];
    LSB = SPI_RX_Buff_Ptr[2];

    bit24 = MSB;
    bit24 = (bit24 << 8) | data;
    bit24 = (bit24 << 8) | LSB;

    bit24= ( bit24 << 8 );
    bit32 = ( bit24 >> 8 );
  }

  return bit32;
}

```

I tried to use the above sketch and I successfully read from 3 different channels but I noticed that the readings vary too much, compared to the example code. In the example code when I turn my potentiometer full CW, it outputs 8388607 which is correct right? since it is signed int.

But when running this sketch, the image below shows the output when the potentiometer is fully CW. Also turning the potentiometer fully CCW leads to negative values (shown in the 2nd picture) but in the example code, it gives 100-300 decimal values. Also these are the configuration registers I sent in registers 1-3 (I edited it in the part of the library) and for register 0, it is on the sketch.

`Config_Reg1 = 0x00;
 Config_Reg2 = 0x40;
 Config_Reg3 = 0x00;`

### using accelerometer

format is (x,y,z)

# Answer
> 0 votes
To get an understanding of how to read from the various ADS1220 channels, first review Figure 38, Analog Input Multiplexer, in the Datasheet as obtained from a link on TI.com's ADS1220 technicaldocuments webpage.

As can be seen, you'll need to close a switch from an AINx input line to the AINₚ bus, and also close the switch between AINₙ and AVSS. The IDACx switches and the BCS switches should remain open.

To operate those switches, first look at §8.6.1, Configuration Registers, in the Register Map section of the Datasheet. You'll see that MUX bits are in register 0, BCS is in register 1, IDAC is in register 2, and IxMUX are in register 3. To see what to put into those fields, look at Tables 16, 17, 19, and 20. For the MUX field, you will want a binary value like 1000, 1001, 1010, or 1011 to select one of AIN0-AIN3 as the AINₚ input and AVSS as the AINₙ input. BCS, IDAC, I1MUX, and I2MUX all should be zero.

For example, to read channels 0, 1, 2 in sequence, set MUX to 1000, set up other register fields, and trigger a conversion. After reading the result, change MUX to 1001, trigger a conversion, read result, change MUX to 1010, trigger a conversion, read result, etc.

---

*Edit 1:* In slightly more detail, one could do as follows.

> • Use a WREG command \[as in §8.5.3.6; or some library equivalent\] to send three bytes to set up Configuration Registers 1, 2, 3.
> • For i=0, 1, and 2 in turn, construct a configuration byte, send that byte to Configuration Register 0, start a conversion, await result, read result; as follows:
>
> > Set the MUX field of a byte to i
> > Set PGA as desired (ie, to 1, 2, or 4, via codes 000, 001, or 010)
> > Set the PGA\_BYPASS bit (as required when AINₙ = AVSS)
> > Use a WREG to send the constructed byte to Configuration Register 0
> > Use a START/SYNC command to start a conversion (see §8.5.3.2)
> > Wait for DRDY to go low
> > Use an RDATA command to read iᵗʰ ADC result (see §8.5.3.4)

---

*Edit 2:* In Protocentral's ADS1220.ino sketch, one finds the code sequence

```
  MSB = SPI_RX_Buff_Ptr[0];
  data = SPI_RX_Buff_Ptr[1];
  LSB = SPI_RX_Buff_Ptr[2];
  bit24 = MSB;
  bit24 = (bit24 << 8) | data;
  bit24 = (bit24 << 8) | LSB; // Converting 3 bytes to a 24 bit int
  bit24= ( bit24 << 8 );
  bit32 = ( bit24 >> 8 );     // Converting 24 bit two's complement to 32 bit two's complement

```

More competently and concisely, and with `SPI_RX_Buff_Ptr` renamed to `SPI_RX_Buff`, this could be written as:

```
  bit32 = (((long)(SPI_RX_Buff[0]<<8 | SPI_RX_Buff[1])<<8 | SPI_RX_Buff[2])<<8)>>8;

```

which acts as follows: Assemble three bytes from `SPI_RX_Buff` into a 24-bit twos-complement-signed number. Shift that number left 8 bits so that its sign bit now sits in the sign bit position of a 32-bit signed integer. Shift that result 8 bits right with sign extension so that the final result is a signed 32-bit integer with possible values from -2²³ up to (2²³-1).

Sign extension occurs – usually – because in many implementations of C, the `>>` operator does an arithmetic shift instead of a logical shift when its operand is signed.

---
Tags: arduino-uno, adc
---


title: Arduino MCP23S17 I/O Expander (SPI)

text:
# Question
Title: Arduino MCP23S17 I/O Expander (SPI)
I found this post and I am having almost the exact same issue. Nick Gammon (the god of arduino) has an excellent answer but I can't for the life of me implement it myself. I am not an advanced user like the initial question asker.

So What I want to do is use 2 MCP23S17's (picture here). I have been messing with one of them all week and have it reading like a charm. I am using the githib library by n0mjs710 to do this. But writing to one will not work.

Along with the zipped library is a few examples. I am trying to read some BCD switches off of one "input MCP" and then display the digits on the "output MCP"

I have used external pullups so I did make one change to the code by commenting out the call for pullups. Here is what Doesn't work:

```
#include <SPI.h>              // We use this library, so it must be called here.
#include <MCP23S17.h>         // Here is the new class to make using the MCP23S17 easy.

MCP inputchip(1, 10);             // Instantiate an object called "inputchip" on an MCP23S17 device at address 1
                                  // and slave-select on Arduino pin 10
MCP outputchip(2, 10);            // Instantiate an object called "outputchip" on an MCP23S17 device at address 2
                                  // and slave-select on Arduino pin 10

void setup() {
  inputchip.begin();
  outputchip.begin();
  inputchip.pinMode(0xFFFF);     // Use word-write mode to set all of the pins on inputchip to be inputs
  //inputchip.pullupMode(0xFFFF);  // Use word-write mode to Turn on the internal pull-up resistors.
  inputchip.inputInvert(0xFFFF); // Use word-write mode to invert the inputs so that logic 0 is read as HIGH
  outputchip.pinMode(0x0000);    // Use word-write mode to Set all of the pins on outputchip to be outputs
}

void loop() {
  int value;                        // declare an integer to hold the value temporarily.
  value = inputchip.digitalRead();  // read the input chip in word-mode, storing the result in "value"
  outputchip.digitalWrite(value);   // write the output chip in word-mode, using our variable "value" as the argument
  // outputchip.digitalWrite(inputchip.digitalRead()); // this one line replaces the three above, and is more efficient
}

```

I have tried:

* slowing the SPI bus by changing the library to SPI\_Divide the clock by 2
* changing the ss line and even splitting the lines so one chip uses pin 10 and the other uses pin 9

So after reading Mr. Gammon's post I have made some changes to the code attempting to rid myself ***of the old slave select pin low trick*** he mentioned. Here is my attempt:

```
MCP inputchip(1, 10);             // Instantiate an object called "inputchip" on an MCP23S17 device at address 1
                                  // and slave-select on Arduino pin 10
MCP outputchip(2, 9);            // Instantiate an object called "outputchip" on an MCP23S17 device at address 2
                                  // and slave-select on Arduino pin 10
int ssPin = 9;

void setup() {
  pinMode(ssPin,OUTPUT);

  inputchip.begin();
  digitalWrite(ssPin, HIGH);
  digitalWrite(ssPin, LOW);
  outputchip.begin();
  inputchip.pinMode(0xFFFF);     // Use word-write mode to set all of the pins on inputchip to be inputs
  //inputchip.pullupMode(0xFFFF);  // Use word-write mode to Turn on the internal pull-up resistors.
  inputchip.inputInvert(0xFFFF); // Use word-write mode to invert the inputs so that logic 0 is read as HIGH
  digitalWrite(ssPin, HIGH);
  digitalWrite(ssPin, LOW);
  outputchip.pinMode(0x0000);    // Use word-write mode to Set all of the pins on outputchip to be outputs
}

void loop() {
  int value;
  // declare an integer to hold the value temporarily.
  value = inputchip.digitalRead();  // read the input chip in word-mode, storing the result in "value"
  digitalWrite(ssPin, HIGH);
  digitalWrite(ssPin, LOW);
  outputchip.digitalWrite(value);   // write the output chip in word-mode, using our variable "value" as the argument
}

```

So any advice would be great to get this working. Help me Obi wan Gammon your me only hope.

# Answer
> 2 votes
Majenko's library works. All praise to Majenko https://github.com/MajenkoLibraries/MCP23S17

# Answer
> 2 votes
This sketch uses the Majenko Library with two MCP23S17 chips to demonstrate the library functions.

It was tested on an Arduino Uno with IDE 1.6.5.

```
/*
 * MultiTest_Majenko_02.ino
 * Library Ref: github.com/MajenkoLibraries/MCP23S17
 *
 * Lowell Bahner
 * 2016-12-11
 *
 * Hardware: Arduino UNO
 * IDE: Arduino 1.6.5
 *
 * Useful SPI Ref: gammon.com.au/spi
 *
 * Wire the SPI Interface common lines (Mega2560 SPI pins shown in [ ]):
 * Arduino SPI_MOSI pin 11 [51] <->   SI  MCP23S17 pin 13
 * Arduino SPI_MISO pin 12 [50] <->   SO  MCP23S17 pin 14
 * Arduino SPI_CLOCK pin 13 [52]<->   SCK MCP23S17 pin 12
 * Arduino SPI_CS pin 10 [53]   <->   SS  MCP23S17 pin 11
 * MCP23S17 VDD pin 9 to +5V
 * MCP23S17 VSS pin 10 to Gnd
 * MCP23S17 Reset pin 18 to +5V
 * MCP23S17 Interrupt pins 19-20
 * MCP23S17 A0,A1,A2 pins connect to Gnd or +5V (000 = Address 0, 100 = Address 1, 010 = Address 2, etc)
 * MCP23S17 Port A pins are chip pins 21-28
 * MCP23S17 Port B pins are chip pins 1-8
 *
 * This sketch runs a series of functions to demonstrate library capabilities.
 * This sketch does not demonstrate interrupt functionality.
 *
 * This sketch instantiates 2 MCP23S17 chips.
 * Bank2 (MCP23S17 address 1) pins are set as INPUT or INPUT_PULLUP.
 *    Normally HIGH, use switch to set a pin LOW.
 * Bank1 (MCP23S17 address 0) pins are set as OUTPUT.
 *    MCP23S17 outputs will power LEDs up to 25ma through 1000ohm resistor to ground.
 *
 * Majenko MCP23S17 library functions (see .h,.cpp files for details):
 *
 *  bank.pinMode(uint8_t pin, uint8_t mode)
 *    where modes are:
 *      OUTPUT - sets pin HIGH
 *      INPUT  - sets pin LOW for sensing change to HIGH +V
 *      INPUT_PULLUP - sets pin HIGH for sensing change to LOW 0V
 *
 *  bank.digitalWrite(uint8_t pin, uint8_t value)
 *    if mode=OUTPUT, pin value = LOW (0) or HIGH (1)
 *    if mode=INPUT, value LOW disables pullup on pin, value HIGH enables pullup on pin
 *
 *  uint8_t value = bank.digitalRead(uint8_t pin)
 *    read the state of the pin
 *
 *  uint8_t value = bank.readPort(uint8_t port)
 *    read entire 8-bit port of all INPUT pins on Port A (port=0) or Port B (port>=1)
 *
 *  uint16_t longValue = bank.readPort()
 *    read both ports as 16-bit combined
 *
 *  bank.writePort(uint8_t port, uint8_t val)
 *    write val (0 or 1, hex example 0x55) to all OUTPUT pins on Port A (port=0) or Port B (port>=1)
 *
 *  bank.writePort(uint16_t val)
 *    write val (hex example 0x55AA) to all OUTPUT pins on Port A and Port B
 *
 *  Also, interrupt functions are defined:
 *      enableInterrupt(uint8_t pin, uint8_t type);
 *      void disableInterrupt(uint8_t pin);
 *      void setMirror(boolean m);
 *      uint16_t getInterruptPins();
 *      uint16_t getInterruptValue();
 *      void setInterruptLevel(uint8_t level);
 *      void setInterruptOD(boolean openDrain);
 *
 *
 *
 *
Run Sketch: Serial Monitor Output

 -- RWpins() --

Bank2: Switch i15: 1 (Push button switch not pushed, Bank2 INPUT pin 15 is HIGH +5V)
Bank1: Output j4:  1 (Bank1 OUTPUT pin 4 is HIGH.
                      Arduino pin 7 is set HIGH.
                      LED on pin 4 is ON. LED on pin 7 is ON.)

Bank2: Switch i15: 0 (Push button switch pushed, grounds Bank2 INPUT pin 15)
Bank1: Output j4:  0 (Bank1 OUTPUT pin 4 switches to LOW.
                      Arduino pin 7 is set LOW.
                      LED on pin 4 is OFF. LED on pin 7 is OFF.)

 -- RWport() --

Bank1: Port A BIN: 00000000
Bank1: Port B BIN: 00000000

Bank1: Port A BIN: 11110100  DEC: 244
Bank1: Port B BIN: 00001011  DEC: 11

 -- RWlongPortValue() --

Bank1: Port A & B BIN: 0000101111110100  HEX: 0x0BF4    DEC: 3060

 -- RWlongPort() --

Bank1: Port A & B BIN: 1011100101000010  HEX: 0xB942    DEC: 47426

 -- CyclePins() --

Bank1: Port A & B BIN: 0000000000000000  HEX: 0x0000    DEC: 0
Bank1: Port A & B BIN: 0000000000000001  HEX: 0x0001    DEC: 1
Bank1: Port A & B BIN: 0000000000000011  HEX: 0x0003    DEC: 3
Bank1: Port A & B BIN: 0000000000000111  HEX: 0x0007    DEC: 7
Bank1: Port A & B BIN: 0000000000001111  HEX: 0x000F    DEC: 15
Bank1: Port A & B BIN: 0000000000011111  HEX: 0x001F    DEC: 31
Bank1: Port A & B BIN: 0000000000111111  HEX: 0x003F    DEC: 63
Bank1: Port A & B BIN: 0000000001111111  HEX: 0x007F    DEC: 127
Bank1: Port A & B BIN: 0000000011111111  HEX: 0x00FF    DEC: 255
Bank1: Port A & B BIN: 0000000111111111  HEX: 0x01FF    DEC: 511
Bank1: Port A & B BIN: 0000001111111111  HEX: 0x03FF    DEC: 1023
Bank1: Port A & B BIN: 0000011111111111  HEX: 0x07FF    DEC: 2047
Bank1: Port A & B BIN: 0000111111111111  HEX: 0x0FFF    DEC: 4095
Bank1: Port A & B BIN: 0001111111111111  HEX: 0x1FFF    DEC: 8191
Bank1: Port A & B BIN: 0011111111111111  HEX: 0x3FFF    DEC: 16383
Bank1: Port A & B BIN: 0111111111111111  HEX: 0x7FFF    DEC: 32767
Bank1: Port A & B BIN: 1111111111111111  HEX: 0xFFFF    DEC: 65535

Bank1: Port A & B BIN: 1111111111111111  HEX: 0xFFFF    DEC: 65535
Bank1: Port A & B BIN: 0111111111111111  HEX: 0x7FFF    DEC: 32767
Bank1: Port A & B BIN: 0011111111111111  HEX: 0x3FFF    DEC: 16383
Bank1: Port A & B BIN: 0001111111111111  HEX: 0x1FFF    DEC: 8191
Bank1: Port A & B BIN: 0000111111111111  HEX: 0x0FFF    DEC: 4095
Bank1: Port A & B BIN: 0000011111111111  HEX: 0x07FF    DEC: 2047
Bank1: Port A & B BIN: 0000001111111111  HEX: 0x03FF    DEC: 1023
Bank1: Port A & B BIN: 0000000111111111  HEX: 0x01FF    DEC: 511
Bank1: Port A & B BIN: 0000000011111111  HEX: 0x00FF    DEC: 255
Bank1: Port A & B BIN: 0000000001111111  HEX: 0x007F    DEC: 127
Bank1: Port A & B BIN: 0000000000111111  HEX: 0x003F    DEC: 63
Bank1: Port A & B BIN: 0000000000011111  HEX: 0x001F    DEC: 31
Bank1: Port A & B BIN: 0000000000001111  HEX: 0x000F    DEC: 15
Bank1: Port A & B BIN: 0000000000000111  HEX: 0x0007    DEC: 7
Bank1: Port A & B BIN: 0000000000000011  HEX: 0x0003    DEC: 3
Bank1: Port A & B BIN: 0000000000000001  HEX: 0x0001    DEC: 1
Bank1: Port A & B BIN: 0000000000000000  HEX: 0x0000    DEC: 0
 *
 *
 *
 */

// Majenko MCP23S17 Library
#include <MCP23S17.h>

// Arduino Library SPI.h
#include <SPI.h>

// SPI CS/SS chipselect pin can be changed by user as desired
const uint8_t chipSelect = 10;

// example Arduino board pin
uint8_t pin7 = 7;

// Create an object for each chip
// Bank1 is address 0. Pins A0,A1,A2 grounded.
// Bank2 is address 1. Pin A0=+5V, A1,A2 grounded.

MCP23S17 Bank1(&SPI, chipSelect, 0);
MCP23S17 Bank2(&SPI, chipSelect, 1);

void setup() {

  // Slow down the master a bit if desired
  SPI.setClockDivider(SPI_CLOCK_DIV8);

  Serial.begin(9600);

  Bank1.begin();
  Bank2.begin();

  // LED connected to Arduino pin 7 to test inter-device communication
  pinMode(pin7, OUTPUT);

  //
  // Set MCP23S17 pin modes:
  // example set one pin: chip.pinMode(0, OUTPUT); // sets chip pin 0 (Port A 0) to OUTPUT mode
  //
  // setChipPins(); // use loop to set individual pins
  // or, since this library does not have a setPortPinMode, do 8 pin loops
  setPortPins(); // example: set pins on each Port on each chip to different modes.
  //

}

// Set all Chip pins to desired mode
void setChipPins() {
  // Example usage

  // Set all Bank1 pins to be OUTPUT
  for (uint8_t i = 0; i <= 15; i++)
    Bank1.pinMode(i, OUTPUT);

  // Set all Bank2 pins to be INPUT_PULLUP
  for (uint8_t i = 0; i <= 15; i++)
    //Bank2.pinMode(i, INPUT);  // unswitched pin voltages about +0.1V, switch must pull pin to +5V
    Bank2.pinMode(i, INPUT_PULLUP);  // unswitched pin voltages about +4.9V, switch must ground pin
}

// Set Port pins to desired mode
void setPortPins() {
  // Example usage

  // Set all Bank1 Port A pins to OUTPUT
  for (uint8_t i = 0; i <= 7; i++)
    Bank1.pinMode(i, OUTPUT);

  // Set all Bank1 Port B pins to OUTPUT
  for (uint8_t i = 8; i <= 15; i++)
    Bank1.pinMode(i, OUTPUT);

  // Set all Bank2 Port A pins to be INPUT
  for (uint8_t i = 0; i <= 7; i++)
    Bank2.pinMode(i, INPUT);

  // Set all Bank2 Port B pins to be INPUT_PULLUP
  for (uint8_t i = 8; i <= 15; i++)
    Bank2.pinMode(i, INPUT_PULLUP);
}

//
// Change LED On/Off with button push
// 1) Switch an INPUT_PULLUP pin to ground
// 2) Read the pin value
// 3) Write the value to an OUTPUT pin
// 4) Turn LED On/Off
// Use functions digitalRead(pin) and digitalWrite(pin,value)
//
void RWpins() {

  Serial.print("\n -- RWpins() --"); Serial.println("");

  uint8_t b15 = 0;  // Bank2 input pin value (0 push LOW, 1 normally open HIGH) with push button switch to gnd
  uint8_t i = 15;   // Bank2 pin number
  uint8_t a4 = 0;   // Bank1 output pin value
  uint8_t j = 4;    // Bank1 pin number

  // read the switch value into b15
  b15 = Bank2.digitalRead(i);
  Serial.print("\nBank2: Switch i"); Serial.print(i); Serial.print(": ");  Serial.println(b15);

  // write the switch pin i, value b15, to the output pin j
  Bank1.digitalWrite(j, b15);

  a4 = Bank1.digitalRead(j);
  Serial.print("Bank1: Output j"); Serial.print(j); Serial.print(": ");  Serial.println(a4);

  // Turn on/off LED connected to Arduino pin 7 through resistor to ground
  digitalWrite(pin7, a4);
}

//
// Read and Write Port values
//
void RWport() {

  Serial.print("\n -- RWport() --"); Serial.println("");

  // set the port pin modes
  setPortPins(); // all Bank1 pins are OUTPUT but set as Ports

  // clear the port pin values to 0
  uint8_t port = 0; // Port A
  uint8_t val = 0x00; // set to 0000 0000
  Bank1.writePort(port, val);
  port = 1; // Port B
  Bank1.writePort(port, val); // set to 0000 0000

  // read the port pin values
  uint8_t valueA = Bank1.readPort(0);
  Serial.print("\nBank1: Port A BIN: "); print8Bits(valueA); Serial.println("");
  uint8_t valueB = Bank1.readPort(1);
  Serial.print("Bank1: Port B BIN: "); print8Bits(valueB); Serial.println("");

  // set the port pin values
  port = 0; // Port A
  val = 0xF4; // set to 1111 0100
  Bank1.writePort(port, val);
  port = 1; // Port B
  val = 0x0B; // set to 0000 1011
  //val = 0xB0; // set to 1011 0000
  Bank1.writePort(port, val);

  // read the port pin values
  valueA = Bank1.readPort(0);
  Serial.print("\nBank1: Port A BIN: "); print8Bits(valueA);
  Serial.print("  DEC: "); Serial.println(valueA, DEC);

  valueB = Bank1.readPort(1);
  Serial.print("Bank1: Port B BIN: "); print8Bits(valueB);
  Serial.print("  DEC: "); Serial.println(valueB, DEC);
}

void RWlongPortValue() {

  Serial.print("\n -- RWlongPortValue() --"); Serial.println("");

  // Read the Bank1 Port pin values as a combined long value
  uint16_t valueLong = Bank1.readPort();
  Serial.print("\nBank1: Port A & B BIN: "); print16Bits(valueLong);
  Serial.print("  HEX: "); crPrintHEX(valueLong, 4);
  Serial.print("  DEC: "); Serial.println(valueLong, DEC);
}

void RWlongPort() {

  Serial.print("\n -- RWlongPort() --"); Serial.println("");

  // Write the Bank1 Port pin values as a combined long value
  uint16_t valueLong = 0xB942;
  Bank1.writePort(valueLong);

  // Read the Bank1 Port pin values as a combined long value
  uint16_t valueLongIn = Bank1.readPort();
  Serial.print("\nBank1: Port A & B BIN: "); print16Bits(valueLongIn);
  Serial.print("  HEX: "); crPrintHEX(valueLongIn, 4);
  Serial.print("  DEC: "); Serial.println(valueLongIn, DEC);
}

//
// Cycle through OUTPUT pins with count-up count-down
//
void CyclePins() {

  Serial.print("\n -- CyclePins() --"); Serial.println("\n");

  // Set all Bank1 pins to be OUTPUT
  for (uint8_t i = 0; i <= 15; i++)
    Bank1.pinMode(i, OUTPUT);

  // clear Bank1 using writePort
  uint16_t valueLong = 0x0000;
  Bank1.writePort(valueLong);

  // Read the Bank1 Port pin values as a combined long value
  for (int8_t i = -1; i <= 15; i++) {
    if (i >= 0) Bank1.digitalWrite(i, 1); // i=-1 allows print of 0 data
    valueLong = Bank1.readPort(); // read 16 bits
    Serial.print("Bank1: Port A & B BIN: "); print16Bits(valueLong);
    Serial.print("  HEX: "); crPrintHEX(valueLong, 4);
    Serial.print("  DEC: "); Serial.println(valueLong, DEC);
  }

  Serial.println("");

  for (int8_t i = 15; i >= -1; i--) { // i=-1 allows print of 0 data
    // decrement after the read while reading down the values
    valueLong = Bank1.readPort(); //  read 16 bits
    Serial.print("Bank1: Port A & B BIN: "); print16Bits(valueLong);
    Serial.print("  HEX: "); crPrintHEX(valueLong, 4);
    Serial.print("  DEC: "); Serial.println(valueLong, DEC);
    Bank1.digitalWrite(i, 0);
  }
}

void loop() {

  // Change LED On/Off with button push
  RWpins();

  // Read and Write Port pins as a group
  RWport();

  // Read the Bank1 Port pin values as a combined long value
  RWlongPortValue();

  // Read and Write Chip 16 pins as a group
  RWlongPort();

  // Cycle through OUTPUT pins with count-up count-down
  CyclePins();

  delay(1000);

}

// print 8-bit byte as 8 bit binary string
void print8Bits(uint8_t myByte) {
  for (byte mask = 0x80; mask; mask >>= 1) {
    if (mask  & myByte)
      Serial.print('1');
    else
      Serial.print('0');
  }
}

// print 16-bit word as 16 bit binary string
void print16Bits(uint16_t myWord) {
  for (uint16_t mask = 0x8000; mask; mask >>= 1) {
    if (mask  & myWord)
      Serial.print('1');
    else
      Serial.print('0');
  }
}

//---------------------------------------------------------------------------------
// crPrintHEX print value as hex with specified number of digits
//---------------------------------------------------------------------------------

void crPrintHEX(unsigned long DATA, unsigned char numChars) {
  unsigned long mask  = 0x0000000F;
  mask = mask << 4 * (numChars - 1);
  Serial.print("0x");
  for (unsigned int i = numChars; i > 0; --i) {
    Serial.print(((DATA & mask) >> (i - 1) * 4), HEX);
    mask = mask >> 4;
  }

  Serial.print("  ");
}

```

---
Tags: arduino-uno, pins
---


# Question
Title: Software PWM implementation on ATTiny44 screws up timing functions
I've came up with a poor man's implementation of software-based PWM for the ATTINY44 and I'm kinda stuck now. It works but it screws up the timing functions badly (delay, delayMicroseconds) no matter what timer I use for the ISR (timer 1 or 0). The delay in my example is more like 1 second than 100ms. Can somebody point out what I'm doing wrong? :)

```
uint8_t pwmled[11] = {0};
volatile uint8_t currentStep = 0;
uint8_t p[11] = {PORTA0, PORTA1, PORTA2, PORTA3, PORTA4, PORTA5, PORTA6, PORTA7, PORTB0, PORTB1, PORTB2};

void initTimer1() {
  cli();
  TCCR1B = (1 << WGM12) | (1 << CS10);
  OCR1A = 64;
  TIMSK1 = (1 << OCIE1A);
  sei();
}

ISR(TIM1_COMPA_vect) {
  if (currentStep < 100)
    currentStep += 1;
  else
    currentStep = 0;
  for (uint8_t x = 0; x <= 10; x++)
    (currentStep < pwmled[x]) ? (x < 8 ? PORTA |= (1 << p[x]) : PORTB |= (1 << p[x])) : (x < 8 ? PORTA &= ~(1 << p[x]) : PORTB &= ~(1 << p[x]));
}

void setup() {
  initTimer1();
  for (int i = 0; i <= 10; i++) {
    pinMode(i, OUTPUT);
    pwmled[i] = 1;
  }
}

void loop() {
  pwmled[random() % 11] = random() % 100;
  delay(100);
}

```

# Answer
What you are doing wrong is:

The problem is your interrupt handling routine **lasts too long**. Since inside ISR() interrupt flag is automatically cleared, timer0 interrupts are being missed and `delay()` depends upon timer0 interrupts.

To confirm the problem is ISR, **remove the for loop** and just toggle one pin instead. I bet the delay will then be as it should.

Try to put `sei()` at the beginning of your ISR to see what is going to happen with the timming of the delay - but **that is not the right way**.

Instead of using `delay()` (based on timer0) you can count the number of timer1 interrupts but **ISR routine must not last longer than the time between two interrupts** and your ISR spends **quite a few** T-states inside the for loop. A rule of a thumb is ISR has to be very short (**fast**) - unless you **really** know what you are doing. For example, in one of my devices I am using a very long ISR routine (in fact the firmware consists of only the ISR - there is only `sleep_mode();` in main) for which I know it **sometimes** lasts longer than the time window between interrupts and I know some of the interrupts are occasionally being missed. However, these few missed interrupts are not critical to that particular application and I am sure the interrupts are being missed rarely.

You could change `OCR1A` value to increase the time between interrupts but then you would have lower PWM frequency.
> 1 votes

---
Tags: timers, attiny, isr
---


title: How do I use two I2C LCDs with 4 pins?

text:
# Question
Title: How do I use two I2C LCDs with 4 pins?
I have two I2C LCD screens:

* one with 2 lines
* one with 4 lines.

Both have 4 pins each: `GND`, `VCC`, `SDA`, `SDL`. I connect `SDA` and `SDL` to `A4` and `A5` respectively, and I display text on each one of them with:

```
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16,4);

```

But how can I use both of them at the same time?

I connected the second one's `SDA` and `SDL` to `A2` and `A3`, but apparently I have to provide the right address for them (like `0x27`), right?

However, while both are connected, using I2C\_Scanner only shows one device:

```
Scanning...
I2C device found at address 0x27  !
done

```

What am I missing?

# Answer
> 4 votes
**With the I2C backpack there are three pairs of landings, A0, A1, A2, which determine the 3 LSB of the device's address, using inverted binary.**

Left alone, they generate part of the F or 7 part of the address. 0x3F is common, as is 0x27.

**To use more than one device it is necessary to jumper them all uniquely.**

The upper bits that generate the 0x3 are hard-wired. So is the highest bit of the lower byte. Only the three lowest-order bits can be changed.

Since these address bits are inverted, jumpering the A0 will subtract 1 from the address. 0x3F will become 0x3E, 7 will become 6.

**You have control enough to make up to 7 LCD modules on the same I2C bus.**

The only caveat is that if you have more than one device writing to the various LCDs you might get collisions, which can mess up the display pretty good.

There are questions on I2C collision avoidance and detection on http://RaspberryPi.StackExchange.com if that is your situation.

**Jumpering one or more of them is pretty easy - just pre-tin some wire and solder it quickly then cut off the excess.**

Wire the SDA and SCL wires of the LCDs in parallel and to the SDA and SCL pins on the Arduino, usually A4 and A5. (I always begin with a breadboard for this). Make sure you have discrete pull-up resistors (10K is common) on each, in only one place on the bus.

If you have a DS3231 RTC module in the system, you do not need to add pull-ups because it has them internally.

If one LCD is already working then you know you have proper pull-up voltage on the bus. (The signals are switched to the ground state to send data on the I2C bus)

## So, to Summarize:

If you have two LCDs in your system you can use LCD modules that already come with different addresses, like

```
LiquidCrystal_I2C lcd1(0x27,....);

```

for the first one, then

```
LiquidCrystal_I2C lcd2(0x3F,.....);

```

for the second one.

## Note that the parameters for these definitions are

```
LiquidCrystal_I2C lcdname(addr,en,rw,rs,d4,d5,d6,d7,bl,blpol);

```

0x27 and 0x3F are the most common stock addresses and **0x27 modules are getting harder to find.**

If you have a 0x27 then it is very likely that if you buy a newer one it will be 0x3f. **Problem solved.**

The d4 and d5 in the definition specifies the pins to use for I2C.

You can run the i2cscanner program to see what it finds, once they are wired together. If you see two different addresses, say 0x27 and 0x3F, then you are good to go.

If only 2F shows, then you want to consider soldering A0 together on one module then run the scanner again to make sure it worked.

## Here is how I usually do it when both come set as 0x3f:

**I have a Yellow one which is a stock 0x3F and a Blue one where I jumpered A0 to make it 0x3E. They both are 20 x 4 displays.**

Here are my definitions: (remember, the 4,5 define SDA, SCL pins)

```
LiquidCrystal lcdblue  (0x3e,2,1,0,4,5,6,7,3,POSITIVE);
LiquidCrystal lcdyellow(0x3f,2,1,0,4,5,6,7,3,POSITIVE);

```

Then in setup() I use this:

```
lcdblue.begin(20,4);
lcdblue.backlight();
delay(250);
lcdblue.nobacklight();
delay(250);
lcdblue.backlight();

lcdyellow.begin(20,4);
lcdyellow.backlight();
delay(250);
lcdyellow.nobacklight();
delay(250);
lcdyellow.backlight();

```

And it's good to go, using pin A4 as SDA and A5 as SCL.

You know they are working as they wink their backlights at you.

If one of yours is 20 x 2 then use `lcd2.begin(20,2);` of course.

If you REALLY want to use other pins for your I2C bus then just change the 4,5 in the `LiquidCrystal_I2C` definition to the pins you want to use. I never have met anyone who would want to do this.

Hope this helps.

# Answer
> 0 votes
You can't hook up I2C devices to arbitrary pins; they must either be connected to SDA and SCL and given different addresses, or you must use software I2C. Figure out how to give the second device a different address, and then instantiate another `LiquidCrystal_I2C` with the new address in order to be able to use it.

# Answer
> 0 votes
You may be able to wire them in parallel, if you can hold the clock (SCL) high (for one at a time).

Put a diode in to stop the other one going high as well.

Pick a spare pin on your arduino (I will use digital pin 7 for device A, 8 for device B, but it doesn't matter which). When you want to talk to device A, make sure pin 7 is in high impedance mode, and 8 is high. Talk to device A. Stop talking to device A. Put pin 8 in high impedance mode, and pin 7 to high. Talk to device B. Wash, rinse, repeat. So long as a device sees it's clock as high, it won't listen or talk.

---
Tags: i2c, lcd
---


# Question
Title: Arduino leonardo. Encoder mouse movement
I want to connect my sensonrs to an arduino leonardo.

The principal idea is use it like a scratch (like dj hero or beatmania??), if I move the scratsh up, the mouse will go up ( y Axis ), and if it go down, the y Axis down.

The middle is for gnd and the other four to 0 to 3 pin in the arduino.

So my problem is I am not sure about the conecction and also the code to run my program, beacuse all the thing that i try to do, had no work in my computer.

# Answer
> 1 votes
That's a quadrature encoder implemented using photo interrupters. Use a DMM to suss out which half of each is the diode and which is the phototransistor, connect both halves as you would were they independent, and decode the quadrature output.

---
Tags: sensors, arduino-leonardo, rotary-encoder
---


# Question
Title: Suggestions for a program for drawing simple schematics
I'm wondering if there are free programs or web sites that let you draw simple schematics similar to this example:

# Answer
> 5 votes
A compilation of possibilities mentioned the comments. I'll add to this as I try out the suggestions.

From @Gerben, "kind of in order of complexity":

* circuitlab.com \- online schematic capture and simulator (analog, digital, and mixed signal). Licensed for professional, student/educator, and hobbyist (free) usage. Officially runs in Chrome and Firefox, and they report users having success with Safari and Opera which are not officially supported.
* Fritzing \- cross-platform (Mac, Windows, Linux). Has Breadboard View mode with built in Arduino support that allows you to create diagrams like this one:

From there you can click on the Schematic view to route wires and convert the breadboard into a traditional schematic.
* CircuitMaker \- Windows only, requires creating an account.
* Eagle \- cross-platform (Mac, Windows, Linux), paid and free versions.

Component library collections (thanks to Marko Mackic for the idea):
* KiCad \- cross-platform (Mac, Linux (with packages for several distributions), Windows, and source code), open source and also on GitHub.

Found Autodesk's 123D Circuits in a question on Arduino Simulators (and emulators).

# Answer
> 2 votes
I've been using ExpressSCH (Express Schematic) from: http://www.expresspcb.com/

That is a free install for Windows and is pretty easy to use.

Example of its output:

It comes with quite a few symbols defined, and you can easily make your own extra ones (like the Uno I did in the schematic above).

# Answer
> 1 votes
Myself, I prefer to use Eagle, and download Sparkfun and Adafruit libraries for components based around Arduino. There you can create schematics, and create PCB layouts too.

# Answer
> 1 votes
There are many cicuit drawing softwares available on the internet. Besides the softwares mentioned above, I would like to recommend EasyEDA editor.

It’s a free, web-based EDA suite, you can use it without installing anything.

Mac, Linux, Windows and Android,All platforms supported.

EasyEDA has simple but powerful drawing capabilities, it’s part library is quite massive and there is plenty of parts to pick from. Users can create their own symbols and footprints either by copying existing ones into My Parts then editing and saving them or by drawing them from scratch.

For example, here is a simple 555 circuit.

---
Tags: documentation
---


title: What means the ~ symbol in the code?

text:
# Question
Title: What means the ~ symbol in the code?
I'm learning Arduino (school and from myself).

We have the following code:

```
temp = Wire.read();
temp = ~temp;
temp = temp - 1;

```

This code is made to read, then print positive and negative values from a temp sensor. If you need more parts of the code, let me know.

I don't understand what does the `~` symbol, can someone help me?

Thanks.

# Answer
> 4 votes
As always, `~` in C++ is bitwise negation.

---
Tags: c++
---


# Question
Title: Can i power Esp8266-Nodemcu with a solarpanel + usb-powerbank?
I was asking myself wether it's possible to power my nodemcu board (version 3) with a usb powerbank, like a smartphone, but the powerbank should then be recharged by a solar panel. So this is basically like it could look like:

I know, there should be some charge regulation, but i would just like to know, if that circuit would be able to charge the powerbank? According to the Hardware Layout, it could be possible, but i am not definetly sure about that. Maybe you can give me some input about that.

# Answer
You can **not** connect a solar panel just like that. There is a voltage regulator at the output of the power bank to get 5V out of the some number of Li-Ion cells and you can not charge the power bank backwards through the output. You must charge Li-Ion cells directly, that is why there is a separate input used for charging the battery pack. If you want to have a battery backup for NodeMCU you have to use a charging board and a MOSFET to switch off the battery output whenever the battery is being charged. The charger must supply enough power for both charging the battery and supplying NodeMCU.

When there isn't voltage at the charger (and NodeMCU) input, MOSFET should switch on the output from the battery and you have to use a diode (in a similar way you used it in your schematics) to prevent beckfeeding when working on battery. It should be Schottky diode with low forward voltage.
> 1 votes

---
Tags: arduino-ide, esp8266, nodemcu
---


title: RF24 Network and Payload

text:
# Question
Title: RF24 Network and Payload
i struggle to figure out the max payload for the RF24 Network library without payload fragmentation. It uses a NetworkHeader with the Attributes from\_node, to\_node, id, type and reserved. This must be send to and lowers the amount of Bytes of the payload.

Can any one tell me how many Bytes I can write without sending two packages?

# Answer
> 3 votes
According to the source code:

```
const static unsigned int max_frame_payload_size = MAX_FRAME_SIZE-sizeof(RF24NetworkHeader);

```

that would be `24 bytes`. Maximum lenght of payload for NRF24L01+ is 32 bytes and the `RF24NetworkHeader` seem to be 8 bytes long. So you can send up to 24 bytes in one package.

**EDIT:**
Here is the stripped `RF24NetworkHeader` declaration code from which can be seen `sizeof(RF24NetworkHeader)` is 8 bytes.

```
struct RF24NetworkHeader {
  uint16_t from_node;           // 2 bytes
  uint16_t to_node;             // 2 bytes
  uint16_t id;                  // 2 bytes
  unsigned char type;           // 1 byte
  unsigned char reserved;       // 1 byte
  static uint16_t next_id;      // static member doesn't count for sizeof()
  RF24NetworkHeader() {}
  RF24NetworkHeader(uint16_t _to, unsigned char _type = 0): to_node(_to), id(next_id++), type(_type) {}
  const char* toString(void) const;
};

```

---
Tags: nrf24l01+, network
---


# Question
Title: Do we need to burn bootloader in new Atmega328p before uploading the arduino code
I have an arduino code which is working fine. Now I am planning to make a PCB out of it. But I do not want to use the complete Arduino board. I just want to use the `Atmega328p` microcontroller. So my plan is to connect the USBasp programmer to the new Atmega328p and upload the code. So before this code, do I need to upload the bootloader or uploading the code first will run fine.

# Answer
**Tools \> Burn Bootloader** in the Arduino IDE does two things:

* Set fuses according to the settings in boards.txt for the **Tools \> Board** selection
* Install the bootloader.

The latter is pointless since when you do an **Upload Using Programmer** the bootloader will be overwritten but the former is very important to do the first time you use a new chip(or anytime you want to change the fuses) to be sure that the correct fuses are set, which likely will be different from the default settings of the chip when you get it. **Upload Using Programmer** does not set fuses, the only way to do this via the Arduino IDE is **Tools \> Burn Bootloader**.

So yes, you should Burn Bootloader.
> 3 votes

# Answer
The only thing the bootloader for the ATmega328P does is to enable UART programming. If you are only using ISP then there is no need to have the bootloader.
> 0 votes

---
Tags: atmega328, bootloader
---


title: Arduino with two (or more) push buttons

text:
# Question
Title: Arduino with two (or more) push buttons
I am trying modify this setup for two push buttons https://www.arduino.cc/en/Tutorial/Button.

The code seems rather trivial

```
int yellowButtonPin = 2;
int blueButtonPin = 4;

int yellowButtonState = 0;
int blueButtonState = 0;

void setup(){
  Serial.begin(9600);
  pinMode(yellowButtonPin,INPUT);
  pinMode(blueButtonPin,INPUT);
}

void loop(){
  yellowButtonState = digitalRead(yellowButtonPin);
  blueButtonState = digitalRead(blueButtonPin);
  if (yellowButtonState == HIGH && blueButtonState == HIGH){
    Serial.write(3);
  }
  else if (yellowButtonState == HIGH && blueButtonState == LOW){
    Serial.write(2);
  }
   else if (yellowButtonState == LOW && blueButtonState == HIGH){
    Serial.write(1);
  }
  else {
    Serial.write(0);
  }
}

```

My problem is that there are several ground pins on the Arduino, but only one 5V pin, so I can't just simple double the circuits. Connecting the two circuits to different grounds but the same 5V didn't work out, although it seemed to be a good idea. How should I do this properly? To be honest, I actually would want to have three buttons, but I guess going from two to three will be trivial after going from one to two.

# Answer
> 2 votes
Learn about:

Built-in pullup resistors in Arduino Debouncing

and checks this code: https://blog.adafruit.com/2009/10/20/example-code-for-multi-button-checker-with-debouncing/

---
Tags: button
---


# Question
Title: How to prevent ATTiny program from running after I flash it with Arduino?
I am making a simple voltage regulator. The whole idea is to just use ADC to read voltage on output side and based on the result, adjust PWM power. I am using PWM on physical pin 5. That's the same pin as the one connected to Arduino pin 10 on this image below:

This means that if I try to flash the program, ATTiny will start to put PWM power into my Arduino. I don't want that to happen. How can I flash the program safely? Can I do something to prevent it from starting?

# Answer
> This means that if I try to flash the program, ATTiny will start to put PWM power into my Arduino. I don't want that to happen.

Why do you think that is a problem? The "PWM power" cannot be any higher than the supply voltage, and that is 5V. The Arduino has no problem with you providing a 5V PWM signal to an input pin.

The only time it could be a problem is if the pin you are sending the PWM to is set to an output, in which case you could risk overloading the pin. To get around that you just need to insert a small resistor between the ATTiny's pin and the Arduino's pin. 330Ω or so should do it. Just enough to limit the current to a safe value (\< 20mA) but small enough that it won't interfere with the programming communication.

A well design schematic for an Arduino ICSP programmer would have had these resistors in all the data communication lines anyway.
> 4 votes

# Answer
That isn't a problem but if you **really** want to prevent ATtiny generating the PWM signal right after flashing the firmware, then you might add a jumper to some free µC input and put the while loop at the beginning of the program which reads that input and waits until you remove the jumper. For example, you could enable internall pull-up on some free input and put the jumper from that pin to GND. Then in the code you can just wait for the input to become high and then proceed with the rest of the code. Then you can just insert the jumper, flash the firmware, remove the connections between ATtiny and Arduino and then remove the jumper.
> 0 votes

# Answer
The Arduino-as-ISP sketch will turn all the OUTPUT pins, connected to the ATTiny, back to **INPUT**. That way nothing bad can happen, when the ATTiny drives those pins HIGH of LOW.
> 0 votes

---
Tags: pwm, attiny, isp, safety
---