title: Car Control via OBD-II port

text:
# Question
Title: Car Control via OBD-II port
I was wondering if it is possible to send commands through the OBD-II on my car via an Arduino Uno Rev 3 with a CAN-BUS Shield from SEEDStudio. I am just going for basic functions i.e. lock control, window control, lights nothing really outside of those basic functions. My shield is currently in the mail and I was hoping anyone could shed light as to if this is even possible. My car model is a 2004 Mini Cooper S. Thanks.

# Answer
Technically, yes: If you hook up this shield to the car buses through OBD-II, and know which messages to send (e.g., ones that the car will accept and work with), then it will work.

The problem is: There are some "official" messages, basically emission related stuff, that are mandatory on every cars. There are lists of these out there. Unfortunately, most messages are OEM dependent (including those that may control the basic features you mentioned), and they don't want you to mess around this. Said differently: The semantic of CAN frames/messages varies from one car to another.

Being able to send receive CAN frames (which this shield is) is like being able to emit sounds & hear them: Mandatory, if you want to discuss with someone, but useless/not enough if you do not speak the same language.
> 2 votes

---
Tags: arduino-uno, can-bus
---


title: From Arduino to a miniaturized circuit

text:
# Question
Title: From Arduino to a miniaturized circuit
I have a project made with Arduino, and I want to replace it by a miniaturized circuit with just a microcontroller. Is there any tutorial that can guide me in doing this? Any reference is wellcome. Thank you!

# Answer
You can use an Arduino on a breadboard to get you going. From the breadboard, you can then develop a circuit on a pre-made PCB like this:

Then to a custom PCB, if you so desire.
> 4 votes

# Answer
The main question is: Which features do you want to have on your board?

You can start off with the design files of the Arduino board you are using: update what you need (and don't need).

Then, for the manufacturing itself, several approaches will work:

* veroboard & through hole components. Not very practical, not small, but easy;
* DIY manufacturing: toner transfer method, or if you have a CNC, isolation milling;
* Boardhouse (e.g. PCB manufacturer) to whom you send your finished design to have it manufactured.

An alternative would be to use a smaller board, like an Arduino nano: it all depends on what your constraints/goals are.
> 2 votes

---
Tags: arduino-uno, atmega328
---


# Question
Title: How to convert array of chars to array of ints?
I have a rather newbie question but I can't figure it out.

Lets say I have this char array:

```
char array[] = "10,11,12,1,0,1,0";

```

How can I convert it to an array of int like this?

```
int arrayINT[] = {10,11,12,1,0,1,0};

```

# Answer
> 7 votes
If you have a C string containing ASCII numbers with a common delimiter (comma in this case) you can use the `strtok()` function to split it into individual strings. Then you can use `atoi()` to convert those individual strings into integers:

```
char array[] = "10,11,12,1,0,1,0";
int intArray[7]; // or more if you want some extra room?

int ipos = 0;
// Get the first token from the string
char *tok = strtok(array, ",");
// Keep going until we run out of tokens
while (tok) {
    // Don't overflow your target array
    if (ipos < 7) {
        // Convert to integer and store it
        intArray[ipos++] = atoi(tok);
    }
    // Get the next token from the string - note the use of NULL
    // instead of the string in this case - that tells it to carry
    // on from where it left off.
    tok = strtok(NULL, ",");
}

```

Note that `strtok()` is a *destructive* function. It will decimate your existing string with NULL characters as it slices it up.

---
Tags: c++, c, string, array, convert
---


# Question
Title: I2C Master-Slave Arduino system to control array of steppers
trying to make a system where one master Arduino makes moving 9 steppers 28BYJ-48 by 3 stepper on each slave arduino.

While all the parts on their way to me, wonder to check with professionals.

Maybe I've missed something?

Any suggestions and tips are welcome. Thank you.

# Answer
> 0 votes
I think your schematic might be wrong there. Only one MEGA is connected to a positive side of a battery.

The MEGA can only run on 7V to 12V. *BUT PLEASE DO NOT apply the voltage to the `3V3` or `5V` pin.*

```
Microcontroller ATmega1280
Operating Voltage   5V
Input Voltage (recommended) 7-12V
Input Voltage (limits)  6-20V

```

And also, I would only put in another MEGA when you don't have enough I/O pins.

```
Digital I/O Pins    54 (of which 15 provide PWM output)

```

In theory you could use 13 steppers on one MEGA. Try slowly scaling up. You don't need PWM for steppers, maybe you're confused with servo's?

And why not use one of the stepper-driving MEGA's as the master? (In the first picture, slave 1 isn't even connected to the SDA/SCL lines of the I2C bus.

# Answer
> 2 votes
I don't quite understand the problem. A arduino mega would have no problem controlling 9 of these steppers alone. If you are asking about i2c protocol please be more specific about what you need help with.

---
Tags: arduino-mega, stepper
---


# Question
Title: Communication between Arduinos using USB Host Shield
I'm working on a project that needs to use USB to pass serial messages between Arduinos (I can't use I2C or SPI for a few reasons – I especially need USB's support for hot-swapping and address allocation). So far I have the USB Host Shield set up on one Arduino Uno, connected to the standard USB port on another. It appears to be working, as can be seen when I run the board\_qc:

The 'slave' Arduino is just running the following code:

```
void loop() {
  Serial.println("Hello");
  delay(1000);
}

```

On the master, I create a USB object from the USB Host library (https://github.com/felis/USB\_Host\_Shield\_2.0).

```
USB Usb;

void setup() {
    Serial.begin(115200);
    Usb.Init();
}

void loop() {
    if (Usb.getUsbTaskState() == USB_STATE_RUNNING)
    {
        Usb.ForEachUsbDevice(&PrintAllData);
    }
}

void PrintAllData(UsbDevice *pdev)
{
    UsbDeviceAddress adr;
    adr.devAddress = pdev->address.devAddress;
    Serial.println(adr.devAddress, HEX);

    uint8_t msg = 0;
    uint16_t len = 0;
    uint8_t rcode = Usb.inTransfer(adr.devAddress, pdev->epinfo->epAddr, &len, msg);

    if (rcode && rcode != hrNAK) {
     Serial.print(F("\r\nData rcv: "));
     Serial.print(rcode, HEX);
   } else if (len > 0) {
     Serial.print(F("\r\nData Packet: "));
     Serial.print(msg[0]);
   }
}

```

I'm not getting any data through though. Does anyone have any suggestions? Or know of any helpful sample code?

# Answer
Have you tried this lib's documentation? It looks like just doing `init()` and then checking the task state is not enough.

Looking at the source code makes me think you might want to add a call to the main task/state machine, e.g. add a call to `Usb.Task();` to your loop, before your `if` statement.
> 0 votes

---
Tags: serial, usb
---


# Question
Title: How do I reduce this down to a smaller, more permanent prototype?
I've prototyped a little light/sunrise alarm clock w/ an Arduino Uno and a breadboard. How do I go about figuring out what components I'd need to reduce this down in to a more semi-permanent prototype?

Obviously I don't need everything the Uno has to offer and I'd like to slim this down into a custom box I build.

But what sort of microcontroller(s) would I need to size this down? How else can I simplify it?

To be clear, I'm not trying to turn this in to any sort of finished/super-polished product. Just wanting to get out of the breadboard and in to some soldering of something a bit more set in stone.

# Answer
At a bare minimum, you need a power supply, and an AtMega or AtTiny chip.

The AtMega and AtTiny's have an internal clock, 1mhz. It's not terribly accurate for timekeeping purposes (1% error, I think, as opposed to 20ppm = 0.02% for the external clock), but I see you have an RTC, so a 1% drift is probably fine (I can't see your code, so I don't know if the internal time is used for anything). Remember that you will need to adjust your code for the different clock rate, anything that uses anything time-related will run at 1/16th speed (delay, serial comms, etc). You will need to set the fuses to use the internal clock.

If your power source isn't 5v, then you need a transformer.

What type of AtTiny or AtMega you use depends on your code, and how many pins you use. I see 5 pins, they are all used as digital I think? You might get away with one of the 14-pin AtTinys. I suspect your code is probably pretty small. You can probably get away with nearly any AtTiny. To select an AtTiny, go to http://www.atmel.com/products/microcontrollers/avr/tinyavr.aspx

Nick Gammon (who will probably be providing his own answer as I type) has an excellent site on how to put the parts together, at http://www.gammon.com.au/breadboard

This site mentions programming the bootloader. On a low-memory chip, you do not need a bootloader, you can upload your program using SPI (same way as you upload the bootloader in Nick's example). Alternatively, you can use a programmer like the USBASP, which makes the whole process a lot easier. When you build your final board, I strongly suggest putting a 6-pin ICSP header (same as the 2x3 pins on the end of your Arduino board) on, to make reprogramming easier. You plug the USBASP into the 6-pin header, and click File-\>Upload using programmer.

ADDITIONAL:

If you want your project "really nice", you can design and etch your own PCB. If "good enough is good enough" (which for me it always is), I suggest you use stripboard (also known by it's brandname, veroboard).

In either case, spend some time thinking about your exact layout. Use a computer layout tool, and spend some time working out the best layout. I generally spend at least 5 times as much time on the layout, as I do on building the board - if a project is twice as big, I will spend twice as much time soldering, but at least 4 times as long laying it out.
> 4 votes

# Answer
Several steps are required:

1. **Define what you want** to achieve in a clear and explicit manner, eg start documenting your project by writing down your decisions and design goals, for example on a project wiki somewhere. This could be the time where you explore the internet to gather several inspirational sources & modules you want to reuse.
2. **Check that your schematic is correct**, eg that first prototype works reliably. Obviously, going from prototype to a "more permanent prototype" should include checking everything works as expected (getting validation from here would be an option).
3. **Prepare a hardware design**, eg routing on your prefered CAD software. Many options exist: Fritzing, Eagle, Kicad, ... You may need help/tutorials to do this properly
4. **Manufacture the pcb**, or get your board manufactured. Several options are available (see below)
5. **Assemble & test**; depending on results, go back to step 1, 2, 3 ;)

To **check that your schematic** is correct, well, you can post it somewhere. As a starter: your initial post has some errors.

* resistors required for LED
* red (+) seems to be on GND, not +5v (!!)
* using a pulldown for the button where an internal pullup is sufficient is a waste of ressource

Answer above has errors, too (as stated). So make sure your schematic & prototype work before trying to get it more permanent.

To **manufacture the PCB**, several options:

* Veroboard & through hole components. Not small, but cheap, easy & reliable.
* DIY: toner transfer method (numerous examples & howto online) : requires a bit more time/skills, but if you plan to do several boards/experiments, can be worth it. Can be rather cheap. Cannot yield high precision pcb. Note: other DIY PCB manufacturing techniques exist.
* boardhouse contract manufacturing: yields perfect results (if your design files are OK...), can't be quick & cheap (but can be either, relatively)
> 2 votes

# Answer
I did an awful try at making a nice breadboard for it.

BUT.

I think you're better off using some perfboard, small solderable wires and an Arduino Nano.

This because the Arduino Nano has an FTDI chip, crystal and power regulator and is barely bigger than an 328 DIP package.

You could easily mount the pieces of perfboard inside/on your enclosure.

Aim to add the snooze button on top with the settings buttons on the sides. The buzzer could be in the back or other side. The display (if any) should be in the front. Your "Neopixels" are no different than WS2812B "led's".
> 1 votes

---
Tags: arduino-uno
---


# Question
Title: How to combine Leonardo with Ultrasonic sensor?
I am working on an Arduino project that replaces the computer mouse. I want to do this in combination with an ultrasonic sensor. I found some nice examples on youtube, but they didn't post the code. And an example on this website. But I don't get it completely. I don't have much Arduino skills, but do have some. How can you attach for example `echoPinScroll` to a board?

I hope someone can give me advice on how to use this ultrasonic to control my mouse!

```
#include <Mouse.h>

int echoPinCursor=2;
int trigPinCursor=3;

int echoPinBtn=4;
int trigPinBtn=5;
int echoPinScroll=6;
int trigPinScroll=7;
int x;
int y;
long duracionCursor, distanciaCursor;
void setup() {
 Serial.begin(9600);
 pinMode(trigPinCursor, OUTPUT);
 pinMode(echoPinCursor, INPUT);
 pinMode(trigPinBtn, OUTPUT);
 pinMode(echoPinBtn, INPUT);
 pinMode(trigPinScroll, OUTPUT);
 pinMode(echoPinScroll, INPUT);

}

void loop() {

//mover el cursor
int direccionx=moverx();
int direcciony=movery();

Mouse.move(direccionx, direcciony,0);
delay(2);

}

int moverx(){
distanciaCursor=obtener_distanciaCursor();
if (distanciaCursor >= 1  || distanciaCursor <= 11){
   x--;
 }
if (distanciaCursor >= 12 || distanciaCursor <= 24){
   x++;
  }
 return x;
}

int movery(){
distanciaCursor=obtener_distanciaCursor();
if (distanciaCursor >= 25 || distanciaCursor <= 37){
   y--;
   }
if (distanciaCursor >= 38 || distanciaCursor <= 50){
   y++;
  }
return y;
}

long obtener_distanciaCursor(void)
{
digitalWrite(trigPinCursor, LOW);
delayMicroseconds(2);

digitalWrite(trigPinCursor, HIGH);
delayMicroseconds(10);

digitalWrite(trigPinCursor, LOW);
duracionCursor = pulseIn(echoPinCursor, HIGH);

distanciaCursor = duracionCursor/58.2;
return(distanciaCursor);

}

```

# Answer
What is your hardware setup?

From your code, it looks like you're not using the pins `trigPinBtn, echoPinBtn, trigPinScroll, echoPinScroll`. Weird. I can't figure out:

1. which ultrasound module you're using
2. what do you expect, eg which movement(s) in front of which ultrasound sensor shall generate which mouse action(s)

I would recommand having an iterative approach:

1. Play with your ultrasound sensor(s), eg understand properly how to wire them to the arduino, how to interface them (software/lib), what kind of values you can get from them, etc... This will depend on the HW module you have chosen (if any yet).
2. Read the documentation that comes with the mouse lib of the Leonardo and play with it independently/with existing, working examples.

That is divide and conquer: understand each bit before trying to assemble them.

THEN, and only then, you will have a better understanding of the different part of your project. You will then be able to formulate an overview of your project goals, and how you can do it. That is, start documenting your project **before** it is done: doing so will ~~force~~ help you to have a clear idea of **what** it is that you're trying to achieve... and thus how to achieve it.

But yeah, the overall project might look something like this:

```
// Ultrasound distance sensor #1, hooked to the arduino with xxx and yyy; generates movement along the x axis
// Ultrasound distance sensor #2, hooked to the arduino with zzz and ttt ; generates movement along the y axis
// Something for the wheel? The buttons?

//global values & objects
setup()
//initialize hardware& libs

loop()
//get raw ultrasound distances
//translate these into x and y movements
//do something about buttons & wheel?
//update mouse values

```
> 1 votes

---
Tags: arduino-leonardo
---


title: Measuring LPO (Low-Pulse Occupancy)

text:
# Question
Title: Measuring LPO (Low-Pulse Occupancy)
I'm using an Arduino clone (Seeeduino Lotus) together with a Shinyei PPD42NS sensor to measure air quality. The sensor reports its measurement as Low-Pulse occupancy. What would be the best way how to collect the value with Arduino? Currently I'm simply looping for some predefined duration using `pulseIn`:

```
unsigned long starttime;
register unsigned long sample_time; // ms
register unsigned long lowpulseoccupancy = 0; // us

// Wait for the signal to return to HIGH
pulseIn(DUSTPIN, LOW);
// Now start measuring
starttime = millis();
while ((sample_time = (millis() - starttime)) < DUST_SAMPLE_TIME_MS) {
    lowpulseoccupancy += pulseIn(DUSTPIN, LOW);
}

ratio_pct = lowpulseoccupancy / (sample_time * 10.0);

```

Is there a better way? In particular, this tight loop prevents Arduino from doing anything else for 30s (or a similar period).

I was thinking about using interrupts, either triggering on `CHANGE`, or (if that's possible) having two functions, one triggering on `RISING` and another on `FALLING`. Are there any caveats when doing so?

# Answer
You can trigger on `CHANGE`, and check in your handler which case it is:

```
   attachInterrupt(digitalPinToInterrupt(my_pin), my_handler, CHANGE);
    (...)
    void my_handler(void) {
      if(LOW==digitalRead(my_pin)) {
        //do_falling();
      }
      else {
        //do_rising();
      }
    }

```

Another option would be to use a timer to poll your input, and implement a logic on top of this.
> 1 votes

---
Tags: interrupt, digital, input, pulsein
---


title: Take the program from the arduino board

text:
# Question
Title: Take the program from the arduino board
How to remove the program from arduino board which is already there in it.?And I need that program in my arduino IDE how to take it please help me?

# Answer
> 3 votes
You can retrieve the program currently in your Arduino with the `avrdude` tool. This tool comes with the Arduino installation. The way to call it is somewhat OS-dependent. On Ubuntu, for an Arduino Uno, I type:

```
avrdude -p atmega328p -c arduino -P /dev/ttyACM0 -b 115200 -D -U flash:r:prog.hex:i

```

This creates the file `prog.hex` with your program in Intel HEX format. You can save this file if you want to re-install it on the Arduino later. You can also turn this file into an assembly listing with `avr-objdump`:

```
avr-objdump -m avr -Dz prog.hex > prog.lst

```

You may be able to make some sense of this listing if

1. you are well versed in AVR assembly language
2. you have lots of spare time

As others have said, you cannot expect to get the original C++ source back.

# Answer
> 1 votes
You can't. The program in the Arduino IDE is compiled to machine code (bits and bytes basically) and that's what is uploaded to the Arduino.

# Answer
> 1 votes
It's a bit like baking a cake. Or brewing cider. Once you have baked your cake can you get the eggs, flour and sugar back again? Can you make apples from cider? No. And it's the same with compiling. Once you have compiled your source code you can't turn it back into source code again.

---
Tags: arduino-ide
---


title: Open WiFi Configuration Automatically

text:
# Question
Title: Open WiFi Configuration Automatically
Is it possible to have an Arduino Uno + WiFi 101 recognize when the USB cable has been connected and prompt a user to enter a network name and password?

Can this be stored on the Arduino itself or does it need to be something run locally on the user's PC?

# Answer
> 1 votes
To render a UI, you need a PC program. It would handle presenting an interface as well as communicating the user's input to the Arduino over UART. I would recommend writing your own program as it would give you a lot of freedom in the UI design. Processing and Python are good options. To avoid using the IDE, you'll need a USB-TTL adapter cable. If you use the default USB connection, you need the drivers which only ship with the installer AFAIK. To detect the COM port, you can either have the user check the Device Manager or make your program auto-detect it, though this isnt very reliable. This link shows some Python code on detecting the Arduino's port or at least, displaying a list of open ports and allowing the user to choose. You can set the baud rate and other stuff permanently in your code; the COM port is the only variable. Also all handshaking b/w the Arduino and PC can be done without the knowledge of the user.

That said, there are already existing programs (for most common OSes) that can provide minimal functionality. If you dont need a fancy GUI, then **putty** (on Windows) can serve to read input from a user and pass it on to the listening Arduino. You can use putty's default baud rate (9600) in your Arduino sketch so that the user doesnt have to set this. Again, the COM port must be known. Device Manager is the only real option.

With this second approach, you could make a user enter some string (or even a char) in putty to prompt the Arduino to ask for the SSID and password. Once the Arduino is powered, it does nothing but wait for that input string and once it receives it, it sends something like: `Enter SSID:` , the user complies (and presses the Return key to terminate) and this is repeated for the password. The Arduino sketch would look like this:

```
#define MAX_LEN 20  //max length of name or password

char PROMPT[] = "ready\r"  //the initial string input from a user
char SSID[MAX_LEN];  // buffers for the ssid and pwd
char PWD[MAX_LEN];

init_done = 0;  // this var is set when an ssid and pwd have been received

void setup(){
  Serial.begin(9600);
  //anything else
}

void loop(){
  if (!init_done)
    continue;
  //  your other code
}

void get_data(){
  Serial.print("Enter Network SSID: \r\n");
  while (Serial.available() == 0);  // wait for input

  // no timeouts used here; wait till user presses return key
  int i = 0;
  char c;
  while (i < MAX_LEN - 1){  // read chars till the buffer is almost full
    c = Serial.read();
    if (c == '\r') // means end of input
      break;
    SSID[i++] = c;
    while (Serial.available() == 0);  // wait for next char
  }
  SSID[i] = 0;  // null terminate
  while (Serial.read() != -1);  // flush serial buffer

  Serial.print("Enter password: \r\n");  //same as before
  while (Serial.available() == 0);

  i = 0;
  while (i < MAX_LEN - 1){
    c = Serial.read();
    if (c == '\r') // end of input
      break;
    PWD[i++] = c;
    while (Serial.available());
  }
  PWD[i] = 0;
  while (Serial.read() != -1);

  //Serial.print("Done.");
  init_done = 1;
}

void serialEvent(){
  if (!init_done){
    while (Serial.peek() != PROMPT[0]) // read off any garbage
      Serial.read();
    int i = 0;
    while (1){
      if (Serial.peek() == PROMPT[i++]) // compare received chars to PROMPT
        Serial.read();
      else
        return

      if (i == sizeof(PROMPT)){ // read enough chars
        while (Serial.read() != -1);  // flush the buffer
        get_data();  // get ssid and so on
      }
    }
  }

```

---
Tags: wifi, networking
---


# Question
Title: GPRS SIM900 and GPS NEO-6M don't work together
I'm trying to get GPS coordinates and send them to my API through the GPRS SIM900 and GPS NEO-6M shields.

In `setup()`, I first start the GPRS shield and call the function that connects to the internet. Then in `loop()`, I start to capture GPS coordinates and finally I send to my API, but my code doesn't work with this logic. I'd like to connect once and get GPS coordinates and send them to the API many times making a tracking.

The app stops if I run the code. `connectToInternet()` in `setup()` and `getGpsPosition()` in `loop()`. The SIM900 shield connects but the NEO6-M shield does not display the coordinates. The GPS only captures the coordinates if I do not connect to the internet.

Could someone help me? Following is my code and printout of the response to AT commands.

```
#include <SoftwareSerial.h>
#include <TinyGPS++.h>
#include <inetGSM.h>

static const int RXPin = 4, TXPin = 3;
InetGSM inet;
TinyGPSPlus gps;
SoftwareSerial serialGps(RXPin, TXPin);
char msg[50];
boolean started = false;
const char* dataCoord = "";

void setup() {
  // Serial connection.
  Serial.begin(19200);
  Serial.print(F("------------------------------------------------- \r\n"));
  Serial.println(F("Starting App Tracking Arduino"));
  Serial.print(F("------------------------------------------------- \r\n"));
  // Turn on GPRS
  powerUpGprs();
  // Start configuration of shield SIM900 with baudrate.
  if (gsm.begin(2400)) {
    Serial.println(F("\nstatus=READY"));
    started = true;
  } else Serial.println(F("\nstatus=IDLE"));
  if (started)
    connectToInternet();
  // Start configuration of shield GPS NEO-6M with baudrate.
  serialGps.begin(9600);
}

void loop() {
  // This sketch displays information every time a new sentence is correctly encoded.
  while (serialGps.available() > 0)
    if (gps.encode(serialGps.read())) getGpsPosition();
}

/**
  Power up
*/
void powerUpGprs() {
  pinMode(9, OUTPUT);
  delay(100);
  digitalWrite(9, HIGH);
  Serial.println(F("\nPower Up SIM900!"));
}

/**
  Connect to Internet via GSM
*/
void connectToInternet() {
  Serial.print(F("\r\n"));
  Serial.print(F("------------------------------------------------- \r\n"));
  Serial.print(F(" CONNECT TO INTERNET \r\n"));
  Serial.print(F("------------------------------------------------- \r\n"));
  //GPRS attach, put in order APN, username and password.
  if (inet.attachGPRS("zap.vivo.com.br", "vivo", "vivo"))
    Serial.println(F("status=ATTACHED"));
  else
    Serial.println(F("status=ERROR"));
  delay(1000);
  //Read IP address.
  gsm.SimpleWriteln("AT+CIFSR");
}

/**
  Get GPS position
*/
void getGpsPosition() {
  Serial.print(F("\r\n\r\n"));
  Serial.print(F("------------------------------------------------- \r\n"));
  Serial.print(F(" GET POSITON \r\n"));
  Serial.print(F("------------------------------------------------- \r\n"));
  // geolocation
  TinyGPSDate &d = gps.date;
  TinyGPSTime &t = gps.time;
  char* timestamp;
  if (!d.isValid()) {
    timestamp = "00/00/0000 00:00:00";
  } else {
    char sz[32];
    sprintf(sz, "%02d/%02d/%02d %02d:%02d:%02d",
      d.day(), d.month(), d.year(),
      t.hour(), t.minute(), t.second());
    timestamp = sz;
  }
  String position = String("");
  position.concat(String("timestamp=") + String(timestamp));
  position.concat(String("&latitude=") + String(gps.location.lat(), 6));
  position.concat(String("&longitude=") + String(gps.location.lng(), 6));
  position.concat(String("&altitude=") + String(gps.altitude.meters()));
  position.concat(String("&speed=") + String(gps.speed.kmph()));
  Serial.println(dataCoord);
  send2Api();
}

/**
  Send To API, The function inet.httpPOST(),
  this is submit method POST via http request
*/
void send2Api() {
  Serial.print(F("\r\n\r\n"));
  Serial.print(F("------------------------------------------------- \r\n"));
  Serial.print(F(" SEND TO API\r\n"));
  Serial.print(F("------------------------------------------------- \r\n"));
  // Read until serial buffer is emapty.
  gsm.WhileSimpleRead();
  // TCP Client HTTP, send a POST request to the server and save the reply.
  int numdata = inet.httpPOST("api.myapp.com.br", 80, "/geolocations ", dataCoord, msg, 100);
  // Print the results.
  Serial.print(F("\nNumber of data received: "));
  Serial.println(numdata);
  Serial.print(F("\nData received: "));
  Serial.println(msg);
};

```

If I connect to internet the GPS does not display the coordinates.

But if I don't connect to internet the GPS displays the coordinates.

# Answer
You are using 2 SoftwareSerial instances and you're losing bytes when you aren't listening to the other port. Also your `inetGSM` library uses pins 3 for RX with the SIM900 and in your Arduino sketch, pin 3 is also the Arduino TX pin to the GPS module. Therefore, anything sent by the Arduino over pin 3 is received by both modules. Confusion.

* Use the GPS module with another pair of pins, maybe, 7 for RX and 8 for TX. Connect the GPS TX to 7 and its RX to 8.
* Try adding: `gsm._cell.listen();` right before this line:

`// Read until serial buffer is empty.
gsm.WhileSimpleRead();`
* Also add `serialGps.listen();` right before this line:

`// Print the results.
Serial.print(F("\nNumber of data received: "));`

Refer to this answer for more details.
> 2 votes

---
Tags: arduino-uno, gsm, communication, gps, command-line
---


title: Splitting String from Serial

text:
# Question
Title: Splitting String from Serial
I am currently working on a program for an Arduino uno and want to, in the program, when it receives a 16 digit number from a serial transmition, it will split the 16 digit number into 4 separate 4 digit numbers.

For Example: The computer sends the Arduino the number 1100115011001150 and I want the Arduino to break the number so that "Avalue" would equal 1100, "Bvalue" would equal 1150, "Cvalue" would equal 1100 and so on...

Thanks for any help you can provide!

# Answer
> 1 votes
```
char ArrayBuffer[][4] = {};         // holds four characters, must be

```

declared as global to loop()

in

```
loop()
{
byte Index = 0;                    // initialize array index
if(Serial.available())             // have data in Serial buffer
{
byte Count = Serial.readBytes(ArrayBuffer[Index],4); // read       //4             //characters     into array buffer , returns actual number //of        characters //read and times out if less than 4 characters are //currently in Serial buffer
 Serial.println(ArrayBuffer[Index]); // print buffer to monitor
}while(++Index != 4);              // read 4 by 4 characters from incoming stream
}

```

... continue with loop - process ArrayBuffer as required }

This is one way to get the incoming stream from Serial buffer into for individual buffers, however, it is better, less chance of misdirecting the data into wrong buffer (index) to read the entire buffer at once instead of using he readBytes four times. Just my opinion, your mileage will vary.

PS what is the trick to format the code and text correctly ? This is a mess. I cannot get the code block to indent, I can get only the first ( four spaces line.

# Answer
> 1 votes
```
while (Serial.available() < 16);   // wait for 16 chars to come          easiest way to do this
for (int i = 0; i < 4; i++){      // for each number
    for (int j = 0; j < 4; j++){    // for each digit in the number
        nums[i] *= 10;
        nums[i] += Serial.read() - '0';

```

Where did my last post - comment on this code went? It was suppose to wait for "peers" approval, per note I got after I posted it.

This is not the best way to use "available()", beside what will happen if 16 characters never arrive?

# Answer
> 0 votes
```
int nums[] = {0, 0, 0, 0};   // must be always reset to zero if you will repeat this process
while (Serial.available() < 16);   // wait for 16 chars to come in; easiest way to do this
for (int i = 0; i < 4; i++){      // for each number
    for (int j = 0; j < 4; j++){    // for each digit in the number
        nums[i] *= 10;
        nums[i] += Serial.read() - '0';

//while (Serial.available() == 0);
//Serial.read();  // in case you use an extra character to separate numbers

A = nums[0];
B = nums[1];
C = nums[2];
D = nums[3];

```

If you are using a character or characters to delimit the 16-digit numbers being received, make sure to read off those extra characters before running the while loop again.

# Answer
> 0 votes
Not tested but should work.

```
int nums[] = {0, 0, 0, 0};
String inString = "";
while (Serial.available() >= 16) {
  for (int k =0;k<4;k++) {
    for (int i =0;i<4;i++) {
      int inChar = Serial.read();
      if (isDigit(inChar)) {
        inString += (char)inChar;
      }
    }
    nums[k]=inString.toInt();
    inString = "";
  }
  Serial.println(nums[0]);
  Serial.println(nums[1]);
  Serial.println(nums[2]);
  Serial.println(nums[3]);
}

```

---
Tags: serial, string
---


title: Shared Memory using SHM Library

text:
# Question
Title: Shared Memory using SHM Library
I am trying to read sensor data from a FIFO buffer embedded in the sensor (LSM9DS1), and store that data on a Teensy 3.2 board to later be put in a file. I can only read 6 bytes at a time from the FIFO.

The sensor's FIFO is read by the Teensy when an interrupt triggers an isr function. I want to store the data on the Teensy memory. Then, after the ISR store the memory, I plan to parse the data and do a few simple calculations in the loop() function before writing it to file.

What is the best way to accomplish this? I tried using a FIFO library for Arduino here, but it doesn't work with interrupts. I encountered errors with declaring it as a volatile memory type.

Could I used shared memory using the sys/shm.h library from C++? If so, how can I import this to my arduino code?

# Answer
> 2 votes
*Shared memory* only makes any sense in two combined situations:

1. You have a kernel arbitrating processes, threads and memory allocation, with process isolation
2. You have multiple threads or processes in your application

You certainly don't have number 1 unless you can install an operating system on the Teensy 3.1 (some RTOS may provide a SHM analogue).

As for 2 yes, it could be said you have two threads. But you don't have any form of process isolation, so what one "thread" can access the other "thread" can access.

Both the ISR and the `loop()` function have access to the exact same memory. Any global variables are accessible to both. You may need to inform the compiler that a variable is modified in one thread and read in another though. The simplest way of doing that is to make the variable *volatile* by prepending the `volatile` keyword to the definition.

---
Tags: teensy, memory-usage
---


# Question
Title: Pin 13 fires relay when powering on... How to disable?
Pin 13 fires relay when powering on... How to disable? I'm using pro mini 5v 16MHz and a DC 12V 2 Channel Relay Module Optocoupler. The relay Jd-VCC is powered by a 12V and it's VCC is 5V (the same as Arduino VCC). The relay is active low and I soldered pins 12 and 13 of the pro mini to IN1 and IN2 of the relay.

When I power the board up it cycles Pin 13(and the on-board LED) ON and then OFF before resuming to the code I uploaded. I believe that this can be fixed by disabling this blinking function in the startup process.

I understand that I can use other pins. Why not learn how to remove this from startup, if I prefer to use this pin for circuit layout purposes?

Any help would be much appreciated. Most of my searches ended up with people using the pin as an input... My issue is when using D13 as an active low pin it has some funky behavior at startup but then works as programmed.

Thanks!!!

# Answer
> 11 votes
There are three things you can do:

1. Remove the bootloader entirely and program the board with a hardware programmer (USB-ASP, Another Arduino, etc).
2. Edit the bootloader source, recompile, and reinstall it to the board using a hardware programmer (as in option 1).
3. Just don't use pin 13 for the relay.

Of the three options the third one is by far the simplest.

---
Tags: pins, bootloader, arduino-pro-mini, relay
---


title: Get servo to travel full length

text:
# Question
Title: Get servo to travel full length
Recently we purchased servos for use in an Arduino and began testing with servos. It turned out that the uSec for the servos differed from the online documentation and we had to find the min and maxes of the uSecs manually:

```
while (Serial.available()) {
    char c = Serial.read();  //gets one byte from serial buffer
    readString += c; //makes the string readString
    delay(2);  //slow looping to allow buffer to fill with next character
}

if (readString.length() >0) {
    Serial.println(readString);  //so you can see the captured string
    int n = readString.toInt();  //convert readString into a number
    Serial.print("writing Microseconds: ");
    Serial.println(n);
    myServo.writeMicroseconds(n);
    readString = ""; //empty for next input
}

```

The issue is that the servos don't travel the full 180 degree advertised price (more like 135-160) and that lack of angular distance is affecting performance of one of our products. **The servos can even mechanically travel a noticeable distance farther than 180, but not "programmatically" farther even when given a larger PWM uSec value that the observed "max" PWM value**

---

**What I've found**

I looked around and apparently there are "Servo Programmers" to calibrate endpoints and midpoints, but cost an arm and a leg. I find it strange that I would have to "program" my servos. I was part of an First (FTC) robotics team using tetrix/nxt electronic control systems, and never noticed a problem with uSec values or not getting the full range of motion using the same brand of servos I currently am now.

---

> How can I perform a low cost, easy way to simply **get the full range of motion I paid for**?

# Answer
> 1 votes
This is an **analog servo**, so there is no endpoint calibration **on the servo side**. This type of calibration is for digital servos (which can be tuned) and controllers. On the servo description page, they talk about a stretcher. This is a translation tool to help with old controllers: usually servos have a narrower band: 1000us to 2000us for 0° to 180°. Therefore old controllers can only do 1000us to 2000us, and would fail to achieve full range with this servo, which requires 600us to 2400us

Also, note that RC servo input signal isn't really a PWM: duty cycle doesn't matter, only lengh of the pulse does.

Your servo doc says: 600us to 2400us for -90° to +90°, which correspond to what the Servo lib does by default according to its documentation. You should be fine. What are the results of a super simple sweep-like code? eg:

```
loop() {
  myServo.writeMicroseconds(600);
  delay(2000);
  myServo.writeMicroseconds(2400);
  delay(2000);
}

```

---
Tags: arduino-uno, pwm, servo
---


# Question
Title: Connecting an arduino uno to an arduino due
So I am trying to get my arduino uno to talk to my arduino due but I'm having issues getting the data outputted on the due side. My arduino uno is the master while the due is the slave. The sensor is connected to the uno and I just require the arduino due to receive and spit out the data as it has a faster sampling rate than the arduino uno. I connected them along the serial (Tx and Rx) lines. And I'm using Serial3 on my arduino due to receive the transmitted data. Both arduinos are grounded together. But powered differently by usb cables connected to my machine. On the arduino uno end ( for brevity sake) the data is sent in binary with the $ sign as the starter bit. Here is the code for the receiving end ( the slave). I just can't seem to get the data out on the serial monitor.

```
    byte b = '$';
    unsigned char buffer[12];
    int count =0;

    void setup() {
    Serial.begin(115200);
    Serial3.begin(115200);
    delay(5);

    }

   void loop() {
   if(Serial.available())
   {
    if (b == Serial.available())
   {
    while(Serial.available())
    {
      buffer[count++] = Serial.read();
       if(count == 12)break;
      //Send the byte to serial port three
      Serial3.write(buffer, count);
    }
 }

 if (Serial3.available()){
  //get a byte from serial port 3
  if(b == Serial3.available()){
    buffer[count++] = Serial3.read();
    //Send the byte to the USB serial port
    Serial.write(buffer, count);
  }
 }
 Serial.println("lyca");
 }
  }

```

# Answer
> 1 votes
```
if(Serial.available())
{
 if (b == Serial.available())
{
 while(Serial.available())
 {

```

I think you may be getting your knickers in a twist there.

... Is serial available? Yes. Is serial available? Still yes! But yes doesn't equal '$'!!!... WHAT?!

You really really need to rethink your understanding of serial communication.

**Read this: http://hacking.majenko.co.uk/reading-serial-on-the-arduino**

# Answer
> 0 votes
There seem to be a confusion on Serial & Serial3. You say that:

* Serial is used to send back debug data to the PC
* Serial3 is used to get data from the master

But this is not clear/coherent to your code. Let's try to see your code with proper indentation. I added comments.

```
void loop() {
  if(Serial.available()) { //isnt Serial your debug port? did you mean Serial3?
    if (b == Serial.available()) { //same. Serial3? also, read() instead of available() ?
      while(Serial.available()) { //same. Serial3?
        buffer[count++] = Serial.read(); //Serial3?
        if(count == 12) {
          break; //will this work for several frames? how can count ever go back to 0?
        }
        Serial3.write(buffer, count); //isnt Serial your debug output?
      }
    }
//your indentation didnt show it, but we're still guarded by the first 'if' here.
//Also I guess you meant Serial here?
    if (Serial3.available()) {
//why check for a SoF? what do you do with data coming up fro the debug PC?
      if(b == Serial3.available()) {
//messing with data in your buffer, potentially outside of it? (count can be>11 here)
        buffer[count++] = Serial3.read();
        Serial.write(buffer, count);
      }
    }
    Serial.println("lyca");
  }
}

```

What about this (code below still has several flaws, but should perform better than yours)

```
void loop(void) {
  if(Serial3.available() > 0) { //available data from master?
    while(Serial3.available() > 0) { //if statement above for clarity, this while on its own would be enough
      inByte = Serial3.read();
      if(inByte  == SOF_BYTE) { //is this a start of frame?
        mybuff.ptr = 0; //let's say we dump everything in buff whenever we get a new SoF
        Serial.println("SoF received");
      }
      else { //let's not keep SoF
        mybuff.append(inByte);
      }
    }
  }
  if(mybuff.size >= FULLFRAME_SIZE) { //we've got a full frame, output it
    Serial.print("Full frame received:");
    Serial.println(mybuff.string);
    mybuff.ptr = 0; //now that we've consumed the frame, kill it
  }
  else {
    Serial.print(".") // no frame, show progress/still alive
  }
  delay(refreshtime);
}

```

---
Tags: arduino-uno, serial, accelerometer
---


title: Arduino CAN SPI Configuration problem

text:
# Question
Title: Arduino CAN SPI Configuration problem
I am using an Arduino UNO along with a Cooking Hacks CAN Bus Module and Multiprotocol Radio Shield. The CAN module is connected to the radio shield which is plugged into the Arduino. I got this radio shield keeping future applications in mind where I can combine multiple protocols, for eg. CAN and Bluetooth.

I connected them through an OBD2-DB9 cable to the car's OBD port but noticed that I was not really getting any messages. Well I am getting messages but just:

```
   -- Constructor Can(uint16_t speed) --
   SPI configured
   The MCP2515 has been successfully reset, configuration mode activated
   Speed=500kps
   -- End Constructor Can(uint16_t speed) --

   Data in buffer 0
   id: 7FF  rtr: FFFFFFFF => Data in buffer 0
   id: 7FF  rtr: FFFFFFFF => Data in buffer 0
   id: 7FF  rtr: FFFFFFFF => Data in buffer 0

```

After analysing the connections, I realised that the hardware is probably fine since the continuity between the pins of the cables is fine and the CAN module(MCP2515 + MCP2551) is receiving power and I also checked the voltages at the pins and think they're mostly fine apart from a few pins which I'm not sure about. Which brings me to the software issue. I can see that the SPI is not getting configured properly and the MCP2515 controller doesn't enter configuration mode which means the bit times defined are not being used and hence the controller is not initialising like it should. I even tried manually changing to configuration mode by changing the values of the REQOP bits of the CANCTRL register as opposed to doing a software reset which was how I was doing it initially. Even then, no luck. To verify the SPI connection, I chose a random read/write control register like BFPCTRL and wrote a value to it and then read it back to verify that it matched the values I wrote. However, the value read back is not the same as the value I wrote. Also, the controller only has trouble going into configuration mode. It seems to change to normal and listen only mode without problem since the CANSTAT register displays the correct values for the REQOP bits. I don't understand why the controller has problem entering configuration mode but no problem changing to the other modes. Can anybody help me?

SPI Code:

```
    bool CAN::begin(uint16_t speed)
    {
    #if (DEBUGMODE ==1 )
    Serial.println("-- Constructor Can(uint16_t speed) --");
    #endif

    //Initialization SPI
    SPI.begin();
    SPI.detachInterrupt();
    SPI.setBitOrder(MSBFIRST);
    // both mode 0 & 3 should work
    SPI.setDataMode(SPI_MODE0);

    //Set the SPI frequency
    SPI.setClockDivider(SPI_CLOCK_DIV4);

    #if (DEBUGMODE==1)
    Serial.println("SPI configured");
    #endif

    //Configure MCP2515 pins
    pinMode(CAN_CS,OUTPUT);
    pinMode(CAN_INT,INPUT);
    digitalWrite(CAN_CS,HIGH);

    writeRegister(BFPCTRL, (1<<B0BFM) | (1<<B1BFM));
    int dat = readRegister(BFPCTRL<<2);
    Serial.println(dat);

    //Software resets MCP2515
    reset();
    delay(100);
    //After the reset, controller enters configuration mode
    dispMode();

```

When I read back the values of B0BFM and B1BFM bits, they should be 1 but the display says that their values are 0.

```
   void CAN::writeRegister( char direction, char data )
   {
   //CS low to select the MCP2515
   digitalWrite(CAN_CS,LOW);

  SPI.transfer(SPI_WRITE);
  SPI.transfer(direction);
  SPI.transfer(data);

  //CS line again to release
  digitalWrite(CAN_CS,HIGH);
   }

  char CAN::readRegister(char direction)
  {
  char data;
  //CS low to select the MCP2515
  digitalWrite(CAN_CS,LOW);

  SPI.transfer(SPI_READ);
  SPI.transfer(direction);
  //Read data SPI
  data = SPI.transfer(0xff);

  //CS line again to release
  digitalWrite(CAN_CS,HIGH);
  return data;
  }

```

# Answer
In SPI protocol you'll need to read the SPI buffer twice because the data you wrote will be read by the IC and the IC will respond to it in the next communication and that's when you know.

Also, by looking at the message, I see that your IC is working fine, but is your CAN bus initialised properly? I'm a FSAE team member and I've faced this issue with the CAN Bus termination resistances and the ODB-II configuration on the Sparkfun CAN Bus shield.

Also, have you tried any other libraries for the CAN Shield? For me the seeedstudio library of their CAN shield worked very well.
> 2 votes

---
Tags: arduino-uno, spi, can-bus
---


# Question
Title: How to recover from DHCP Renewal and Rebind failures?
I'm using an Ethernet shield with the built-in Ethernet library. I obtain an IP address using DHCP, and call `Ethernet.maintain()` periodically to ensure that the DHCP lease is renewed as required. So far I've never seen this fail, but `maintain()` can return error codes for renew fail and rebind fail and I assume that I should be handling them. What conditions would cause these errors to occur, and what's the best practise for recovering from them? Is it enough to call `Ethernet.maintain()` repeatedly until it returns cleanly, should I call `Ethernet.begin()` to reinitialise the Ethernet shield, or would it be best to reset both the Arduino and Ethernet shield using the watchdog timer?

# Answer
> 0 votes
Possible causes:

* The DHCP server might be down.
* Or it might have lost its state (but I think they try really hard to preserve the list of leases).
* Or some other cause which makes the server unavailable/unwilling to renew the lease.

Solutions:

* If you can wait, you can retry, but otherwise I'd just say try to obtain a new lease, unless for some reason you *really* want to stick to the IP from the previous lease.
* If you control the server and your network is kinda stable, you could assign a fixed IP to your device configure the server to associate it with the MAC address you gave to your device. In general, when the network setup is really stable, this might be preferable, since other entities on the network will probably cache the IP of your device and use it, should the DNS fail as well (ex: dnsmasquerade works both as dhcp server and dns). Similarly, your device doesn't have to worry anymore of the DHCP lease, because it's permanent.

---
Tags: ethernet
---


# Question
Title: My RTC is returning a sporadic date/time
RTC seems to be sporadically returning bogus date/times. Here are the logs from my serial monitor:

```
2016/3/23 8:19:46
2017/3/23 8:19:46
2016/3/23 8:19:46
2016/3/23 8:19:46
2016/3/23 8:19:46
2016/3/23 8:19:46
2016/3/23 8:19:46
2016/3/23 8:19:46
2016/3/23 8:19:46
2165/165/165 15:19:46
2016/3/23 8:19:46
2016/3/23 8:19:46
2016/3/23 8:19:46
2016/3/23 8:19:46
2016/3/23 8:19:46
2016/3/23 8:19:46
2016/3/23 8:19:46
2016/3/23 8:19:46
2016/3/23 8:19:46

```

That `2165/165/165 15:19:46` appears throughout the logs.

Here's the relevant code:

```
#include <Wire.h>
#include "RTClib.h"

RTC_DS1307 rtc;

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

  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }
  if (! rtc.isrunning()) {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
    rtc.adjust(DateTime(__DATE__, __TIME__));
  }
}

void loop() {
  DateTime now = rtc.now();

  Serial.print(now.year(), DEC);
  Serial.print('/');
  Serial.print(now.month(), DEC);
  Serial.print('/');
  Serial.print(now.day(), DEC);
  Serial.print(" ");
  Serial.print(now.hour(), DEC);
  Serial.print(':');
  Serial.print(now.minute(), DEC);
  Serial.print(':');
  Serial.print(now.second(), DEC);
  Serial.println();
}

```

I have a Grove RTC module.

# Answer
Previous reports of this RTC problem (,,) attribute it to hardware issues, such as broken wires (to SCL or to battery) and overvoltage (`>`3.6 V supply vs 3 to 3.3 V).

If your setup uses breadboards or other temporary connections, you might try adding some redundant wires. If your setup uses soldered connections, go over them carefully, looking for shorts and opens; or use a solder sucker / solder wick to remove old solder; then solder anew to make fresh, bright connections.

If you don't locate a hardware problem (and perhaps even if you do) you could add error-testing to your sketch. That code would see if all relevant fields have valid, in-range values. If any fields are invalid, it would delay a few milliseconds and then reread the RTC.
> 1 votes

# Answer
The RTC library does not check for communications success. In particular, here:

```
DateTime RTC_DS1307::now() {
  Wire.beginTransmission(DS1307_ADDRESS);
  Wire.send((byte) 0);
  Wire.endTransmission();

  Wire.requestFrom(DS1307_ADDRESS, 7);
  uint8_t ss = bcd2bin(Wire.read() & 0x7F);
  uint8_t mm = bcd2bin(Wire.read());
  uint8_t hh = bcd2bin(Wire.read());
  Wire.read();
  uint8_t d = bcd2bin(Wire.read());
  uint8_t m = bcd2bin(Wire.read());
  uint16_t y = bcd2bin(Wire.read()) + 2000;

  return DateTime (y, m, d, hh, mm, ss);
}

```

There should be a check for a zero returned from `Wire.endTransmission()`. It isn't otherwise possible to detect if the data is invalid (if we got the endTransmission OK) however generally speaking I2C will return 0xFF if the transmission has ceased.

The code in the library for `bcd2bin` is this:

```
static uint8_t bcd2bin (uint8_t val) { return val - 6 * (val >> 4); }

```

You can see that if passed 0xFF (255) it will return:

```
   255 - (6 * 15) = 165

```

Thus if any of the minutes, hours, day or month (which are not further affected in the code above) are 165 (or if the year is 2165) you can assume the whole date/time is bad.
> 4 votes

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


# Question
Title: ISR executes twice if data coming through SoftwareSerial
I am using Arduino Pro Mini to get GPS info from a u-blox NEO-M8N chip and display it on a Adafruit OLED display. NEO-M8N has a PPS(pulse per second) output which is aligned to GPS's second. Because UART and deserialization is slow, I use PPS signal to make time displays more accurately. The PPS(time pulse) signal and UART message are coming like this:

On my Arduino, SoftwareSerial RX/TX is on pin 7/8 (but only use pin 7 because Arduino has no message to send to NEO-M8N), and the interrupt(PPS) is on pin 2. If I just connect pin 7, display update once per second as intended; if I just connect pin 2, time increased by one second per second as intended. BUT if connect them both, `((`time will increased more than one second per second`)` and `(` `processGPS()` will lost sync with upcoming UBX(u-blox message format) message`))` occasionally.

And here is the entire code:

```
#include <SoftwareSerial.h>
#include <Adafruit_SSD1306.h>

#define OLED_RESET 9
Adafruit_SSD1306 display(OLED_RESET);

#if (SSD1306_LCDHEIGHT != 64)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif

// Connect the GPS RX/TX to arduino pins 7 and 8
SoftwareSerial S_Serial = SoftwareSerial(7,8);
int intpin = 2;
volatile int state = LOW;

const unsigned char UBX_HEADER[] = { 0xB5, 0x62 };

struct NAV_PVT {
  unsigned char cls;
  unsigned char id;
  unsigned short len;
  unsigned long iTOW;
  unsigned short year;
  byte month;
  byte day;
  byte hour;
  byte miniute;
  byte sec;
  unsigned char valid;
  unsigned long tAcc;
  long nano;
  byte fixType;
  unsigned char flag;
  unsigned char flag2;
  byte numSV;
  long lon;
  long lat;
  long height;
  long hMSL;
  unsigned long hAcc;
  unsigned long vAcc;
  long velN;
  long velE;
  long velD;
  long gSpeed;
  long headMot;
  unsigned long sAcc;
  unsigned long headAcc;
  unsigned short pDop;
  byte reserved1[6];
  long headVeh;
  byte reserved2[4];
};

NAV_PVT pvt;

void calcChecksum(unsigned char* CK) {
  memset(CK, 0, 2);
  for (int i = 0; i < (int)sizeof(NAV_PVT); i++) {
    CK[0] += ((unsigned char*)(&pvt))[i];
    CK[1] += CK[0];
  }
}

bool processGPS() {
  static int fpos = 0;
  static unsigned char checksum[2];
  const int payloadSize = sizeof(NAV_PVT);

  while ( S_Serial.available() ) {
    byte c = S_Serial.read();
    if ( fpos < 2 ) { //SYNC
      if ( c == UBX_HEADER[fpos] )
        fpos++;
      else
        fpos = 0;
    }
    else {
      if ( (fpos-2) < payloadSize )
        ((unsigned char*)(&pvt))[fpos-2] = c;

      fpos++;

      if ( fpos == (payloadSize+2) ) {
        calcChecksum(checksum);
      }
      else if ( fpos == (payloadSize+3) ) {
        if ( c != checksum[0] )
          fpos = 0;
      }
      else if ( fpos == (payloadSize+4) ) {
        fpos = 0;
        if ( c == checksum[1] ) {
          return true;
        }
      }
      else if ( fpos > (payloadSize+4) ) {
        fpos = 0;
      }
    }
  }
  return false;
}

void pps()
{
  state=!state;
}

void PrintScreen()
{
  display.clearDisplay();

  //Size 2
  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.setCursor(0,0);
  float sik = (pvt.gSpeed / 100) / 3.6f;
  if (sik<100)
    display.print(" ");
  if (sik<10)
    display.print(" ");
  display.print(sik,1);//SpeedInKph
  display.setCursor(84,0);
  if (pvt.numSV<10)
    display.print(" ");
  display.print(pvt.numSV);//SV

  //Size 1
  display.setTextSize(1);
  display.setCursor(60,8);
  display.print("km/h");
  display.setCursor(63,0);
  display.print("CHL");
  display.setCursor(108,8);
  display.print("SVs");
  display.setCursor(108,0);
  switch (pvt.fixType){
    case 0:
      display.print("N.F");
      break;
    case 2:
      display.print("2D");
      break;
    case 3:
      display.print("3D");
      if ((byte)pvt.flag & 2)
        display.print("+");
      break;
    default:
      display.print("INV");
      break;
  }

  long  temp;
  //Line 1
  display.setCursor(0,16);
  if (pvt.lat >= 0)
    temp = pvt.lat;
  else
    temp = -pvt.lat;
  if (temp >= 1000000000)
    display.print("lat:");
  else
    if (temp >= 100000000)
      display.print("lat: ");
    else
      display.print("lat:  ");
  display.print(temp / 10000000);display.print(".");
  long temp2 = 1000000;
  temp = temp % 10000000;
  while ((temp / temp2 == 0)&&(temp2>1))
  {
    display.print("0");
    temp2 /= 10;
  }
  display.print(temp);
  if (pvt.lat >= 0)
    display.print("N");
  else
    display.print("S");
  temp = 10000;
  while (((pvt.pDop / temp) == 0)&&(temp>1))
  {
    display.print(" ");
    temp /= 10;
  }
  display.println(pvt.pDop);

  //Line2
  if (pvt.lon >= 0)
    temp = pvt.lon;
  else
    temp = -pvt.lon;
  if (temp >= 1000000000)
    display.print("lon:");
  else
    if (temp >= 100000000)
      display.print("lon: ");
    else
      display.print("lon:  ");
  display.print(temp / 10000000);display.print(".");
  temp2 = 1000000;
  temp = temp % 10000000;
  while ((temp / temp2 == 0)&&(temp2>1))
  {
    display.print("0");
    temp2 /= 10;
  }
  display.print(temp);
  if (pvt.lon >= 0)
    display.print("E");
  else
    display.print("W");
  display.println(" HEAD");

  //Line3
  display.print("hMSL:");
  if (pvt.hMSL < 0)
    pvt.hMSL = -pvt.hMSL;
  temp = 10000000;
  while (((pvt.hMSL / temp) == 0)&&(temp>1000))
  {
    display.print(" ");
    temp /= 10;
  }
  display.print((pvt.hMSL % 100000000) / 1000);display.print(".");
  if ((pvt.hMSL % 1000) < 100)
    display.print("0");
  if ((pvt.hMSL % 1000) < 10)
    display.print("0");
  display.print(pvt.hMSL % 1000);
  display.print("|");
  temp = pvt.headMot / 100000;
  if (temp < 100)
    display.print(" ");
  if (temp < 10)
    display.print(" ");
  display.print(temp);display.print(".");
  temp2 = (pvt.headMot%100000)/1000;
  if (temp2<0)
    temp2 = -temp2;
  if (temp2<10)
    display.print("0");
  display.println(temp2);

  //Line4
  display.print("h,vAcc:");
  if (pvt.hAcc >= 100000)
    display.print("  >100");
  else
  {
    display.print(pvt.hAcc / 1000);display.print(".");
    if (pvt.hAcc % 1000 < 100)
      display.print("0");
    if (pvt.hAcc % 1000 < 10)
      display.print("0");
    display.print(pvt.hAcc % 1000);
  }
  display.print(",");
  if (pvt.vAcc >= 100000)
    display.print(" >100");
  else
  {
    display.print(pvt.vAcc / 1000);display.print(".");
    if (pvt.vAcc%1000 < 100)
      display.print("0");
    if (pvt.vAcc%1000 < 10)
      display.print("0");
    display.print(pvt.vAcc%1000);
  }
  display.println("m");

  //Line5
  display.print("V:");
  if (pvt.gSpeed < 1000000)
    display.print(" ");
  if (pvt.gSpeed < 100000)
    display.print(" ");
  if (pvt.gSpeed < 10000)
    display.print(" ");
  display.print((pvt.gSpeed % 10000000)/1000);display.print(".");
  if (pvt.gSpeed % 1000 < 100)
    display.print("0");
  if (pvt.gSpeed % 1000 < 10)
    display.print("0");
  display.print(pvt.gSpeed % 1000);
  display.print("m/s");
  if (pvt.sAcc < 1000000)
  {
    if (pvt.sAcc < 100000)
      display.print(" ");
    if (pvt.sAcc < 10000)
      display.print(" ");
    display.print("~");
    display.print(pvt.sAcc / 1000);display.print(".");
    if (pvt.sAcc % 1000 < 100)
      display.print("0");
    if (pvt.sAcc % 1000 < 10)
      display.print("0");
    display.println(pvt.sAcc % 1000);
  }
  else
  display.println(" ~>100");

  //Line6
  if ((pvt.year<10000)&&(pvt.year>=1000))
    display.print(pvt.year);
  else
    display.print("????");
  display.print("/");
  if ((pvt.month<=12)&&(pvt.month>=1))
  {
    if (pvt.month < 10)
      display.print("0");
    display.print(pvt.month);
  }
  else
    display.print("??");
  display.print("/");
  if ((pvt.day<=31)&&(pvt.day>=1))
  {
    if (pvt.day < 10)
      display.print("0");
    display.print(pvt.day);
  }
  else
    display.print("??");
  if (pvt.valid & 0x04)
    display.print("UTC");
  else
    display.print("INV");
  if ((pvt.hour<=23)&&(pvt.hour>=0))
  {
    if (pvt.hour < 10)
      display.print("0");
    display.print(pvt.hour);
  }
  else
    display.print("??");
  display.print(":");
  if ((pvt.miniute<=59)&&(pvt.miniute>=0))
  {
    if (pvt.miniute < 10)
      display.print("0");
    display.print(pvt.miniute);
  }
  else
    display.print("??");
  display.print(":");
  if ((pvt.sec<=60)&&(pvt.sec>=0))
  {
    if (pvt.sec < 10)
      display.print("0");
    display.print(pvt.sec);
  }
  else
    display.print("??");

  display.display();
}

void PrintSec()
{
  pvt.sec = (pvt.sec + 1)%60;
  display.fillRect(114,56,12,8,BLACK);
  display.setCursor(114,56);
  if (pvt.sec<10)
    display.print("0");
  display.println(pvt.sec);
  display.display();
  state = LOW;
}

void setup()
{
  S_Serial.begin(9600);
  pinMode(intpin, INPUT);
  attachInterrupt(digitalPinToInterrupt(intpin), pps, RISING);
  // by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  // init done
}

void loop() {
  if (state == HIGH)
    PrintSec();
  if ( processGPS() )
    PrintScreen();
}

```

I found a similar issue here (Interrupt Service Routine Executes Twice ATmega88), but since ISR only executes once if I connect pin 2 alone, I think the cause might be something else.

Is it a software issue or a hardware issue? How to fix it?

# Answer
> 1 votes
**1)** First, deferring `PrintSec` to `loop` through the volatile `state`, which is set by the ISR, actually takes *more* time to update the display. You might as well just test the pin in `loop`:

```
void setup()
{
  S_Serial.begin(9600);
  pinMode(intpin, INPUT);

  // by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
}

void loop() {

         bool state    = digitalRead(intPin);
  static bool oldState = false;

  // Watch for change
  if (oldState != state) {
    oldState = state;

    // RISING edge?
    if (state)
      PrintSec();
  }

  if ( processGPS() )
    PrintScreen();
}

```

---

**2)** "But I might miss a PPS!" you exclaim. The bad news is that if you can't finish `PrintScreen` in time to get back to testing the pin, then you're Trying To Do Too Much.

You might want to consider incremental updates of the display. If you have the previous pieces (i.e., an extra NAV\_PVT struct), you could compare each piece to see if it has changed. If it has, it's ok to spend time writing it. Just add an extra test to each piece:

```
NAV_PVT pvt, prevPVT;
static bool firstTime = true;
  .
  .
  .
void PrintScreen()
{
  if (firstTime)
    display.clearDisplay();

  //Size 2
  display.setTextSize(2);
  display.setTextColor(WHITE);

  //  Update the Speed?
  if (firstTime || (pvt.gSpeed != prevPVT.gSpeed)) {
    display.setCursor(0,0);
    float sik = (pvt.gSpeed / 100) / 3.6f;
    if (sik<100)
      display.print(" ");
    if (sik<10)
      display.print(" ");
    display.print(sik,1);//SpeedInKph
  }

```

At the end of `PrintScreen`, do this:

```
  display.display();

  prevPVT   = pvt;
  firstTime = false;
}

```

For most updates, only the `seconds` field would get written.

Clearing the screen and drawing the labels could probably happen just once in `setup`.

---

**3)** I would suggest a more efficient and reliable software serial library. `SoftwareSerial` disables *all* interrupts for the entire 10-bit character time, once the start bit is received. This makes it both vulnerable and intrusive to other interrupts, like PinChange and SPI. Ick. If you can use pins 8 & 9, AltSoftSerial is the best choice.

If you can't use those pins, and you're not using the USB port to connect to a host, could you use Serial input (pin 0) for the GPS? The GPS would have to be disconnected to do USB programming, but it could stay connected if you're using an ISP.

---

**4)** You need a more robust way to restart UBX packet framing, even if chars are lost. I would suggest something like this:
```
void loop() {
  if (state == HIGH) {
    PrintSec();
    fpos = 0; // new packet coming soon, ditch old partial packet
  }
  if ( processGPS() )
    PrintScreen();
}

```

At least that will keep you in sync. Without it, packet completion might not happen until after a 2nd PPS occurs (and 2nd packet begins arriving). Maybe this explains the symptoms you're seeing?

# Answer
> 0 votes
If i understand you correctly you have 2 ways that increase your seconds,

1. when software serial receives data
2. When PPM pin goes high

And when each of theese are run separately things work, but when you use them together seconds increase by 2 each time ?

wouldnt this suggest that your program only should use one of theese to increase your seconds.

---
Tags: interrupt, softwareserial, arduino-pro-mini, isr
---


title: What is pulseIn in programming Arduino?

text:
# Question
Title: What is pulseIn in programming Arduino?
I have seen some tutorials on ultrasonic range detector sensor.

In that, what is the meaning of the word `pulseIn`?

# Answer
> 3 votes
`pulseIn()` is used to Reads a pulse (either HIGH or LOW) on a pin. For example, if value is HIGH, `pulseIn()` waits for the pin to go HIGH, starts timing, then waits for the pin to go LOW and stops timing. Returns the length of the pulse in microseconds or 0 if no complete pulse was received within the timeout.

The timing of this function has been determined empirically and will probably show errors in shorter pulses. Works on pulses from 10 microseconds to 3 minutes in length. Please also note that if the pin is already high when the function is called, it will wait for the pin to go LOW and then HIGH before it starts counting. This routine can be used only if interrupts are activated. Furthermore the highest resolution is obtained with short intervals.

**Syntax**

```
pulseIn(pin, value)
pulseIn(pin, value, timeout)

```

**Parameters**

*pin:* the number of the pin on which you want to read the pulse. (int)

*value:* type of pulse to read: either HIGH or LOW. (int)

*timeout (optional):* the number of microseconds to wait for the pulse to be completed: the function returns 0 if no complete pulse was received within the timeout. Default is one second (unsigned long).

**Returns**

The length of the pulse (in microseconds) or 0 if no pulse is completed before the timeout (unsigned long).

For additional information and example code, visit: https://www.arduino.cc/en/Reference/PulseIn, hope this help you to understand the meaning of `pulseIn()`.

---
Tags: arduino-uno, programming, pulsein
---


# Question
Title: How to check if all pins are connected on my board to make sure Arduino sends the correct pattern number on my tool
What to add on this code to check my pins state during run? And how can i trigger error using Visual basic when 1 of my pin is disconnected?

```
String input = "";

void setup(){

Serial.begin(9600); // Sets up communication with the serial port

pinMode(6,OUTPUT);
pinMode(7,OUTPUT);
pinMode(8,OUTPUT);
pinMode(9,OUTPUT);
pinMode(10,OUTPUT);
pinMode(11,OUTPUT); // for start of program operation
pinMode(12,OUTPUT); // for stop of program operation

digitalWrite(6,LOW);
digitalWrite(7,LOW);
digitalWrite(8,LOW);
digitalWrite(9,LOW);
digitalWrite(10,LOW);

digitalWrite(11,LOW);
digitalWrite(12,LOW);

}

void loop(){

int recipe;
//Serial.print("Enter recipe number: ");

while(Serial.available()==0){    // Waits for data from serial port
}

while(Serial.available() > 0){
int data = Serial.read();
  // convert the incoming byte to a char
  // and add it to the string
input += (char)data;

recipe = input.toInt()+'0';    //recipe=0 if not a digit
if(recipe == '0')
  recipe = data;

if(data == '\n'){
  //Serial.print("Recipe: ");
  //Serial.println(recipe);
  //Serial.print("String: ");
  //Serial.println(input);
  input = "";
}
}

if(recipe == 's'){
digitalWrite(11,HIGH);
delay(1000);
digitalWrite(11,LOW);

digitalWrite(6,LOW);
digitalWrite(7,LOW);
digitalWrite(8,LOW);
digitalWrite(9,LOW);
digitalWrite(10,LOW);
}

else if(recipe == 't'){
digitalWrite(12,HIGH);
delay(1000);
digitalWrite(12,LOW);

digitalWrite(6,LOW);
digitalWrite(7,LOW);
digitalWrite(8,LOW);
digitalWrite(9,LOW);
digitalWrite(10,LOW);
}

else if(recipe>'0' && recipe<'32'){

recipe = recipe-'0';
char binary[7] = {0};   // This is where the binary representation will be stored
recipe += 32; // Adding 32 so that there will always be 6 digits in the string
itoa(recipe,binary,2);  // Convert recipe to a string of base 2 and save it in array 'binary'
char* signals = binary + 1; // Get rid of the most significant digit to get the 5 bits

//Serial.print(signals);    // Print out the signals in binary

int i;
for(i=0; i<5; i++){
  if(signals[i] == '0')
    signals[i] = '1';
  else
    signals[i] = '0';
  digitalWrite(i+6, signals[i]-'0');    // write to pin; converts the bit of the string to HIGH or LOW
  //Serial.print(signals[i]);
}

}
else
loop();

}

```

# Answer
As mentioned in a comment, your code has some fundamental flaws. **Do not** call `loop()` from within `loop()`! Aside from the code errors, your question has a legitimate element.

Testing the tri-state behaviour of an input pin will let you know if it is genuinely high, genuinely low, or floating (disconnected). The technique was given in this answer to similar problem I was encountering.

In short:

Connect a large (1MOhm) resistor to each input between the pin and ground, then for each pin:

* Turn off internal pullup;
* Read value of input pin;
* Turn on internal pullup;
* Read value again.

If the value changes from the first to the second `digitalRead()`, the input was not connected to anything. If the value remains the same then it is a genuine value from a connected device.
> 2 votes

---
Tags: arduino-uno, electronics, arduino-micro, home-automation, automatization
---