title: How much code can an Arduino board run?

text:
# Question
Title: How much code can an Arduino board run?
I'm getting back up and running with microcontrollers after about 5 years of hibernation time, and I am trying to understand a lot of different things. I have been experimenting with Arduinos for the past few weeks and am having a ton of fun. I'm a software engineer by day and a hardware hacker / manufacturer by night. At my day job, I write scripts and applications that are thousands of lines long and highly complex, using external libraries of thousands more lines of code, etc. These are full-fledge, professional software applications.

So, here is my question. Is the Arduino capable of running full-fledged robotics and other large, complex hardware applications, or is it more of a tinkering, hobbyist tool?

How big of a project can be built using Arduino? Are there memory concerns? Can an Arduino run thousands and thousands of lines of code out of the box, and if not, is there a way to add more memory for larger, more complex projects?

# Answer
> 10 votes
There are several "Arduinos" with memory capacities ranging from slightly less than 32k/2k/16MHz (Flash/RAM/CPUClock) ("Uno") to 512k/96k/84MHz ("Due".) In addition, there are "mostly compatible" boards that expand that range down to less than 8k/512/8MHz ("Gemma", "Digistump") and up to about 1M/256k/120MHz (TI "EK-TM4C1294XL Launchpad"), and "somewhat compatible" boards with 4G/1G/400MHz (Intel "Edison")

Whether these are sufficient for "full fledged robotics" depends on what you consider that to mean. Edison is probably the only contender if you wanted to include computer vision, for example, and it probably doesn't do that very well. ("What did you expect at ONLY 1 core at 400MHz?!")

The small Arduinos probably do not support your "very large libraries", either. For example, while the "Arduino Language" is technically C++, support for the C++ STL is not included due to limitations of the small CPUs used and their run-time environment.

32k of program memory (on the popular Uno) is sufficient for "thousands of lines of code", but I'd think robotics would tend to run toward much more than that. The small amount of RAM available on most of the flash-based microcontrollers also tends to be a serious limitation when you start looking at standard data-intensive algorithms. 32k/2k disappears quite quickly if you start implementing an extensive user interface, networking, or graphics. I would say that an Uno-class Arduino is suitable for implementing COMPONENTS of robotics systems (motor drivers, sensor management, etc), but probably not a whole robot.

A good example of large robotics-like software that runs on Arduino-class hardware can probably be found in the 3D Printer space. "Marlin" firmware runs on an Arduino Mega or equivalent (256k/8k/16MHz) (with RAMPS shield), and there are alternative driver packages that run on smaller and larger arduino-like hardware. Marlin is about 280k lines of code, according to cloc.

Most Arduino hardware does NOT have expandable memory. The AVR cpus cannot run code except from their internal Flash, and few of the other boards have any sort of memory bus that could be used for expansion.

# Answer
> 4 votes
No accepted or up-voted answers, eh? I'll try my hand. :)

> How big of a project can be built using Arduino?

Depends on the model. You can go from around 4 KB of programmable memory to 256 KB, and then get into the larger models like the Due (512 KB).

> Are there memory concerns?

There are *always* memory concerns, however when you have gigabytes of RAM (like on your PC) you tend to ignore them.

These are microcontrollers, designed for embedded applications. You will find yourself probably wishing you had more of everything (RAM, PROGMEM and EEPROM). However for many applications what they have is absolutely fine.

> Can an Arduino run thousands and thousands of lines of code out of the box

Probably not. Consider the Uno with 32 KB of program memory. At from two to four bytes per machine instruction (most are two bytes), you are probably going to fit at most:

```
32768 / 2 = 16384

```

... machine instructions. So no, not hundreds of thousands. The larger models, maybe.

> and if not, is there a way to add more memory for larger, more complex projects?

The Atmega2560 has expandable RAM, for example here which adds 512 KB of RAM.

> How big of a project can be built using Arduino?

I have quite a few around the place here doing their own things. One lets me know if I left the garage door open accidentally. I look upon them as being useful for "helper" applications. I wouldn't try to put my SQL database on one.

# Answer
> 2 votes
Although Arduino is more of a hobbyist electronics board, it can handle complex projects depending on which board you use. The Mega has 54 input pins, so can handle loads of devices and has much more memory and storage. See the Uno - Mega specs below

> The ATmega328 chip found on the Uno has the following amounts of memory: Flash 32k bytes (of which .5k is used for the bootloader) SRAM 2k bytes EEPROM 1k byte
>
> The ATmega2560 in the Mega2560 has larger memory space : Flash 256k bytes (of which 8k is used for the bootloader) SRAM 8k bytes EEPROM 4k byte

---
Tags: memory
---


# Question
Title: verification error, first mismatch at byte 0x3895 0xdf != 0x44?
I bought a SainSmart Arduino Mega 2560. I uploaded a small sketch to it, and it uploaded fine. When I upload a larger sketch though, I get this error:

```
verification error, first mismatch at byte 0x3895
         0xdf != 0x44

```

So obviously there's nothing wrong with my bootloader because I can upload smaller files. Why is this happening?

# Answer
> 1 votes
If your sketch contains !!! in it, that can cause some versions of the bootloader to drop into interactive mode, eg.

```
Serial.println ("Rocket firing!!!");

```

Also there can be problems with 0xFF bytes in your code causing the bootloader to incorrectly assume that that page of memory was erased, when it was not.

I have a bootloader-uploader sketch at: Atmega bootloader programmer

You need a second board to use it (eg. a Uno) - the bootloader for the Mega2560 is a reasonably up-to-date one. I haven't actually tested it with the Sainsmart version of the Mega, but I presume that internally that part is the same.

# Answer
> 0 votes
I believe I have finally understood this error today, and would like someone to verify or refute.

In "avrdude.conf" there is defined for each processor and for each memory type a minimum duration and a maximum duration that the programmer will repeat trying to write each byte. These have values of "min\_write\_delay = 4500" and "max\_write\_delay = 4500" (no idea what the units are).

After increasing the max\_write\_delay to "max\_write\_delay = 16000" (arbitrary increase but keeping it less than a 16 bit signed integer to avoid buffer overflow risks), for all memory types (but I would presume that only "flash" memory needs the parameter to be altered) my Arduino takes an extra 30 seconds to program, but no more verification errors.

---
Tags: avrdude
---


# Question
Title: Detecting distance moved by accelerometer?
I have an accelerometer connected to an Arduino Uno board, is there a way I can detect the distance it this accelerometer moved on each of the 3 axis?

# Answer
> 10 votes
This is normally referred to as Dead Reckoning. The processes of determining position using known values, such as acceleration.

First we have to relate acceleration, velocity and position mathematically. Velocity is the integral of acceleration with respect to time:

Similarly, position is the integral of velocity with respect to time:

Here is an explanation that should tie this all together. However, it appears this explanation goes in the reverse order. That is using derivatives of position to find velocity. And derivatives of velocity to find acceleration. Simply put, finding a derivative is the opposite process of finding an integral.

A final note, this all works well on paper. In reality Dead Reckoning based only on acceleration does not work very well. For instance, I believe most vehicle GPS systems tend to use steering and speed if Dead Reckoning is to be used for guidance.

Added later...

Found this web site where someone talks specifically about Dead Reckoning using an Arduino. He is simply using the deltas of filtered acceleration readings:

```
velocity(i) = velocity(i-1) + acceleration (i)
position(i) = position (i-1) + velocity (i)

```

But goes on to say accumulated errors causes drift and positioning errors.

# Answer
> -1 votes
Think about it:

* Accelerometers measure acceleration.
* Acceleration is a change in speed.
* Distance travelled is speed multiplied by time.

If you know the starting speed (e.g., stationary) and you know how much you have accelerated between two points in time you can calculate the average speed for that time period - and since you know the time of that time period (one would hope) then you can get an approximation of the distance travelled in that axis.

I say approximation, because you are working with finite time points (quanta) and only looking at the acceleration at those points in time. It's far from perfect, but it can give you a rough ballpark figure. The smaller your quanta the better your accuracy - but it will never be anything more than a guestimation at best.

Now it's just, as they say, a SMOP.

---
Tags: accelerometer
---


title: Calibrating ESC and then using it

text:
# Question
Title: Calibrating ESC and then using it
i have 30Amp ESC which i can move motor by providing values ,

but i am unable to know what is the minimum and maximum throttle speed of the motor....

how to achieve that level of info through arduino,

although when i calibrate through Open pilot software ,it is able to calibrate and the minimum value is 1500ms ..

Also after calibrating it once , do i need to arm everytime before using ESC in the arduino program through serial input ?

# Answer
> 0 votes
Used this code -

```
/*
Coded by Marjan Olesch
Sketch from Insctructables.com
Open source - do what you want with this code!
*/
#include <Servo.h>

int value = 0; // set values you need to zero

Servo firstESC, secondESC; //Create as much as Servoobject you want. You can controll 2 or more Servos at the same time

void setup() {

  firstESC.attach(9);    // attached to pin 9 I just do this with 1 Servo
  Serial.begin(9600);    // start serial at 9600 baud

}

void loop() {

//First connect your ESC WITHOUT Arming. Then Open Serial and follo Instructions

  firstESC.writeMicroseconds(value);

  if(Serial.available())
    value = Serial.parseInt();    // Parse an Integer from Serial

}

```

the problem was when i was connecting the battery , it was not making any sounds...it was already calibrated by open pilot GCS so it was not calibrating again... i needed to reset the ESC and then run this program from arduino

---
Tags: serial, arduino-mega, motor, servo
---


title: Distance finder technology 0-24inches

text:
# Question
Title: Distance finder technology 0-24inches
Can anyone point me towards whats best for relatively low cost distance measuring in the 0-36" range (or 0 - 1m range) with 1/16"/1mm accuracy. My initial approach was going to be to hack a laser tape measure, but wanted to know if that was the best in cost vs accuracy.

Essentially looking to measure how close I am to a stationary metal plate.

Thanks for any help.

# Answer
You will likely find the best accuracy is derived from a laser-based measurement. My Bosch is laser only, no ultrasound component and has 1/16" resolution. For your application, the six inch minimum distance limitation of the Bosch is outside your specifications.

Because laser measurement devices use time versus distance, it's possible you could construct a mirror chamber with front-surface mirrors that would cause the laser to travel six inches before exiting the chamber, overcoming that limitation. The calibration should be straight-forward, as you'd place the chamber flush and adjust your mirror placement until you read the exact expected compensation distance.

You would need only small mirror panes, which would not "break the bank," but if you find a discarded large-screen projection television, the mirror within is front surface and quite large. Front surface mirrors should not have contamination from touching and should be cleaned with care, as you can erode or otherwise degrade the reflective surface.

I found this site: http://blog.qartis.com/arduino-laser-distance-meter/ which looks promising for a different model of laser rangefinder, although the creator has run into a stumbling block or two.

It would appear that the key is to overcome the minimum distance limitation, perhaps as I suggested above, and interfacing with serial communications of the arduino.

One of the links I pursued involved the creator contacting the technical support of the manufacturer. The support ticket was closed as "resolved," in the manner of advising the user that the warranty was void by opening the case. Yeah, like that matters to makers and hackers!
> 2 votes

---
Tags: sensors
---


title: No Response from ESP8266 WIFI

text:
# Question
Title: No Response from ESP8266 WIFI
I am getting no response back from an ESP8266 WIFI with Arduino Mega using library ITEADLIB\_Arduino\_WeeESP8266.

```
//serial monitor response

setup begin

FW Version:

to station + softap ok

Join AP success

IP:

single ok

setup end

create tcp ok

release tcp ok

create tcp ok

```

**Arduino Mega Code**

```
#include "ESP8266.h"
#include <SoftwareSerial.h>

#define SSID        "atmel"
#define PASSWORD    "bets12345"
#define HOST_NAME   "www.google.com"
#define HOST_PORT   (80)

SoftwareSerial mySerial(10, 11); /* RX:D3, TX:D2 */ ESP8266 wifi(mySerial);

void setup(void) {
  Serial.begin(9600);
  Serial.print("setup begin\r\n");
  Serial.print("FW Version:");
  Serial.println(wifi.getVersion().c_str());
  if (wifi.setOprToStationSoftAP()) {
    Serial.print("to station + softap ok\r\n");
  } else {
    Serial.print("to station + softap err\r\n");
  }
  if (wifi.joinAP(SSID, PASSWORD)) {
    Serial.print("Join AP success\r\n");
    Serial.print("IP:");
    Serial.println( wifi.getLocalIP().c_str());
  } else {
    Serial.print("Join AP failure\r\n");
  }
  if (wifi.disableMUX()) {
    Serial.print("single ok\r\n");
  } else {
    Serial.print("single err\r\n");
  }
  Serial.print("setup end\r\n");
}

void loop(void) {
  uint8_t buffer[128] = {0};
  if (wifi.createTCP(HOST_NAME, HOST_PORT)) {
    Serial.print("create tcp ok\r\n");
  } else {
    Serial.print("create tcp err\r\n");
  }
  char *hello = "Hello, this is client!";
  wifi.send((const uint8_t*)hello, strlen(hello));
  uint32_t len = wifi.recv(buffer, sizeof(buffer), 10000);
  if (len > 0) {
    Serial.print("Received:[");
    for(uint32_t i = 0; i < len; i++) {
      Serial.print((char)buffer[i]);
    }
    Serial.print("]\r\n");
  }
  if (wifi.releaseTCP()) {
    Serial.print("release tcp ok\r\n");
  } else {
    Serial.print("release tcp err\r\n");
  }
  delay(5000);
}

```

# Answer
> 2 votes
Rx and Tx properly crossed - SwSerial Rx to ESP Tx and SwSerial Tx to ESP Rx? And the connections are sound? It wouldn't be the first time "someone" thought he'd killed an ESP, only to find a missing connection from its transmitter (not that I'd know anything about that ..... ;)

# Answer
> 1 votes
Have you remembered to logic shift the ESP8266 from 3.3v to 5v?

Any by no response, do you mean no response from your web server or the board itself?

# Answer
> 0 votes
If you are using an ESP-01 board (which is an ESP8266 based board) You should try running the ESP8266 from an independent 3.3V power supply.

The Arduino Mega 3.3V pin only supplies up to 50mA, wheres as the ESP8266 requires up to 200mA.

Also, make sure the CH\_PD and RESET pins are held high (connected to the 3.3V).

Because you're using an Arduino Mega, you might find it beneficial to use pins 16 and 17, and Serial2 instead of software serial. Internet sources indicate that they are sometimes set up with a baud rate of either 9600, 57600 or 115200. I managed to get mine working with 115200, but software serial is limited to a baud rate of 19200.

---
Tags: arduino-mega, wifi, esp8266
---


title: Arduino as an automation controller

text:
# Question
Title: Arduino as an automation controller
I am considering using an Arduino as a controller for a water treatment system and would love to hear your opinions. All it has to do is open/close a water gate (by starting/stopping a motor) at predefined times. It would have to...

* Be able to connect to a phone using a usb cable. The phone would act as a UI to change settings and water flush times on the Arduino (via a custom app)
* Log data which would be easily retrievable
* Ideally, be able to connect to a cell network and send/receive packets. I believe there is a shield for this
* Consume MINIMAL POWER. All it has to do is flush once every few days, log data, and possibly receive data from shield/usb. It would be running off of a solar panel and battery. In winter it could run out of power.

And thats pretty much it! Can this project be done with an Arduino? I would greatly appreciate any advice and recommendations!

# Answer
Have a look at my Temperature and humidity sensor - battery powered. That works from 3 x AA batteries, and has been going for a few years. I think I replaced the batteries once. It keeps track of the time, and logs data to the disk (SD card).

I don't have room to describe the whole project here, but the general idea is that the processor sleeps most of the time (consuming around 6 µA). Now this particular project doesn't turn on a motor, but adding a solid-state relay should be all you need to do that.

> Be able to connect to a phone using a usb cable. The phone would act as a UI to change settings and water flush times on the Arduino (via a custom app)

I think this will take a lot of power, keeping the phone active. One possible thing to try would be to power up the phone (eg. using another relay) during a certain "window" of time (eg. 6 pm to 7 pm). Then you would know to try to configure the device during that time.
> 1 votes

# Answer
So first of all, if the voltage of your systems is too high, arduino cannot provide that on its own. Arduinos can only provide 5v out with the rail. So you could use a relay shield, an add on board to stack on top of it, or just plain old relays with some soldering. Now, for connectivity, try this thing. http://www.annikken.com/andee/ It is relatively easy to learn, and you can build a decent UI without the need for coding an app. I think you can get them for ~30$. However, I do not know how well the arduino can run with so many shields. For data logging, a few companies make data logging shields, or you can get an external read/write and wire it up. I have a small, probably 3" by 8" solar panel for my arduino and it is quite unreliable even in low power applications. However, if you have a good one, that is cool. Best of luck -Peter
> 0 votes

---
Tags: power, remote-control
---


# Question
Title: What options are available for connecting to a CDMA network?
I am looking specifically to connect to a CDMA carrier from an Arduino. In doing research, I came across a CDMA shield option (requires getting a CDMA module that you drop into a shield), but that ends up being quite expensive - the CDMA module alone is $140, as opposed to a GSM shield which runs $30-$60. I've also tried looking for other CDMA modules, but haven't been able to find much.

Even if it's not sold as a proper Arduino shield, does anyone know of a CDMA module for hobby projects?

# Answer
There are no CDMA (more correctly known as CDMA2000) modules for hobby projects. There are a lot of reasons for this, which I won't get into, but suffice it to say, it is the way it is.

**EDIT**

Okay, I'll bite (just a little).

* I think the most important reason is CDMA is actually kind of USA-centric technology. While there are now a few other countries that have CDMA networks deployed, it pales in comparison to the number GSM networks globally.
* So in the cellular services world there is a service offering called machine to machine (M2M). What this is is a service to allow various machines (think parking meters, vending machines, ATMs, etc.) to have a data connection for control and status messages. These services are usually bought in bulk at rates much lower than equivalent consumer services would cost.
* The rest from here on out is just economies of scale. If I am making an ATM machine, would I rather be limited to a handful of countries, or be able to sell in almost all countries. The obvious choice is the latter, so these manufacturers use GSM.
* The reason a hobbyist can get anything cheap is because some other industry is using a lot of them. For example accelerometers used to be crazy expensive, that was until millions of cell phones started shipping with them every year, and now you can get them for pretty cheap. GSM modules are relatively cheap because there are lot of devices being made with them for the above mentioned reasons. CDMA modules are not so cheap because there are not a lot of devices using them.
> 3 votes

# Answer
I assume when you state "CDMA" it is Carrier Detect Multiple Access. There are several that are not very expensive and can go thousands of feet such as a RS485 network. The premium would be CAN, it will give your CSMA-NDA (Carrier Detect, Multiple Access, Non Destructive Arbitration). A non-destructive bit-wise arbitration is used to control access to the bus. There are many more but these seem to be very popular. Of course you can always go to an Ethernet Network, that is not that expensive and is typically a star network where the others are point to point. This is not a complete answer but it should get you going down the correct path. CAN will not run with one node, it needs a remote node to acknowledge the transmission. Try this link for a better description: "http://bitstream24.com/controller-area-network-can-bus-arbitration-principle/' Check the people that support this forearm, they sell the modules with instructions and of course eBay. Good Luck, Gil
> 0 votes

# Answer
Take a look at this link, you should get the impression that CDMA envelopes a lot more then Cell Phones. http://www.slideshare.net/mnsh01987/bluetooth-technology?next\_slideshow=1

Since you did not state CDMA2000 and I was involved in the automotive industry I took that approach because you can use CAN, RS485 and many other adapters to implement it with the Arduino, to my knowledge a complete CDMA2000 package is not yet available to the Arduino users. Initially we tested the CDMA theory with open collector transistors on a wire transmission line then we tested CSMANDA with the same hardware. From that point custom chips were designed and implemented. This was in the early 90's.
> 0 votes

# Answer
I am looking at NimbeLink's Arduino baseboard which works with a CDMA modem. Never tried it, but thinking of ordering one. http://nimbelink.com/skywire-arduino-cellular-shield/. Not sure if you'd put this as 'affordable' since it is $40 for baseplate + $130 for modem.

Also this Arduino WCDMA 3G. http://linksprite.com/wiki/index.php5?title=3G\_%2B\_GPS\_Shield\_for\_Arduino

Frustrating to have all this cheap awesome GSM technology, but only CDMA network in my region.
> 0 votes

---
Tags: shields
---


# Question
Title: MFRC522 Module Won't Read Multiple PICCs Consecutively
I recently bought an MFRC522 RFID module to use with my Arduino Uno, which came as a kit with a couple of MiFare 1K cards.

The issue I've been having is that, I cannot scan cards consecutively (the same card or two different ones) without resetting the Sketch. I hold a card in front of the reader and it is scanned, but when I hold another card in front of the reader it just doesn't recognize it as being there in the `mfrc522.PICC_IsNewCardPresent()` function. It does however work when using the example sketch "DumpInfo".

Here is the code I've written (please excuse any of my bad practices/untidiness).

```
/* Include Required Libraries */
#include <MFRC522.h>
#include <SPI.h>

/* Define Values for MFRC522 */
#define RST_PIN 9
#define SS_PIN 10

/* Instantiate the MFRC522 Object */
MFRC522 mfrc522(SS_PIN, RST_PIN);

/* Initialize Variables */
byte resultBuffer[18];
MFRC522::MIFARE_Key key;
unsigned int integerValue = 0;
char incomingByte;

void setup()
{
  Serial.begin(9600);
  SPI.begin();
  mfrc522.PCD_Init();
  Serial.println(F("Ready to scan card..."));

  for (byte i = 0; i < 6; i++)
  {
    key.keyByte[i] = 0xFF;
  }
}

void loop()
{
  if (!mfrc522.PICC_IsNewCardPresent())
  {
    if (Serial.available() <= 0)
    {
      return;
    }

    integerValue = 0;
    while(true)
    {
      incomingByte = Serial.read();
      if (incomingByte == '\n') break;
      if (incomingByte == -1) continue;
      integerValue *= 10;
      integerValue = ((incomingByte - 48) + integerValue);
    }

    printHeader();
    Serial.println("NEW BLOCK READ VALUE :");
    Serial.println(integerValue);
  }

  if (!mfrc522.PICC_ReadCardSerial())
  {
    return;
  }

  readAndPrint(integerValue);
}

void printHeader()
{
  Serial.println(" ");
  Serial.println("----------------------------------------");
}

int authenticateKeyA(int blockNumber)
{
  printHeader();
  Serial.println("Authenticating with key A...");

  int largestModulo4Number = blockNumber / 4 * 4;
  int trailerBlock = largestModulo4Number + 3;

  byte status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, trailerBlock, &key, &(mfrc522.uid));

  if (status != MFRC522::STATUS_OK)
  {
    Serial.println("ERROR : Authentication was unsuccessful.");
    return 0;
  }
  else
  {
    Serial.println("SUCCESS : Authentication was successful.");
    return 1;
  }
}

int authenticateKeyB(int blockNumber)
{
  printHeader();
  Serial.println("Authenticating with key B...");

  int largestModulo4Number = blockNumber / 4 * 4;
  int trailerBlock = largestModulo4Number + 3;

  byte status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_B, trailerBlock, &key, &(mfrc522.uid));

  if (status != MFRC522::STATUS_OK)
  {
    Serial.println("ERROR : Authentication was unsuccessful.");
    return 0;
  }
  else
  {
    Serial.println("SUCCESS : Authentication was successful.");
    return 1;
  }
}

int readBlock(int blockNumber, byte *resultBuffer)
{
  printHeader();
  Serial.println("Starting read block function...");

  int authSuccess = authenticateKeyA(blockNumber);
  Serial.println(" ");

  if (!authSuccess)
  {
    Serial.println("ERROR : Terminating function.");
    return 0;
  }

  byte bufferSize = 18;

  byte status = mfrc522.MIFARE_Read(blockNumber, resultBuffer, &bufferSize);

  if (status != MFRC522::STATUS_OK)
  {
    Serial.println("ERROR : Read failed.");
    return 0;
  }
  else
  {
    Serial.print("SUCCESS : Block ");
    Serial.print(blockNumber);
    Serial.print(" was read successfully.");
    return 1;
  }

  mfrc522.PICC_HaltA();
  mfrc522.PCD_StopCrypto1();
}

void readAndPrint(int blockNumber)
{
  readBlock(blockNumber, resultBuffer);

  printHeader();
  Serial.println("RESULT :");
  for (int j=0 ; j<16 ; j++)
  {
   Serial.print(resultBuffer[j], HEX);
   Serial.print(" ");
  }
  Serial.println(" ");

  delay(2000);
  printHeader();
  Serial.println("Ready to scan card...");
}

```

Before scanning the card for the first time, the serial output looks like this :

After scanning the card for the first time, the serial output looks like this :

After scanning the card for the second time, the serial output doesn't change from image 2. I tried running `Serial.println("no card detected");` when the code inside `if (!mfrc522.PICC_IsNewCardPresent())` is ran, just to check if the program was frozen (I'd heard someone else had an issue where the program froze after scanning the first card) - it wasn't frozen, both before and after scanning the first card, it printed out 'no card detected' repeatedly.

I would greatly appreciate any help as I have no clue as to how I should proceed.

Cheers,

# Answer
The correct condition, for what you intend, should be `if (mfrc522.PICC_IsNewCardPresent())`, so that the code in the IF block is run when a card is present, though this isn't the best structure. Like you discovered, your program isn't frozen. One of the 2 return statements (I'm not sure which) is causing it to abort `loop()` before calling `readAndPrint()`. With your current code:

* the first `return` will always be executed whenever no card is detected. Since you don't seem to be sending anything with the Serial monitor, `Serial.available()` will return 0 and so `loop()` returns.
* The second `return` will be executed if the reader fails to obtain the UID of the card with a `SELECT`. The `SELECT` will fail only if you don't first call `PICC_RequestA()` for 'new' cards (just coming within range), or `PICC_WakeupA()` for `HALT`ed cards (cards already within range but sleeping).

I don't know if you're trying different cards or just one. If its just one card, you may have to take it out of range and then bring it within range again for the reader to detect it a second time. But, if you want to read the card's data more than once, without taking it out of range, you have to call `PICC_WakeupA()` instead of `PICC_IsNewCardPresent()` since, as the names indicate, you're waking a sleeping card, not detecting a new card entirely. Also structure your `loop()` like this:

```
void loop(){
  if (!mfrc522.PICC_IsNewCardPresent()) {  // replace the condition with PICC_WakeupA()
    return;  // if you dont want the card to leave the reader's range
  }

  if (!mfrc522.PICC_ReadCardSerial()) {
    return;
  }

  // all the code that should be executed if a card has been detected and its UID read

}

```

However, there's usually little sense in `HALT`ing a card and then waking it in the very next iteration, so you might want to do all the sector reading and writing at once, HALT the card, and then wait for a new card to enter the field; at least that's what's desired in most applications.
> 1 votes

---
Tags: arduino-uno, rfid
---


# Question
Title: Using a SPI based ADC (ADE7912) with Arduino
I'm trying to use Analog Devices' isolated ADC ADE7912 to build a native product for voltage and current sensing, using an Arduino as a microcontroller. The IC communicates with the Arduino using SPI (and SCK frequencies of 8,4,2 and 1 MHz), and I have followed the datasheet and written down some basic code using SPI-transactions and all, which seems to be giving correct results when I apply a positive voltage to the inputs of the ADC. I have two problems here:

1. When I try to display the SCLK, MISO and MOSI signals on an oscilloscope, the clock seems to have trouble maintaining its value (it becomes erratic and hence the SPI communication also misses some values etc.) Why is this happening?
2. When I apply a negative voltage to the ADC inputs, the IC does not really show any response to that even though it clearly supports negative voltage inputs to the ADC, as mentioned in the datasheet. This might be an IC related problem, but I am not sure.

Also, is there anyone who has built a library for this IC? Would be greatly obliged if they could share it.

# Answer
I have not written a full library, but I have recently been using the ADE7913 (same as ADE7912 but with an extra voltage channel) with an Arduino MEGA.

The basic sketch located here talks to the ADE7913 over SPI, and then prints the results of the measurement registers over serial (so you can see them using a serial monitor).

I have not yet done much measurement testing, so can't comment on the negative voltage issue you have seen, but the sketch sets up the ADE7913 to use the V2WV register for monitoring temperature, and converts the result into degrees C, so you should be able to tell if its working properly.

In terms of the issues you have been having with the SPI comms, I can offer the following suggestions based on my troubleshooting experience (I also had glitchy comms initially):

1. I'm pretty new to SPI, but my interpretation of the data-sheet is that the ADE791X chips use `SPI_MODE3` (i.e. SCLK is normally high, and samples are read on the trailing clock edge). I have found `SPI_MODE1` also works, but unless others can correct me would suggest using 3.
2. I found having physically long jumper wires (my prototyping is still on a bread-board) caused issues. I have read elsewhere that at frequencies in the ones of MHz, distances less than tens of meters shouldn't be an issue; but I shortened / tidied my wiring and it seemed to help.
3. I would run everything at lowest possible speeds to troubleshoot, i.e. set the ADC sampling rate to 1kHz (set `CONFIG` bits `5:4` to `11`), and set the SCLK at 250kHz.
4. In the attached sketch, I am reading the register values based on an interrupt from the `CLKOUT\!DREADY` pin. You have to be careful that this reading routine takes less than one ADC sampling time to read all the registers. There is a good explanation of this timing constraint in Figure 8 of this application note. The attached sketch also reports some timing information over serial to help with this.

Hope that helps,

* Khalid.
> 1 votes

---
Tags: arduino-mega, spi, adc
---


# Question
Title: Linker error when trying to use functions in separate header and source files
It is my first day of working with Arduino (it is a Due). I want to read from TMP102 through I2C. I wrote some code and it works just fine. But now I want to separate the TMP102 code from the main source code. But I get linker error:

> sketch\_jun15a.ino.cpp.o: In function `setup':
>  C:\Users\Saeid\Desktop\sketch_jun15a/sketch_jun15a.ino:62: undefined
>  reference to`tmp102\_allocate(int)' collect2.exe: error: ld returned 1 exit status

My code is at the moment consist of 3 files:

**tmp102.h**

```
#ifndef TMP102_H
#define TMP102_H

//TP102 sensor struct
typedef struct TMP102 {
  int   address;
  float celsius;
  float fahrenheit;
} tmp102_t;

tmp102_t* tmp102_allocate(int address);

void tmp102_init_struct(tmp102_t * t, int address);

#endif

```

**tmp102.c**

```
#include "tmp102.h"

tmp102_t* tmp102_allocate(int address) {
  tmp102_t* t = (tmp102_t*) malloc(sizeof(tmp102_t));
  if(t) { //allocation success
    tmp102_init_struct(t, address);
    return t;
  } else {
    return 0; //null pointer
  }
}

void tmp102_init_struct(tmp102_t* t, int address) {
  t->address = address;
  t->celsius = 0.0;
  t->fahrenheit = 0.0;
}

```

and here is the setup function of the sketch:

```
#include "tmp102.h"
void setup(){

  //setup TP102 sensors
  tp_1 = tmp102_allocate(72); //error is here
  tempSensors[0] = tp_1;

  //rest of stuff...

}

```

I think there is no mistake in the code. There is also no option in the Arduino IDE so that I can meddle with the compiler/linker options.

All the files are inside the sketch folder. I created these files using the drop down button in the IDE...

# Answer
This is talked about here. Evidently, the C++ compiler changes names of \*.c files when compiling. Try changing the names of your files from \*.c to \*.cpp so that the C++ compiler does not change the names. Then recompile.
> 1 votes

# Answer
The reason you are getting the undefined reference to \`tmp102\_allocate(int)' is because your c source file is being converted to a cpp file and the function name is being mangled to support overloading etc etc. You need to flag that the functions are c code with extern "C" blocks. If you change your header file to the following it should compile. Alternatively, if you change the extension of your source file to .cpp you won't have any issues with name mangling but your code will probably not work (malloc). Note that by checking if \__cplusplus is defined you can use this header in both cpp and c projects.

**tmp102.h**

```
#ifndef TMP102_H
#define TMP102_H

#ifdef __cplusplus
  extern "C" {
#endif

//TP102 sensor struct
typedef struct TMP102 {
  int   address;
  float celsius;
  float fahrenheit;
} tmp102_t;

 tmp102_t* tmp102_allocate(int address);

void tmp102_init_struct(tmp102_t * t, int address);

#ifdef __cplusplus
  }
#endif

#endif

```
> 1 votes

---
Tags: arduino-uno, arduino-ide, arduino-due, compile
---


# Question
Title: Enabling quicker and more accurate MindWave Mobile detection?
Currently I am trying to get a Mindwave Mobile device to operate with an Arduino Uno. I'm following the guide here.

However the sample code given doesn't work very well. I have been trying to get a more consistent output but to no avail.

MindWave Code :

```
#include <SoftwareSerial.h>     // library for software serial
SoftwareSerial mySerial(5, 6);  // RX, TX
int BAUDRATE = 57600;

// checksum variables
byte payloadChecksum = 0;
byte CalculatedChecksum;
byte checksum = 0;              //data type byte stores an 8-bit unsigned number, from 0 to 255
int payloadLength = 0;
byte payloadData[64] = {0};
byte poorQuality = 0;
byte attention = 0;
byte meditation = 0;

// system variables
long lastReceivedPacket = 0;
boolean bigPacket = false;
boolean brainwave = false;

void setup() {
  Serial.begin(57600);       // Bluetooth
  delay(500);
  mySerial.begin(4800);      // software serialz
  delay(500);
  Serial.print("Communicating... ");
  mySerial.print("Communicating... ");
  mySerial.println();
}

byte ReadOneByte() {
  int ByteRead;
  // Wait until there is data
  while (!Serial.available());
  //Get the number of bytes (characters) available for reading from the serial port.
  //This is data that's already arrived and stored in the serial receive buffer (which holds 64 bytes)
  ByteRead = Serial.read();
  return ByteRead; // read incoming serial data
}

unsigned int delta_wave = 0;
unsigned int theta_wave = 0;
unsigned int low_alpha_wave = 0;
unsigned int high_alpha_wave = 0;
unsigned int low_beta_wave = 0;
unsigned int high_beta_wave = 0;
unsigned int low_gamma_wave = 0;
unsigned int mid_gamma_wave = 0;

void read_waves(int i) {
  delta_wave = read_3byte_int(i);
  i += 3;
  theta_wave = read_3byte_int(i);
  i += 3;
  low_alpha_wave = read_3byte_int(i);
  i += 3;
  high_alpha_wave = read_3byte_int(i);
  i += 3;
  low_beta_wave = read_3byte_int(i);
  i += 3;
  high_beta_wave = read_3byte_int(i);
  i += 3;
  low_gamma_wave = read_3byte_int(i);
  i += 3;
  mid_gamma_wave = read_3byte_int(i);
}

int read_3byte_int(int i) {
  return ((payloadData[i] << 16) + (payloadData[i + 1] << 8) + payloadData[i + 2]);
}

void loop() {
  // Look for sync bytes
  // Byte order: 0xAA, 0xAA, payloadLength, payloadData,
  // Checksum (sum all the bytes of payload, take lowest 8 bits, then bit inverse on lowest
  if (ReadOneByte() == 0xAA) {
    if (ReadOneByte() == 0xAA) {
      payloadLength = ReadOneByte();
      if (payloadLength > 169) //Payload length can not be greater than 169
        return;
      payloadChecksum = 0;
      for (int i = 0; i < payloadLength; i++) {     //loop until payload length is complete
        payloadData[i] = ReadOneByte();             //Read payload
        payloadChecksum += payloadData[i];
      }
      checksum = ReadOneByte();                     //Read checksum byte from stream
      payloadChecksum = 255 - payloadChecksum;      //Take one’s compliment of generated checksum
      if (checksum == payloadChecksum) {
        poorQuality = 200;
        attention = 0;
        meditation = 0;
      }
      brainwave = false;
      for (int i = 0; i < payloadLength; i++) { // Parse the payload
        switch (payloadData[i]) {
          case 02:
            i++;
            poorQuality = payloadData[i];
            bigPacket = true;
            break;
          case 04:
            i++;
            attention = payloadData[i];
            break;
          case 05:
            i++;
            meditation = payloadData[i];
            break;
          case 0x80:
            i = i + 3;
            break;
          case 0x83:                         // ASIC EEG POWER INT
            i++;
            brainwave = true;
            byte vlen = payloadData[i];
            //mySerial.print(vlen, DEC);
            //mySerial.println();
            read_waves(i + 1);
            i += vlen; // i = i + vlen
            break;
        }                                 // switch
      }                                   // for loop

/*
      if (bigPacket) {
        if (poorQuality == 0) {
        }
        else {                            // do nothing
        }
      }
*/
      if (brainwave && attention > 0 && attention < 100) {
        mySerial.print(attention, DEC);
        mySerial.println();

        Serial.print(attention, DEC);
        Serial.println();
      }
    }
  }
}

```

Often, the serial monitor stops display new values that stems from the Mindwave. Any suggestions on how I could modify the code to get it to run more smoothly will be greatly appreciated.

# Answer
No use in reinventing the wheel!

> Brain is an Arduino Library for parsing data from Neurosky-based EEG headsets. Tested units include the Star Wars Force Trainer and Mattel MindFlex.
>
> It's designed to make it simple to send out an ASCII string of comma-separated values over serial, or to access processed brain wave information directly in your Arduino sketch. See the examples for code demonstrating each use case.

https://github.com/kitschpatrol/Brain

Install the library, and set it up like this:

```
#include <Brain.h>

// Set up the brain parser, pass it the hardware serial object you want to listen on.
Brain brain(Serial);

void setup() {
// Start the hardware serial.
Serial.begin(9600);
}

void loop() {
// Expect packets about once per second.
// The .readCSV() function returns a string (well, char*) listing the most recent brain data, in the following format:
// "signal strength, attention, meditation, delta, theta, low alpha, high alpha, low beta, high beta, low gamma, high gamma"
    if (brain.update()) {
    Serial.println(brain.readErrors());
    Serial.println(brain.readCSV());
    }
}

```

Can't guarantee that it will work, but if you have the TX pin of the bluetooth hooked up to the RX pin of the Arduino I'm pretty sure it will work.
> 1 votes

# Answer
I have just spotted this question because I had a similar issue: the while condition reading Serial data is blocking.

I've rewritten the parsing part a little bit, which you can see here.

This makes it smoother to run things in parallel, but it takes about the same time to accumulate a big packet of brainwave data.
> 0 votes

---
Tags: serial, programming, c++, bluetooth
---


# Question
Title: Not able to upload program to "Arduino Due"
I'm not able to upload sketch on Arduino Due, using Programming Port.

Even blink sketch from examples is not working. So tried with blank sketch, I got following messages.

# Answer
> 0 votes
Go to device manager, and make sure that you can see the change in your com ports when you unplug and plug the Arduino into your computer.

You may also have to follow the instructions here: https://www.arduino.cc/en/Guide/Cores

I will also occasionally find that uploading won't work when I have something external connected to the RX,TX,3.3 and 5V, and GND pins.

It also helps to go to File-Preferences- and enable both options for "Show verbose output during". If you do that and post the output, we might have a better idea as to what is going wrong.

---
Tags: arduino-due
---


title: Arduino Uno: Pullup Resistor

text:
# Question
Title: Arduino Uno: Pullup Resistor
I have been reading a bit about the internal pullup resistor. I know from past projects in school that resistor themselves are fragile (burnt one by accident due to higher current than was made for).

I have two different Arduino models. One by Intel and rest are standard Arduino Uno.

So I was wondering about safely using the internal pullup resistor on the Arduino Uno. Hence my question is about the internal pullup resistor pinmode; How many pin can you connect to it safely and not overload it?

# Answer
> 5 votes
Each pin has its own, separate, pullup resistor.

I don't believe you can damage it by drawing current from the port, because the pullup resistor is only active when the port is in high impedance (hi-Z, input) mode.

The pullup resistor can be damaged by overvoltage, static discharge, and the like.

The Uno has 20 kOhm pullup resistors according to this tutorial. If you feed it a 0V signal while the Atmega is running at 5V, the current will be a quarter of a milliamp, which is miniscule.

---
Tags: arduino-uno
---


# Question
Title: How can you reduce the clock frequency of an Arduino Mega?
I'm trying to debug a problem and need to reduce the speed of the clock on my Arduino Mega from 16MHz to 8MHz.

I can't find any simple way of doing so, so I wanted to know if there were any gurus here who knew if this was possible, as well as how to do it.

WITHOUT PRESCALER:

```
long int runTime;

void setup()
{
  Serial.begin(9600);     //Setting the data transfer rate
}

void loop()
{
  delay(1000);
  runTime = millis();
  Serial.print("Runetime: ");
  Serial.println(runTime);
  delay(100);
  exit(0);
}

OUTPUT: 999

```

WITH PRESCALER:

```
long int runTime;

void setup()
{
  Serial.begin(19200);   //Setting the data transfer rate for when CLK Freq. is Halfed

  CLKPR = _BV(CLKPCE);  // enable change of the clock prescaler
  CLKPR = _BV(CLKPS0);  // divide frequency by 2
}

void loop()
{
  delay(1000);
  runTime = millis();
  Serial.print("Runetime: ");
  Serial.println(runTime);
  delay(100);
  exit(0);
}

OUTPUT: 999

```

# Answer
You can set the clock prescaler for that:

```
void setup() {
    noInterrupts();
    CLKPR = _BV(CLKPCE);  // enable change of the clock prescaler
    CLKPR = _BV(CLKPS0);  // divide frequency by 2
    interrupts();
}

```

This is explained in section 10.12 and 10.13 of the ATmega2560 datasheet.

Of course, changing the clock frequency will mess with the time-related function (`millis()`, `delay()` and co.) and the baud rate of the serial port.

**Edit**: Here is a small program to demonstrate the slowing of the clock:

```
//#define SLOW_CLOCK

void setup()
{
#ifdef SLOW_CLOCK
    noInterrupts();
    CLKPR = _BV(CLKPCE);  // enable change of the clock prescaler
    CLKPR = _BV(CLKPS0);  // divide frequency by 2
    interrupts();
#endif
    pinMode(LED_BUILTIN, OUTPUT);
}

void loop()
{
    digitalWrite(LED_BUILTIN, HIGH);
    delay(500);
    digitalWrite(LED_BUILTIN, LOW);
    delay(500);
}

```

This makes the LED flash at 1 Hz. If you uncomment the line `#define SLOW_CLOCK`, it instead flashes at 0.5 Hz.
> 5 votes

---
Tags: arduino-mega, oscillator-clock
---


title: Strange RPM Readings on Teensy 3.2

text:
# Question
Title: Strange RPM Readings on Teensy 3.2
While trying to read RPM from a computer fan using the 4-wire protocol, I am getting strange readings. +12 and GND from the fan are connected to a power supply, and the tachometer to the PIN-0 or a Teensy 3.2.

I wrote code to read the tachometer pulse using the internal pull-up and interrupts. The strange thing happening is that the number of recorded revolutions is **increasing** as I manually slow the fan using my fingers.

Here is the code :

```
#include <avr/io.h>
#include <avr/interrupt.h>
#include <elapsedMillis.h>

const int fanPulse = 0;
volatile long half_revolutions;
elapsedMillis timeElapsed;

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

  pinMode(fanPulse, INPUT_PULLUP);
  attachInterrupt(fanPulse, rpm_fun, FALLING);

  half_revolutions = 0;
  // analogWriteFrequency(20, 25000); // Teensy 3.0 pin 3 also changes to 375 kHz
}

void rpm_fun() {
  half_revolutions++;
}

void loop() {
  if (timeElapsed < 1000)
    return;

  Serial.printf("%d revolutions in %d miliseconds\n", half_revolutions / 2, (unsigned long)timeElapsed);

  timeElapsed = 0;
  half_revolutions = 0;
}

```

Here is the strange output :

```
0 revolutions in 1000 miliseconds  // Start
0 revolutions in 1000 miliseconds
82 revolutions in 1000 miliseconds
394 revolutions in 1000 miliseconds  // "normal" reading
412 revolutions in 1000 miliseconds
576 revolutions in 1000 miliseconds
456 revolutions in 1000 miliseconds
554 revolutions in 1000 miliseconds
585 revolutions in 1000 miliseconds
799 revolutions in 1000 miliseconds  // Slowing the fan
712 revolutions in 1000 miliseconds
691 revolutions in 1000 miliseconds
683 revolutions in 1000 miliseconds
625 revolutions in 1000 miliseconds
531 revolutions in 1000 miliseconds
239 revolutions in 1000 miliseconds
0 revolutions in 1000 miliseconds
0 revolutions in 1000 miliseconds  // End

```

# Answer
Without the ground of the teensy connected to the ground of the fan all you will be measuring is noise. Ground is required to complete the circuit between the teensy and the fan.
> 2 votes

---
Tags: teensy
---


title: Bootloader sequence

text:
# Question
Title: Bootloader sequence
If I got the picture right(correct me if I'm wrong) the standard bootloader senses the serial comm, and if nothing is read it passes control to the core program, which roughly corresponds to

```
int main(void) {
    init();
    setup();
    for (;;) {
        loop();
        if (serialEventRun) serialEventRun();
    }
    return 0;
}

```

I wish to understand what happens when (while the core program is running) I upload a new sketch (using the IDE or `avrdude`). I guess that the bootloader regains control when something is read in the serial comm, and this happens via a board reset (triggered somewhere inside `serialEventRun`).

If so, how does this flow interplay with the usage of the serial port? Assume I want to use `avrdude` to upload the sketch via USB, and also use the serial comm during the program execution.

# Answer
> 2 votes
Most computers begin execution at (or jump indirect through) location zero on startup. There may be variations, but this is the general idea. Whatever is put at location zero when the bootloader is installed causes the bootloader to gain control on a power-up or a reset. After that, it is up to the bootloader what happens next.

What usually happens is that the bootloader watches the serial port for the start of a "handshake" sequence; when (if) it sees what it is looking for, it replies in a manner that lets the loader program, e.g., avrdude, know that this is the bootloader replying and not some random text that was being sent just at that moment. (If the bootloader doesn't see the the handshake sequence begin within a short period, or it sees something other than the handshake, it starts the existing user program).

From there, the loader program and the bootloader cooperate to transfer the user program to the Arduino and load it into Flash memory at specified locations. Also transferred along with the user program is its starting address. When the upload is finished and verified, the bootloader transfers to the user program's starting address.

At this point, the user program owns the machine, including the serial port(s), and will continue to do so until another power-cycle or a reset. There is no need for the user program and the bootloader to negotiate use of the port; the bootloader owns it from reset to end-of-upload, and the user program owns it thereafter.

Update:

> However at that point (while the user program is running) I can start an upload (from the IDE or avrdude).

This is possible only because avrdude can send a hardware signal (*not* contained in the data stream) that the Arduino board uses to cause the chip to reset. It is still the reset process that transfers control from the running program to the bootloader. As an example, on a number of my hand-built boards I did not include that auto-reset circuit. On those boards, avrdude cannot begin a new upload autonomously; I have to manually reset them when I start avrdude.

# Answer
> 1 votes
It sounds like you're missing the fact that the Arduino IDE resets the Arduino board by toggling one of the comm port flow control signals. This causes a hardware reset on the Arduino board and then things happen as you've explained.

---
Tags: serial, bootloader
---


title: Ethernet Controlled Arduino Arm

text:
# Question
Title: Ethernet Controlled Arduino Arm
Good day, I am currently attempting to write code that will allow a user to connect to an Arduino Mega via IP address and control a robotic arm on the X and Y axis as well as open and close the claw. I am facing 2 issues and hope someone can help me

1. when it connects for the first few seconds the servos twitch and I'm not sure why
2. In my current code i am reading in the URL of the button pushed and moving the arm 5 degrees each time, but i would like to be able to hold the button down and have the arm move instead but I'm not sure how to go about that

```
/*
 Jamil Gaufr and Eva Santos
 Bridges Project @ SUNY Purchase
 Robotic Arm Control & Interface
 */

#include <SPI.h>
#include <Ethernet2.h>
#include <Servo.h>

//Represents servo to open/close claw
Servo microservo;
//Represents servo to move forward/away
Servo Yax;
//Represents servo to swivel left/right
Servo Xax;

int pos = 0;
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };   //physical mac address
EthernetServer server(80);                             //server port
String readString;
String x = "x =";
String y = "y = ";
String cl = "claw  = ";

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  Yax.attach(4);
  Xax.attach(5);
  microservo.attach(6);
  // start the Ethernet connection and the server:
  Ethernet.begin(mac);
  server.begin();
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());
  //Initializes every axis to start at the 45 degree position
  Yax.write(100);
  Xax.write(60);
  microservo.write(90);
  //1 second delay
  delay(1000);
}

void loop() {
  // Create a client connection
  EthernetClient client = server.available();
  if (client) {
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();

        //read char by char HTTP request
        if (readString.length() < 100) {
          //store characters to string
          readString += c;
          //Serial.print(c);
        }

        //if HTTP request has ended
        if (c == '\n') {
          //Serial.println(readString); //print to serial monitor for debuging

          client.println("HTTP/1.1 200 OK"); //send new page
          client.println("Content-Type: text/html");
          client.println();
          //begins html code
          client.println("<HTML>");
          client.println("<HEAD>");
          client.println("<TITLE>Bridges Program </TITLE>");
          //CSS style code for buttons
          client.println("<STYLE>");
          client.println(".button { ");
          client.println("background-color: #4CAF50;");
          client.println("border: none;");
          client.println("color: white;");
          client.println("padding: 15px 32px;");
          client.println("text-align: center;");
          client.println("display: inline-block;");
          client.println("font-size: 16px;");
          client.println("margin: 4px 2px;");
          client.println("cursor: pointer;");
          client.println("}");
          client.println("</STYLE>");
          //end of CSS code
          client.println("</HEAD>");
          client.println("<BODY>");
          //Page header
          client.println("<H1>Welcome to Robo-Farm!</H1>");
          client.println("<hr />");
          client.println("<br />");
          //Sub-heading
          client.println("<H2>Robotic Arm</H2>");
          client.println("<br />");
          //Creates buttons and corresponding URL extension
          client.println("<a href=\"/?button1on\"\" class = \"button\">Close Claw</a>");
          client.println("<a href=\"/?button1off\"\" class = \"button\">Open Claw</a><br />");
          client.println("<br />");
          client.println("<br />");
          //Creates buttons and corresponding URL extension
          client.println("<a href=\"/?button2on\"\" class = \"button\">Move forward</a>");
          client.println("<a href=\"/?button2off\"\" class = \"button\">Move Away</a><br />");
          client.println("<br />");
          client.println("<br />");
          //Creates buttons and corresponding URL extension to IP address
          client.println("<a href=\"/?button3on\"\" class = \"button\">Swivle left</a>");
          client.println("<a href=\"/?button3off\"\" class = \"button\" >Swivle right</a><br />");
          client.println("<br />");
          client.println("<br />");
          //Footer text
          client.println("<p>Created by Gafur & Santos.</p>");
          client.println("<br />");
          client.println("</BODY>");
          client.println("</HTML>");
          //end of html file
          delay(1);
          //stopping client
          client.stop();
          //controls the Arduino if you press the buttons
          //parses the URL for the corresponding extension
          if (readString.indexOf("?button1on") > 0 && microservo.read() <= 175) { // button1 on is close claw
            microservo.write(microservo.read() + 5);  // tell servo to go to position in variable 'pos'
            delay(15);                        // waits 15ms for the servo to reach the position
            Serial.println(cl + microservo.read());
          }
          if (readString.indexOf("?button1off") > 0&& microservo.read() >= 95) { // close claw
            microservo.write(microservo.read() - 5);  // tell servo to go to position in variable 'pos'
            delay(15);                                // waits 15ms for the servo to reach the position
            Serial.println(cl +microservo.read());
          }
          if (readString.indexOf("?button2on") > 0 && Yax.read() < 150 ) { // button2 on is move forward on y ax (towards the servo on the claw)
            Yax.write(Yax.read() - 5);                // tell servo to go to position in variable 'pos'
            delay(15);                                // waits 15ms for the servo to reach the position
            Serial.println(y + Yax.read());
          }
          if (readString.indexOf("?button2off") > 0&& Yax.read() > 70 ) {
            Yax.write(Yax.read() + 5);                // tell servo to go to position in variable 'pos'
            delay(15);                // waits 15ms for the servo to reach the position
            Serial.println(y + Yax.read());
          }
          if (readString.indexOf("?button3on") > 0 ) { // button3 is swivle in direction of sticker
            Xax.write(Xax.read() - 3);                // tell servo to go to position in variable 'pos'
            delay(15);                                // waits 15ms for the servo to reach the position
            Serial.println(x + Xax.read());
          }
          if (readString.indexOf("?button3off") > 0) {
            Xax.write(Xax.read() + 3);                // tell servo to go to position in variable 'pos' S
            delay(15);                // waits 15ms for the servo to reach the position
            Serial.println(x + Xax.read());
          }
          //clearing string for next read
          readString = "";

        }
      }
    }
  }
}

```

# Answer
Question 1 will need more information about your code and your wiring of the arm to offer any reasonable answer.

Question 2: There really isn't much to go on but I'll take a guess that you're sending a single message to the arm server on each button press - ? I'd try instead, sending another message every 't' starting at (.75 * t) from message-1, where 't' is the time taken for the arm to move 5 degrees. That's a totally wild guess based on unfounded assumptions of what's happening now, and what fraction of 't' I guess would make sense, but that would be my first, very experimental approach. And even so, given the non-determinism of internet packet arrival times, I wouldn't bet on getting very smooth motion, nor instant stopping on button release.

My next experiment would be send start moving/keep moving commands to the arm on button-press, stop moving on button-release, with the arm controller being smart enough to 1) stop anyway after some short period of no messages or it reaches its limit, and 2) not let commands accumulate (or the arm will keep driving until it limits).

Update:
Yes, if you're using a terminal emulator that has the ability to send each keystroke rather than line-by-line, and doesn't suppress key-repeat. As above, don't accumulate incoming keystrokes but when you're looking for another, drain the buffer first then watch for an incoming one. If you don't find it within \<TIMEOUT\>, stop moving. \<TIMEOUT\> should be slightly longer than the key-repeat interval.

(I like my second way better - winging it at the keyboard, heh! - but if it were me, I'd probably try both anyway just for what I could learn from either one).
> 1 votes

---
Tags: arduino-mega, ethernet, servo, web-server, robotics
---


# Question
Title: MPU9250 - Calibration Not Saved with RTIMULib EEPROM Issues
I'm using the MPU9250 and the RTIMULib to perform sensor fusion, however, when I run ArduinoMagCal, and save the calibration, and follow that with running the main ArduinoIMU it claims the calibration file is not saved, and there is no data to use. I'm trying to determine why this is - I have tried the other MPU9250 libraries without luck, as this one is working on my setup (Arduino Micro -\> eventually NodeMCU).

Repo : https://github.com/maxouille/RTIMULib-Arduino

ArduinoMagCal

```
////////////////////////////////////////////////////////////////////////////
//
//  This file is part of RTIMULib-Arduino
//
//  Copyright (c) 2014-2015, richards-tech
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy of
//  this software and associated documentation files (the "Software"), to deal in
//  the Software without restriction, including without limitation the rights to use,
//  copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
//  Software, and to permit persons to whom the Software is furnished to do so,
//  subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in all
//  copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
//  INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
//  PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
//  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
//  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
//  SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

#include <Wire.h>
#include "I2Cdev.h"
#include "RTIMUSettings.h"
#include "RTIMU.h"
#include "CalLib.h"
#include <EEPROM.h>

RTIMU *imu;                                           // the IMU object
RTIMUSettings settings;                               // the settings object
CALLIB_DATA calData;                                  // the calibration data

//  SERIAL_PORT_SPEED defines the speed to use for the debug serial port

#define  SERIAL_PORT_SPEED  115200

void setup()
{
  calLibRead(0, &calData);                           // pick up existing mag data if there

  calData.magValid = false;
  for (int i = 0; i < 3; i++) {
    calData.magMin[i] = 10000000;                    // init mag cal data
    calData.magMax[i] = -10000000;
  }

  Serial.begin(SERIAL_PORT_SPEED);
  Serial.println("ArduinoMagCal starting");
  Serial.println("Enter s to save current data to EEPROM");
  Wire.begin();

  imu = RTIMU::createIMU(&settings);                 // create the imu object
  imu->IMUInit();
  imu->setCalibrationMode(true);                     // make sure we get raw data
  Serial.print("ArduinoIMU calibrating device "); Serial.println(imu->IMUName());
}

void loop()
{
  boolean changed;
  RTVector3 mag;

  if (imu->IMURead()) {                                 // get the latest data
    changed = false;
    mag = imu->getCompass();
    for (int i = 0; i < 3; i++) {
      if (mag.data(i) < calData.magMin[i]) {
        calData.magMin[i] = mag.data(i);
        changed = true;
      }
      if (mag.data(i) > calData.magMax[i]) {
        calData.magMax[i] = mag.data(i);
        changed = true;
      }
    }

    if (changed) {
      Serial.println("-------");
      Serial.print("minX: "); Serial.print(calData.magMin[0]);
      Serial.print(" maxX: "); Serial.print(calData.magMax[0]); Serial.println();
      Serial.print("minY: "); Serial.print(calData.magMin[1]);
      Serial.print(" maxY: "); Serial.print(calData.magMax[1]); Serial.println();
      Serial.print("minZ: "); Serial.print(calData.magMin[2]);
      Serial.print(" maxZ: "); Serial.print(calData.magMax[2]); Serial.println();
    }
  }

  if (Serial.available()) {
    if (Serial.read() == 's') {                  // save the data
      calData.magValid = true;
      calLibWrite(0, &calData);
      Serial.print("Mag cal data saved for device "); Serial.println(imu->IMUName());
    }
  }
}

```

ArduinoIMU

```
////////////////////////////////////////////////////////////////////////////
//
//  This file is part of RTIMULib-Arduino
//
//  Copyright (c) 2014-2015, richards-tech
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy of
//  this software and associated documentation files (the "Software"), to deal in
//  the Software without restriction, including without limitation the rights to use,
//  copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
//  Software, and to permit persons to whom the Software is furnished to do so,
//  subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in all
//  copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
//  INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
//  PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
//  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
//  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
//  SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

#include <Wire.h>
#include "I2Cdev.h"
#include "RTIMUSettings.h"
#include "RTIMU.h"
#include "RTFusionRTQF.h"
#include "CalLib.h"
#include <EEPROM.h>

RTIMU *imu;                                           // the IMU object
RTFusionRTQF fusion;                                  // the fusion object
RTIMUSettings settings;                               // the settings object

//  DISPLAY_INTERVAL sets the rate at which results are displayed

#define DISPLAY_INTERVAL  300                         // interval between pose displays

//  SERIAL_PORT_SPEED defines the speed to use for the debug serial port

#define  SERIAL_PORT_SPEED  115200

unsigned long lastDisplay;
unsigned long lastRate;
int sampleCount;

void setup()
{
    int errcode;

    Serial.begin(SERIAL_PORT_SPEED);
    Wire.begin();
    imu = RTIMU::createIMU(&settings);                        // create the imu object

    Serial.print("ArduinoIMU starting using device "); Serial.println(imu->IMUName());
    if ((errcode = imu->IMUInit()) < 0) {
        Serial.print("Failed to init IMU: "); Serial.println(errcode);
    }

    if (imu->getCalibrationValid())
        Serial.println("Using compass calibration");
    else
        Serial.println("No valid compass calibration data");

    lastDisplay = lastRate = millis();
    sampleCount = 0;

    // Slerp power controls the fusion and can be between 0 and 1
    // 0 means that only gyros are used, 1 means that only accels/compass are used
    // In-between gives the fusion mix.

    fusion.setSlerpPower(1);

    // use of sensors in the fusion algorithm can be controlled here
    // change any of these to false to disable that sensor

    fusion.setGyroEnable(false);
    fusion.setAccelEnable(true);
    fusion.setCompassEnable(true);
}

void loop()
{
    unsigned long now = millis();
    unsigned long delta;
    int loopCount = 1;

    while (imu->IMURead()) {                                // get the latest data if ready yet
        // this flushes remaining data in case we are falling behind
        if (++loopCount >= 10)
            continue;
        fusion.newIMUData(imu->getGyro(), imu->getAccel(), imu->getCompass(), imu->getTimestamp());
        sampleCount++;
        if ((delta = now - lastRate) >= 1000) {
            Serial.print("Sample rate: "); Serial.print(sampleCount);
            if (imu->IMUGyroBiasValid())
                Serial.println(", gyro bias valid");
            else
                Serial.println(", calculating gyro bias");

            sampleCount = 0;
            lastRate = now;
        }
        if ((now - lastDisplay) >= DISPLAY_INTERVAL) {
            lastDisplay = now;
//          RTMath::display("Gyro:", (RTVector3&)imu->getGyro());                // gyro data
//          RTMath::display("Accel:", (RTVector3&)imu->getAccel());              // accel data
            //RTMath::display("Mag:", (RTVector3&)imu->getCompass());              // compass data
            RTMath::displayRollPitchYaw("Pose:", (RTVector3&)fusion.getFusionPose()); // fused output
           Serial.println();
        }
    }
}

```

Lastly in the repo, you will see a CalLib folder with the CalLib.cpp program inside, wondering if it is saving to the EEPROM incorrectly?

```
////////////////////////////////////////////////////////////////////////////
//
//  This file is part of RTIMULib-Arduino
//
//  Copyright (c) 2014-2015, richards-tech
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy of
//  this software and associated documentation files (the "Software"), to deal in
//  the Software without restriction, including without limitation the rights to use,
//  copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
//  Software, and to permit persons to whom the Software is furnished to do so,
//  subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in all
//  copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
//  INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
//  PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
//  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
//  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
//  SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

#include "CalLib.h"
#ifdef __SAM3X8E__

// Due version

#include "DueFlash.h"

DueFlash flash;

void calLibErase(byte device)
{
    uint32_t data = 0;

    flash.write(CALLIB_START + sizeof(CALLIB_DATA) * device, &data, 1); // just destroy the valid byte
}

void calLibWrite(byte device, CALLIB_DATA *calData)
{
    calData->validL = CALLIB_DATA_VALID_LOW;
    calData->validH = CALLIB_DATA_VALID_HIGH;

    flash.write(CALLIB_START + sizeof(CALLIB_DATA) * device, (uint32_t *)calData, sizeof(CALLIB_DATA) / 4);
}

boolean calLibRead(byte device, CALLIB_DATA *calData)
{
    memcpy(calData, CALLIB_START + sizeof(CALLIB_DATA) * device, sizeof(CALLIB_DATA));
    return calData->valid == CALLIB_DATA_VALID;
}

#else

// AVR version

#include <EEPROM.h>

void calLibErase(byte device)
{
    EEPROM.write(sizeof(CALLIB_DATA) * device, 0); // just destroy the valid byte
    //EEPROM.commit();
}

void calLibWrite(byte device, CALLIB_DATA *calData)
{
  byte *ptr = (byte *)calData;
  byte length = sizeof(CALLIB_DATA);
  int eeprom = sizeof(CALLIB_DATA) * device;

  calData->validL = CALLIB_DATA_VALID_LOW;
  calData->validH = CALLIB_DATA_VALID_HIGH;

  for (byte i = 0; i < length; i++) {
    EEPROM.write(eeprom + i, *ptr++);
    //EEPROM.commit();
  }
}

boolean calLibRead(byte device, CALLIB_DATA *calData)
{
  byte *ptr = (byte *)calData;
  byte length = sizeof(CALLIB_DATA);
  int eeprom = sizeof(CALLIB_DATA) * device;

  calData->magValid = false;

  if ((EEPROM.read(eeprom) != CALLIB_DATA_VALID_LOW) ||
      (EEPROM.read(eeprom + 1) != CALLIB_DATA_VALID_HIGH)) {
    return false;                                  // invalid data
  }

  for (byte i = 0; i < length; i++)
    *ptr++ = EEPROM.read(eeprom + i);
  return true;
}
#endif

```

# Answer
There was a compilation error which was preventing me from seeing that the data was indeed being saved to EEPROM, as far as I know there are no more issues. Just be mindful if you want to test it to add this in your calibration file after the save line:

```
  if (imu->getCalibrationValid())
      Serial.println("Using compass calibration");
  else
      Serial.println("No valid compass calibration data");

```
> 0 votes

---
Tags: sensors, esp8266, arduino-micro, eeprom
---


# Question
Title: Can I connect a camera to an arduino mini?
I was wondering if it was possible to connect a camera like this onto an Arduino mini and have the Arduino save video and audio to a micro SD card.

# Answer
> 1 votes
Not really (at least, not with any appreciable quality). Basically, the bandwidth involved is simply too much for the Arduino's relatively slow 16MHz core speed. You might be able to periodically capture greyscale lowres frames, but capturing the full 1280x960 resolution at any decent framerate is basically impossible.

If you want to find Arduino projects that involve capturing video like this, the search term is `arduino composite video input`. There are many projects out there that interface the Arduino with a composite input, but none that I know of that can capture full video. Consider the following: your Arduino runs at 16 MHz. If you were to handle 640x480 greyscale video (1 byte per pixel), that would be a data bandwidth (disregarding signal bandwidth) of 640\*480\*30 = 9216000 bytes/second. That's a pretty tall order: even if you could process each pixel in two (single cycle) instructions with no overhead, you still wouldn't have enough processor bandwidth.

If all you want to do is record composite video to an SD card, there are far easier options out there, search `composite video recorder sd`.

---
Tags: sd-card, arduino-micro
---


# Question
Title: Sleep and Wake Arduino according to LDR interrupt
I have to sleep the system in the night and have to wake the system in day time. I am using LDR to get input. LDR input is connected to interrupt pin 0 of Arduino Uno.

Here is my code.

```
#include <avr/sleep.h>
int led =13;
int triggerPin = 2;

void wakeUpNow()
{

}

void setup()
{
pinMode(triggerPin, INPUT);
pinMode(led, OUTPUT);
attachInterrupt(0, sleepNow, LOW);
}

void loop()
{
digitalWrite(led, HIGH);;
delay(1000);
digitalWrite(led, LOW);
}

void sleepNow()
{
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable();
attachInterrupt(0,wakeUpNow, RISING);
sleep_mode();
sleep_disable();
detachInterrupt(0);
}

```

Cannot we attach two function in a interrupt?

**Edited** The following code works perfectly. I want to replace the conditional check with interrupt.

```
#include <avr/sleep.h>
int led =13;
int wakePin = 2;

void wakeUpNow()
{
delay(100);
}

void setup()
{
pinMode(wakePin, INPUT);
pinMode(led, OUTPUT);
//attachInterrupt(0, sleepNow, LOW);
}

void loop()
{
digitalWrite(led, HIGH);;
delay(1000);
digitalWrite(led, LOW);

if(digitalRead(wakePin)==LOW)
  sleepNow();

}

void sleepNow()
{
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable();
attachInterrupt(0,wakeUpNow, RISING); function
sleep_mode();
sleep_disable();
detachInterrupt(0);
}

```

I want to replace \`

```
if(digitalRead(wakePin)==LOW)
  sleepNow()

```

with\`

```
attachInterrupt(0, sleepNow, LOW);

```

Please let me know how I can do that.

Thank you.

# Answer
> I want to replace the conditional check with interrupt.

Why? If it is awake it might just as well be testing the pin as doing anything else.

If you make it an interrupt, in the ISR interrupts will be off. Then if you go to sleep it will never wake.

So, your current design is the correct one, except:

```
attachInterrupt(0,wakeUpNow, RISING); function

```

What is `function` doing there?
> 1 votes

---
Tags: arduino-uno, interrupt, sleep
---


# Question
Title: Unable to replicate Arduino code into ATmega8 code
I am trying to replicate an LTC Audio Decoder code from Arduino Uno into AVR ATmega8 which I got from here.

My Arduino Uno code is working great. Here is my Arduino Uno code:

```
#define one_time_max          588 // these values are setup for NTSC video
#define one_time_min          422 // PAL would be around 1000 for 0 and 500 for 1
#define zero_time_max          1080 // 80bits times 29.97 frames per sec
#define zero_time_min          922 // equals 833 (divide by 8 clock pulses)

#define icpPin 8        // ICP input pin on arduino
#define end_data_position      63
#define end_sync_position      77
#define end_smpte_position     80

volatile unsigned int bit_time;
volatile boolean valid_tc_word;
volatile boolean ones_bit_count;
volatile boolean tc_sync;
volatile boolean write_tc_out;
volatile boolean drop_frame_flag;

volatile byte total_bits;
volatile byte current_bit;
volatile byte sync_count;

volatile byte tc[8];
volatile char timeCode[11];

/* ICR interrupt vector */
ISR(TIMER1_CAPT_vect)
{
 //toggleCaptureEdge
 TCCR1B ^= _BV(ICES1);
  //Serial.println("Inter");
 bit_time = ICR1;

 //resetTimer1
 TCNT1 = 0;

if ((bit_time < one_time_min) || (bit_time > zero_time_max)) // get rid of anything way outside the norm
 {
   //Serial.println(bit_time, DEC);
   total_bits = 0;
 }
 else
 {
   if (ones_bit_count == true) // only count the second ones pluse
     ones_bit_count = false;
   else
   {
     if (bit_time > zero_time_min)
     {
       current_bit = 0;
       sync_count = 0;
     }
     else //if (bit_time < one_time_max)
     {
       ones_bit_count = true;
       current_bit = 1;
       sync_count++;
       if (sync_count == 12) // part of the last two bytes of a timecode word
       {
         sync_count = 0;
         tc_sync = true;
         total_bits = end_sync_position;
       }
     }

     if (total_bits <= end_data_position) // timecode runs least to most so we need
     {                                    // to shift things around
       tc[0] = tc[0] >> 1;

       for(int n=1;n<8;n++)
       {
         if(tc[n] & 1)
           tc[n-1] |= 0x80;

         tc[n] = tc[n] >> 1;
       }

       if(current_bit == 1)
         tc[7] |= 0x80;
     }
     total_bits++;
   }

   if (total_bits == end_smpte_position) // we have the 80th bit
   {
     total_bits = 0;
     if (tc_sync)
     {
       tc_sync = false;
       valid_tc_word = true;
     }
   }

   if (valid_tc_word)
   {
     valid_tc_word = false;

     timeCode[11]= '\0';
     timeCode[10] = (tc[0]&0x0F)+0x30;      // frames
     timeCode[9] = (tc[1]&0x03)+0x30;      // 10's of frames
     timeCode[8] =  '-';
     timeCode[7] = (tc[2]&0x0F)+0x30;      // seconds
     timeCode[6] = (tc[3]&0x07)+0x30;      // 10's of seconds
     timeCode[5] =  '-';
     timeCode[4] = (tc[4]&0x0F)+0x30;      // minutes
     timeCode[3] = (tc[5]&0x07)+0x30;      // 10's of minutes
     timeCode[2] = '-';
     timeCode[1] = (tc[6]&0x0F)+0x30;      // hours
     timeCode[0] = (tc[7]&0x03)+0x30;      // 10's of hours

       drop_frame_flag = bit_is_set(tc[1], 2);

     write_tc_out = true;
   }
 }
}

void setup()
{
 Serial.begin(9600);
 pinMode(8, INPUT);                  // ICP pin (digital pin 8 on arduino) as input

 bit_time = 0;
 valid_tc_word = false;
 ones_bit_count = false;
 tc_sync = false;
 write_tc_out = false;
 drop_frame_flag = false;
 total_bits =  0;
 current_bit =  0;
 sync_count =  0;

 Serial.println("Finished setup ");
 delay (1000);

 TCCR1A = B00000000; // clear all
 TCCR1B = B11000010; // ICNC1 noise reduction + ICES1 start on rising edge + CS11 divide by 8
 TCCR1C = B00000000; // clear all
 TIMSK1 = B00100000; // ICIE1 enable the icp

 TCNT1 = 0; // clear timer1
}

void loop()
{
  if (write_tc_out)
   {
     write_tc_out = false;
     //if (drop_frame_flag)
       //Serial.print("TC-[df] ");
     //else
       //Serial.print("TC-[nd] ");
     Serial.println((char*)timeCode);
   //  Serial.print("  ");
     //Serial.print("\r");
   }
}

```

Now to replicate this code for AVR ATmega8, I just copy this code in AVR studio and make small changes like initializing UART, initializing Input Capture Mode etc. Here is my AVR ATmega8 code:

```
#define F_CPU 16000000UL

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <avr/sfr_defs.h>

#define one_time_max          588 // these values are setup for NTSC video
#define one_time_min          422 // PAL would be around 1000 for 0 and 500 for 1
#define zero_time_max          1080 // 80bits times 29.97 frames per sec
#define zero_time_min          922 // equals 833 (divide by 8 clock pulses)

#define icpPin 8        // ICP input pin on arduino
#define end_data_position      63
#define end_sync_position      77
#define end_smpte_position     80

volatile unsigned int bit_time;
volatile char valid_tc_word;
volatile char ones_bit_count;
volatile char tc_sync;
volatile char write_tc_out;
volatile char drop_frame_flag;

volatile unsigned char total_bits;
volatile unsigned char current_bit;
volatile unsigned char sync_count;

volatile unsigned char tc[8];
volatile char timeCode[11];

void USARTInit(uint16_t ubrr_value)
{

    UBRRL = ubrr_value;
    UBRRH = (ubrr_value>>8);
    UCSRC|=(1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
    UCSRB=(1<<RXCIE)|(1<<RXEN)|(1<<TXEN);

}

unsigned char USARTReadChar()
{

    while(!(UCSRA & (1<<RXC)));
    return UDR;
}

void USARTWriteChar(char data)
{

    while(!(UCSRA & (1<<UDRE)));
    UDR=data;
}

void send_string(char s[])
{
    int i =0;

    while (s[i] != 0x00)
    {
        USARTWriteChar(s[i]);
        i++;
    }
}

int main(void)
{

    USARTInit(103);
    DDRB=0;
     bit_time = 0;
     valid_tc_word = 0;
     ones_bit_count = 0;
     tc_sync = 0;
     write_tc_out = 0;
     drop_frame_flag = 0;
     total_bits =  0;
     current_bit =  0;
     sync_count =  0;

    send_string("FINISHED SETUP");
    _delay_ms(1000);

    TCCR1A = 0;
    TCCR1B = (1<<ICNC1)|(1<<ICES1)|(1<<CS11);
    TIMSK = (1<<TICIE1);
    TCNT1 = 0;
    sei();
    while(1)
    {

        if (write_tc_out==1)
        {
            write_tc_out = 0;
            send_string((char*)timeCode);
        }
}

}

ISR(TIMER1_CAPT_vect)
{

 //toggleCaptureEdge
 TCCR1B ^= _BV(ICES1);
  //Serial.println("Inter");
 bit_time = ICR1;

 //resetTimer1
 TCNT1 = 0;

if ((bit_time < one_time_min) || (bit_time > zero_time_max)) // get rid of anything way outside the norm
 {
   //Serial.println(bit_time, DEC);
   total_bits = 0;
 }
 else
 {
   if (ones_bit_count == 1) // only count the second ones pluse
     ones_bit_count = 0;
   else
   {
     if (bit_time > zero_time_min)
     {
       current_bit = 0;
       sync_count = 0;
     }
     else //if (bit_time < one_time_max)
     {
       ones_bit_count = 1;
       current_bit = 1;
       sync_count++;
       if (sync_count == 12) // part of the last two bytes of a timecode word
       {
         sync_count = 0;
         tc_sync = 1;
         total_bits = end_sync_position;
       }
     }

     if (total_bits <= end_data_position) // timecode runs least to most so we need
     {
               // to shift things around
       tc[0] = tc[0] >> 1;

       for(int n=1;n<8;n++)
       {
         if(tc[n] & 1)
           tc[n-1] |= 0x80;

         tc[n] = tc[n] >> 1;
       }

       if(current_bit == 1)
         tc[7] |= 0x80;
     }
     total_bits++;
   }

   if (total_bits == end_smpte_position) // we have the 80th bit
   {
     total_bits = 0;
     if (tc_sync)
     {
       tc_sync = 0;
       valid_tc_word = 1;
     }
   }

  if (valid_tc_word==1)
   {

     valid_tc_word = 0;

     timeCode[11]= '\0';
     timeCode[10] = (tc[0]&0x0F)+0x30;      // frames
     timeCode[9] = (tc[1]&0x03)+0x30;      // 10's of frames
     timeCode[8] =  '-';
     timeCode[7] = (tc[2]&0x0F)+0x30;      // seconds
     timeCode[6] = (tc[3]&0x07)+0x30;      // 10's of seconds
     timeCode[5] =  '-';
     timeCode[4] = (tc[4]&0x0F)+0x30;      // minutes
     timeCode[3] = (tc[5]&0x07)+0x30;      // 10's of minutes
     timeCode[2] = '-';
     timeCode[1] = (tc[6]&0x0F)+0x30;      // hours
     timeCode[0] = (tc[7]&0x03)+0x30;      // 10's of hours

       drop_frame_flag = bit_is_set(tc[1], 2);

     write_tc_out = 1;
   }

 }
}

```

Now when I run this code, I don't get any time stamps. I have gone through this code many times but I am unable to figure out the mistake in my code. Can any one help me figure out the issue?

# Answer
> 1 votes
I figure out the issue , I just add a small delay in ISR and my code is running fine now. I don't know reason behind it but anyway my code is running now. Here is my new code:-

```
#define F_CPU 16000000UL

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <avr/sfr_defs.h>

#define one_time_max          588 // these values are setup for NTSC video
#define one_time_min          422 // PAL would be around 1000 for 0 and 500 for 1
#define zero_time_max          1080 // 80bits times 29.97 frames per sec
#define zero_time_min          922 // equals 833 (divide by 8 clock pulses)

#define icpPin 8        // ICP input pin on arduino
#define end_data_position      63
#define end_sync_position      77
#define end_smpte_position     80

volatile unsigned int bit_time;
volatile char valid_tc_word;
volatile char ones_bit_count;
volatile char tc_sync;
volatile char write_tc_out;
volatile char drop_frame_flag;

volatile unsigned char total_bits;
volatile unsigned char current_bit;
volatile unsigned char sync_count;

volatile unsigned char tc[8];
volatile char timeCode[11];

void USARTInit(uint16_t ubrr_value)
{

    UBRRL = ubrr_value;
    UBRRH = (ubrr_value>>8);
    UCSRC|=(1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
    UCSRB=(1<<RXCIE)|(1<<RXEN)|(1<<TXEN);

}

unsigned char USARTReadChar()
{

    while(!(UCSRA & (1<<RXC)));
    return UDR;
}

void USARTWriteChar(char data)
{

    while(!(UCSRA & (1<<UDRE)));
    UDR=data;
}

void send_string(char s[])
{
    int i =0;

    while (s[i] != 0x00)
    {
        USARTWriteChar(s[i]);
        i++;
    }
    USARTWriteChar('\n');
}

int main(void)
{

    USARTInit(103);
    DDRB=0;
    bit_time = 0;
    valid_tc_word = 0;
    ones_bit_count = 0;
    tc_sync = 0;
    write_tc_out = 0;
    drop_frame_flag = 0;
    total_bits =  0;
    current_bit =  0;
    sync_count =  0;

    send_string("FINISHED SETUP");
    _delay_ms(1000);

    TCCR1A = 0;
    TCCR1B = (1<<ICNC1)|(1<<ICES1)|(1<<CS11);
    TIMSK = (1<<TICIE1);
    TCNT1 = 0;
    sei();
    while(1)
    {

        if (write_tc_out==1)
        {
            write_tc_out = 0;
            send_string((char*)timeCode);
        }
    }

}

ISR(TIMER1_CAPT_vect)
{

    //toggleCaptureEdge
    TCCR1B ^= _BV(ICES1);
    //Serial.println("Inter");
    bit_time = ICR1;

    //resetTimer1
    TCNT1 = 0;
_delay_us(13);

    if ((bit_time < one_time_min) || (bit_time > zero_time_max)) // get rid of anything way outside the norm
    {
        //Serial.println(bit_time, DEC);
        total_bits = 0;
    }
    else
    {
        if (ones_bit_count == 1) // only count the second ones pluse
        ones_bit_count = 0;
        else
        {
            if (bit_time > zero_time_min)
            {
                current_bit = 0;
                sync_count = 0;
            }
            else //if (bit_time < one_time_max)
            {
                ones_bit_count = 1;
                current_bit = 1;
                sync_count++;
                if (sync_count == 12) // part of the last two bytes of a timecode word
                {
                    sync_count = 0;
                    tc_sync = 1;
                    total_bits = end_sync_position;
                }
            }

            if (total_bits <= end_data_position) // timecode runs least to most so we need
            {
                // to shift things around
                tc[0] = tc[0] >> 1;

                for(int n=1;n<8;n++)
                {
                    if(tc[n] & 1)
                    tc[n-1] |= 0x80;

                    tc[n] = tc[n] >> 1;
                }

                if(current_bit == 1)
                tc[7] |= 0x80;
            }
            total_bits++;
        }

        if (total_bits == end_smpte_position) // we have the 80th bit
        {
            total_bits = 0;
            if (tc_sync)
            {
                tc_sync = 0;
                valid_tc_word = 1;
            }
        }

        if (valid_tc_word==1)
        {

            valid_tc_word = 0;

            timeCode[11]= '\0';
            timeCode[10] = (tc[0]&0x0F)+0x30;      // frames
            timeCode[9] = (tc[1]&0x03)+0x30;      // 10's of frames
            timeCode[8] =  '-';
            timeCode[7] = (tc[2]&0x0F)+0x30;      // seconds
            timeCode[6] = (tc[3]&0x07)+0x30;      // 10's of seconds
            timeCode[5] =  '-';
            timeCode[4] = (tc[4]&0x0F)+0x30;      // minutes
            timeCode[3] = (tc[5]&0x07)+0x30;      // 10's of minutes
            timeCode[2] = '-';
            timeCode[1] = (tc[6]&0x0F)+0x30;      // hours
            timeCode[0] = (tc[7]&0x03)+0x30;      // 10's of hours

            drop_frame_flag = bit_is_set(tc[1], 2);

            write_tc_out = 1;
        }

    }
}

```

---
Tags: arduino-uno, programming, c, atmega328, avr
---


title: Arduino Fio and BC127 communication

text:
# Question
Title: Arduino Fio and BC127 communication
I am using an ArduinoFio and a BC127 (datasheet). I'm having troubles getting the serial connection working properly from the Arduino to the BC127 and viceversa. I wasn't able to communicate with the BC127 and I don't know if is because isn't correctly powered on or something else.

**I've connected pin 0 of the BC127 to GND, pin 33 to 3V3 and pin 41,42 (RX, TX) to the TX, RX arduino's pins.**

I've tested with the tester that all wires are connected, but the BC127 seems dead.

Any help is appreciated :|

# Answer
There's a couple of things I would try.

First: Don't use the native Arduino TX/RX pins, they should be left alone to talk to the computer. Use SoftwareSerial instead in start a separate serial connection.

Second: Check that Arduino TX pin (that you declared in softwareSerial) is connected to the BC127 RX and vice versa. Unlike just about every other connection in electronics, serial connections need to have their pins reversed so that TX talks to RX. It's an easy mistake to make and one I've made when not paying attention to what I was doing.

Third: Flow control.

If the BC127 sends data when the Arduino isn't listening the data could be lost, to prevent this the BC127 won't send until the Arduino signals it is ready through flow control. See the BC127 datasheet page 8, pins 40 and 43. Trying tying UART\_CTS to 3V3 and UART\_RTS to Ground. That should cause the BC127 to be in a constant 'send' state.

Lastly I'd hook up a couple of LEDs to pins 37 and 38. They should give you some sort of status indication that could be useful in debugging future problems.
> 1 votes

# Answer
use this method for dealing with voltage translation. Also we have IC's which does the level shifting. Works great with higher frequencies as well.
> 1 votes

# Answer
Use voltage level translator. 5v to 3.3V. Dont just connect directly 5v tx to a 3.3v tx...!!
> -1 votes

---
Tags: power, pins
---


# Question
Title: How can I understand the circuit diagram for Arduino Starter Kit Project 4?
I have acquired the arduino starter kit project book, and the explanations seem at times confusing and difficult to understand.

Concerning the above circuit diagram, the book states (I am translating from French): *"The resistor and the photoresistor are in series and together they divide up the voltage. The voltage at the point where they meet is proportional to the ratio of their resistances, according to Ohm's Law."*

1. What does "the voltage at the point where they meet" mean? The voltage/ p.d. is always supposed to be across something, e.g. a certain component. This statement makes no sense to me at all.
2. The above misunderstanding leads on to me not understanding what the input pins A0-A2 actually receive. I understand that they receive a voltage, but don't know across what. Also, if the voltage inputs from these pins are used later on, are they digital? (these pins have an analogue-digital converter).

# Answer
The important thing to remember, which will help you understand everything else, is that *voltage is measured **with respect to another point***.

In this (and almost every) case it is measured *with respect to* ground. So when you say the voltage at point X is Y volts you are actually saying that the difference in voltage between point X and GND is Y volts.

So on your schematic A0 measures the difference in voltage between it's IO pin (the junction between the 10KΩ resistor and the LDR) and ground. And looking at it, what is between its IO pin and ground? The 10KΩ resistor. So it is actually the voltage across that resistor that you are measuring.

Doing the sums:

Assume there is enough light falling on the LDR to make it have a resistance of 5KΩ. Current flows through both the LDR and the 10KΩ resistor in series, so it has a total resistance of (10,000 + 5,000) 15KΩ. With 5V across the whole lot (5V -\> LDR -\> 10KΩ -\> GND) you get:

```
I = V/R = 5/15,000 = 0.000333... or 333µA.

```

333µA flowing through 10KΩ drops how much voltage?

```
V=RI = 10,000 × 0.000333... = 3.333...V

```

So A0 would be measuring 3.333V at that point.

Now, you turn out the lights, and the resistance of the LDR rises to, say, 50KΩ. What happens to those sums now? Well, let's look:

```
Total resistance = 50,000 + 10,000 = 60,000Ω
I=V/R = 5/60,000 = 0.00008333...
V=RI = 10,000 × 0.00008333... = 0.8333...V

```

The formulae can be simplified into just the ratio of the two resistances:

```
           R2
Vout = --------- × Vin
        R1 + R2

```

So that is, with the lights on:

```
        10,000
Vout = --------- × 5 = 0.666... × 5 = 3.333...
        15,000

```

And with the lights on:

```
        10,000
Vout = --------- × 5 = 0.1666... × 5 = 0.8333...
        60,000

```

From that measured voltage, of course, you can then calculate what the resistance of the LDR must have been at the time. Rearranged the formula looks like:

```
      R2 × Vin
R1 = ---------- - R2
        Vout

```

Plug in the numbers for the voltage with the lights on:

```
      10,000 × 5              50,000
R1 = ------------ - 10,000 = -------- - 10,000 = 5,000Ω
       3.333...              3.333...

```

The kind of circuit is known as a *Voltage Divider* or *Potential Divider* and you can read more about them here: https://en.wikipedia.org/wiki/Voltage\_divider
> 2 votes

# Answer
1. I think what it means is that A0 = (5V / (Photo Resistor + 10K)). Since the Photo Resistor will vary the voltage you get at A0 will be proportional to the light. So by rearranging the formula above (I'm no good at doing that so you are on your own) you can convert the number received by A0 into the resistance that the photo resistor as applying and presumably turn that into Lux (?).
2. The analog pins report a number between 0 and 1023. I can never remember if this equates to receiving a voltage of 0 - 5V or 0 - 2.5v. Either way it is a linear conversion, so you can use (5V/1024)\*reading to work out what the voltage at the pin is (or (2.5C/1024)\*Reading).

Hope that helps.
> 0 votes

# Answer
The analog inputs of the arduino can't read resistances. They read voltages and compare them with a reference voltage. They give you a number between 0 and 1023 so the read voltage is 1/1024 of the reference voltage.

The configuration of the LDR and the resistor is called a voltage divider. It is needed to get a voltage that the analog pin can read.

The intersection of the LDR and the resistor is where you can measure that voltage (or connect it to the analog pin of the arduino).

More info about this subject was already given in this question:

Why do you need a second resistor when using a photoresistor/LDR?

Wiki page about voltage dividers and the relevant formulas

https://en.wikipedia.org/wiki/Voltage\_divider
> 0 votes

---
Tags: arduino-uno, programming, pins, resistor, photoresistor
---