title: Logic level converter not working?

text:
# Question
Title: Logic level converter not working?
I'm trying to connect a 3.3v depth sensor to an Arduino uno. The logic level converter does not seem to send any current over (the sensor does not work and the voltmeter reads nothing). I tested the depth sensor separately, so I know it works, meaning it must be the converter. Why wouldn't it be working?

I've tried two logic level converters so far, but neither seems to work. This is basically how I connected it:

Here's the LLC:

Did I mess something up soldering it or by plugging it in wrong earlier?

# Answer
> 6 votes
Based on your schematic, you need to provide a 3.3v power source to the 3.3v side of the logic level converter. You can use the 3.3v pin on the Arduino.

Also, it's really hard to evaluate your soldering with such a shaky picture. Just make sure none of the pins are connected. A visual inspection usually will do, but if you want to be sure, use your multimeter's continuity function. Test all adjacent pins to confirm they are not bridged.

---
Tags: arduino-uno, voltage-level, electronics, voltage
---


# Question
Title: How do i get stored Midi to Play back without the notes sounding sustained?
How can i get my stored midi notes to play back without sounding sustained like in this video : https://youtu.be/zc1zbwheyE0?t=2m30s. Here is some of my code:

```
// Callback function to for recording note played is called upon reception of a NoteOn.
void MyHandleNoteOn(byte channel, byte pitch, byte velocity) {

if ((currentState != STATE_R) || (noteIndex >= MAX_NOTE))
      return;

  // Record the note
  noteList[noteIndex].channel = channel;
  noteList[noteIndex].pitch = pitch;
  noteList[noteIndex].velocity = velocity;
  noteList[noteIndex].deltaT = millis() - lastNoteTime;

  lastNoteTime = millis();
  noteIndex++;

 }

 void StateMachine(void)
{
  static uint16_t  nextNote;

MIDI.read();   // keep this going as fast as possible and empty buffer all the time

  switch (currentState)
  {
    case STATE_I2P:    // Set up for playback

      nextNote = 0;
      lastNoteTime = millis();
      SwitchState(STATE_P);
      break;

    case STATE_P:      // Play the notes back
   lcd.clear();
 lcd.setCursor(5,0);
  lcd.print("Playing Recorded Song");
  if (nextNote >= noteIndex) SwitchState(STATE_P2I);  // we are done

       if ((millis() - lastNoteTime) >= noteList[nextNote].deltaT)
       {
         MIDI.sendNoteOn(noteList[nextNote].pitch, noteList[nextNote].velocity, 1); //noteList[nextNote].channel);  // Send the note
        noteOn(0x90,noteList[nextNote].pitch,100);
         nextNote++;
         lastNoteTime = millis();
       }
      break;
   }

```

# Answer
You need to store and send out the 'note off' messages in addition to the 'note on' messages.
> 2 votes

# Answer
A MIDI stream is far more than just a list of notes to play. It's a set of instructions to the musical instrument on exactly *how* to play the music.

Take the typical MIDI keyboard, for example. When you press a note a "Note On" message is generated. This contains the note number (pitch) of the note to play along with the *velocity* (volume) of the note. It's called *velocity* because it's derived from how fast the key travels between two points - the faster it travels the harder you must have hit it and so the louder it should sound.

Then when you release the key a "Note Off" message is generated. This tells the target to *stop playing the note*.

Normally if you get two "Note On" messages for the same note without a "Note Off" for that note in between the new "Note On" replaces the old one, and a subsequent "Note Off" will stop all sound for that note, not just the most recent "Note On".

As well as those there are other messages as well detailing various other aspects of the music - patch and bank (instrument) selection, pitch bend, sustain, after-touch, etc. All of these are important to the overall sound of the music. And then there are "SysEx" messages (System Exclusive) which are (to a large extent) exclusive to the system that is generating them (hence the name). To faithfully recreate the music all of these *should* be stored as well.

The bare minimum though would be to store both the "Note On" and "Note Off" and maybe the velocity. How you store them is up to you, but both of them are required.

In your existing code you would need to expand the structure of your array to include *what* the instruction is. Not just assume it's all "Note On", but store whether the instruction is a "Note On" or a "Note Off", so when you play the MIDI back you can send the correct sequence of On and Off for the notes.
> 1 votes

---
Tags: arduino-mega, programming, midi
---


# Question
Title: Flash Arduino Micro code on Atmega32U micro controller
First of all, I am not an expert on electronics, so forgive me for asking something which is trivial for probably the most of you.

I am trying to get my Arduino (Micro) code running on a custom PCB with the Atmega32U chip on it. The person who made the PCB copied parts of the schematics of the Arduino Micro onto a custom PCB. What he did, is place the Atmega chip on it, and also copied the wiring for the micro USB connector.

That way, I can hook up the PCB to my USB port but now Windows does not recognize the chip as a "Arduino hosted via a COM port", but just as a atmega chip.

I learned that installing Atmel Studio 7 will also provide the correct drivers so that Windows recognizes the chip correctly via USB:

The next step for me was to get my code running on the atmega chip. So with some help from the internet I came to the following steps:

* open my sketch in Arduino IDE
* compile with verbose output
* find the location where the ".HEX" file is stored

But how can I flash this .HEX to the Atmega chip?

# Answer
To get your chip to respond to the Arduino environment over USB you need a booloader (some extra code) to be running on the Atmega32.

To install the bootloader you can use another Arduino as a programmer to the ICSP pins (or any other AVR ICSP programmer).
This procedure and description from Sparkfun for the Arduino Pro will help you.

This may help you understand the ICSP aspect, again from Sparkfun.
> 2 votes

# Answer
You can flash the .hex file to the chip with avrdude.

First, you have to add avrdude to your PATH variables.
This can be done by adding the folder of avrdude.exe to the PATH variables, described in this method.
An example path to your avrdude.exe can be this:
`C:\Program Files (x86)\Arduino\hardware\tools\avr\bin\`.

Then go to your project where the .hex file lies, and use avrdude to flash the .hex file to the chip.

Example commands can be found on the avrdude website, the description of avrdude flashing can be found here.

My example command that I use in Atmel Studio with an Arduino Mega clone that has an ATmega2560 chip (slightly modified to fit the question:
`avrdude.exe -v -p atmega2560 -c wiring -P COM3 -b 115200 -D -U flash:w:<hexfile.hex>:i`
> 0 votes

---
Tags: flash
---


title: Atmega328p low voltage

text:
# Question
Title: Atmega328p low voltage
I am using atmega328p in my PCB prototype, due to some reason I can use only 4 volt for power supply. My question is that "How to run atmega328P through 4 voltage"

# Answer
> 3 votes
Shouldn't be a problem. The minimal voltage required to run at 16MHz is 3.8 Volt. No extra steps required.

# Answer
> 0 votes
Having only a 4V power supply, you can insert a boost converter to step up the voltage to 5V and then supply it to VCC of atmega328p

---
Tags: arduino-uno, atmega328, voltage-level, fuses
---


title: 8 bits 62.5kHz PWM signal

text:
# Question
Title: 8 bits 62.5kHz PWM signal
```
// TIMER/COUNTER 0
// PIN 6(OC0A) = NON-INVERTED [_BV(COM0A1)]
// PIN 5(OC0B) = INVERTED     [_BV(COM0B1) | _BV(COM0B0)]
// PWM MODE    = FAST PWM     [_BV(WGM01) | _BV(WGM00)]
// PRESCALER   = 1            [_BV(CS00)]
TCCR0A = _BV(COM0A1) | _BV(COM0B1) | _BV(COM0B0) | _BV(WGM01) | _BV(WGM00);
TCCR0B = _BV(CS00);

// TIMER/COUNTER 1
// PIN 9(OC1A)  = ?????
// PIN 10(OC1B) = ?????
// PWM MODE     = FAST PWM 8BIT[_BV(WGM12) | _BV(WGM10)]
// PRESCALER    = 1            [_BV(CS10)]
TCCR1A = ????? | _BV(WGM10);
TCCR1B = _BV(WGM12) | _BV(CS10);

// TIMER/COUNTER 2
// PIN 11(OC2A) = NON-INVERTED [_BV(COM2A1)]
// PIN 3(OC2B)  = NON-INVERTED [_BV(COM2B1)]
// PWM MODE     = FAST PWM     [_BV(WGM21) | _BV(WGM20)]
// PRESCALER    = 1            [_BV(CS20)]
TCCR2A = _BV(COM2A1) | _BV(COM2B1) | _BV(WGM21) | _BV(WGM20);
TCCR2B = _BV(CS20);

```

Hi. My intention of writing the codes is to clarify my doubts regarding arduino timer.

First of all, I intend to have 6 consistent PWM outputs which is **8 bits** and **runs at 62.5kHz**. The confusion here is FAST PWM and PHASE CORRECT PWM. TIMER 1 and 2 is usually presented as PHASE CORRECT PWM. So does changing the PWM mode of TIMER 1 and 2 to FAST PWM enables the PWM to reach a frequency of 62.5kHz (prescaler set as 1)? Is the code that I have written correct? Do take note of the inverted and non-inverted pin mode.

Secondly, as seen from my code above, Timer/Counter 1 is not properly written (?????). I wish to control pin 9 and 10 so that it can invert or non-invert individually. Timer 0 and 2 allows me to set the pins individually (inverted and non-inverted). However from the atmega328p datasheet, Timer 1 control register is weird. How can I **set the register** so that I can do what I want to do which is to **control the pins individually**?

I truly apologize for any confusion caused by my sentence structure. I am aware I have a poor way of organizing and presenting my idea. And lastly, thank you for taking your time reading these doubt of mine.

# Answer
As mentioned in my comment, it seems latest ATmega328P datasheet from Microchip have lost some information. I use the datasheet from 2014 and it is complete:

Regarding PWM frequency of Timer1 and Timer2, as you spotted yourself, those timers support Phase Correct PWM **in addition to** Fast PWM.

To reach a 62.5KHz PWM frequency, you have to apply the formulas available in the datahseet.

## For Fast PWM

i.e. with 16MHz MCU frequency and prescaler set to 1:

> fPWM = 16000000/(1 . (1 + 255)) = 62.5 KHz

which is what you want.

## For Phase Correct PWM

i.e. with 16MHz MCU frequency and prescaler set to 1:

> fPWM = 16000000/(2 . 1 . 255) = 31.4 KHz

which is the maximum PWM frequency you can get here.

## Conclusion

To get 62.5KHz PWM frequency with Timer 1 and Timer2, you shall absolutely use FastPWM, not Phase Correct PWM.

For Timer 1, that means setting `WGM12` and `WGM10` to `1`.

For Timer2, that means setting `WGM21` and `WGM20` to `1`.

Hence your code snippet is correct towards what yu want to achieve.
> 0 votes

# Answer
for an arduino, 16Mhz / 62.5Khz = 256 -\> prescaler = 1 and single sloped pwm, with its top at 255.

the number of timer modes meeting those conditions are limited.

if you move outside of arduino, a lot more of choices.
> 0 votes

---
Tags: arduino-uno, pwm, atmega328, timers
---


title: What are the causes of Arduino lockup?

text:
# Question
Title: What are the causes of Arduino lockup?
We know watchdog timer if enabled RESETs when Arduino is locked up somewhere inside the code. As the title suggests has anyone experienced this unless they put deliberately a while(1) loop inside the code? Of course, buffer overflow or memory related issues are excluded.

I mean is it worth in Arduino to use watchdog and RESET rather than to fix the code to not get locked up. Are there still some behavior which are not predictable here?

# Answer
Most Arduino projects involve sensing the physical world or controlling the physical world (hopefully with some feed back). When sensing the physical world, it is best to add extra code to protect the project from locking up. And then, even more code concerned with what to do when the unlikely happens. Unfortunately, many projects leave out this extra code. Reasons vary:

* The project is a prototype and the effort is thought necessary.
* There is no time in the schedule to create this "extra code".
* The unexpected event is thought to be an impossible situation.
* There is no room left to add code that is not expected to run.

As an example:

A bicycle is outfitted with an Arduio base digital speedometer. Speed is calculated based on the period of a wheel mounted magnet passing a frame mounted Hall Effect switch. It works as long as the bicycle is moving at a reasonable speed. However, the program does not take into account what happens if the bicycle is not moving. If the magnet does not pass the Hall Effect switch. The program's period counter continues to count up. Eventually the watch dog timer reset the program. Over and over again.

Approaches to avoid lockup or to avoid using the watch dog timer:

1. Place all "non-blocking" polling in an infinite loop which also check the elapsed time. Consider the amount of time allowed to make a successful reading. If that time expires consider a good course for the program to follow. For instance a warning to the user or a default value when the measured value is unavailable.
2. Use interrupts. That is, use the above method, but relay on external signal changes to generate interrupts to set values and / or flags. This is a good (however more complex) alternative if the external signal occurs too fast for "non-blocking" polling.
> 1 votes

---
Tags: arduino-mega, reset
---


# Question
Title: i am unable to make a correct program using the pushbutton to toggle LED on/off?
I want to toggle the the LED on on my first complete click(i.e. pushing and even releasing the pushbutton) and i want to make my LED off at my second click.

This is the program :-

```
int led = 13;
int buttonpin = 8;
boolean lastbuttonstate = LOW;
boolean ledon = LOW;

void setup ()
{
  digitalWrite(buttonpin,HIGH);
  pinMode(buttonpin,INPUT);
  pinMode(led,OUTPUT);
}

void loop ()
{
  if( digitalRead(buttonpin) == HIGH && lastbuttonstate == LOW && ledon = !digitalRead(buttonpin))
  {
    digitalWrite(led,HIGH);
  }
  else if (digitalRead(buttonpin) == LOW && lastbuttonstate == HIGH && ledon =!digitalRead(buttonpin))
  {
    digitalWrite(led,HIGH);
  }
   if( digitalRead(buttonpin) == HIGH && lastbuttonstate == LOW && ledon =digitalRead(buttonpin))
  {
    digitalWrite(led,LOW);
  }
  else if (digitalRead(buttonpin) == LOW && lastbuttonstate == HIGH && ledon =digitalRead(buttonpin))
  {
    digitalWrite(led,LOW);
  }
}

```

I have connected all the connections on my breadboard according to schematic but there is something wrong in the program itself.

# Answer
I would use a different approach

```
int led = 13;
int buttonpin = 8;
boolean waspressed = false;

void setup (){
    pinMode(buttonpin,INPUT);
    pinMode(led,OUTPUT);
    digitalWrite(led,LOW);
}

void loop(){
    if(digitalRead(buttonpin) == HIGH){
        waspressed = true;
    }else{
        if(waspressed == true){
            digitalWrite(led, !digitalRead(led));
            waspressed = false;
        }
    }
}

```

We can understand it better if we just take a step by step view. When the controller is started, it first executes the setup(), setting the led pin as output, buttonpin as input and setting the led pin value to low. The led pin is set to LOW because it needs to have an initial value once it is an output. The initial value can also be HIGH without changing the behavior of the circuit. Always remember to set an initial value to all your output pins. This prevent them to float, which may lead no unpredictable results.

The loop() can be a little more tricky.

**State 1 - button not pressed**

The first interaction tries the value of buttonpin:`if(digitalRead(buttonpin) == HIGH)`. Once the button is not pressed (buttonpin is LOW), the interpreter moves to the `else` element. At this element, there is another conditional - i.e, another `if`. This conditional looks for the value of `waspressed`. This is false, as set at the begging of the code. Because of this, the information inside the conditional is not executed and the loop() is executed over and over with no change until the button is pressed.

**Stage 2 - button is pressed**

When the button is pressed, the next iteraction of loop() will catch this action when trying the first conditional `if(digitalRead(buttonpin) == HIGH)`. Once buttonpin is high if the button is pressed, `waspressed` will be set to true. This will repeat as long as the button remain pressed.

**Stage 3 - button is released**

After being released, the first conditional will read buttonpin as LOW, and the interpretor will move the the `else` element. At that element, it will try the second conditional `if(waspressed == true)`. Until now, there is no difference from what was executed at the first stage, however this time, `waspressed` is true because it was set true when the button was pressed. This leads the interpreter inside the conditional and execute the lines

```
digitalWrite(led, !digitalRead(led));
waspressed = false;

```

The first one set the led pin to the opposite value it has. I.e, if the led pin is HIGH, it becames LOW, if it is LOW, it becames HIGH. This happens because `!digitalRead(led)` outputs the complement of the value of `digitalRead(led)` \- without the !.

The second one set waspressed to false again. With this, the next iteration will be back to stage one and wait for another press on the button.
> 1 votes

# Answer
This appears to be the classic "how to debounce a mechanical button" problem.

You can either denounce a button using external hardware. Or you can denounce a button using software.

***Using Hardware:***

Normally a Set Reset or SR Latch is used to debounce mechanical buttons. It is common to use a single poll double throw (break before make) type switch to accomplish this.

***Using Software:***

When solving this in software, one needs to create a state machine with 4 states. Two of which are the normally expected ON and OFF state. The other two are the state where we are not sure if the button is pressed or not. As the button is in motion or is "bouncing". These 2 extra states have a time component much longer then the expected time it takes the switch to stop "bouncing". But much shorter then to be noticeable to the operator of the button.

For a really good explanation of using state machines for debouncing switches specifically for an Arduino refer to the "denounce a button using software" link at the top of this answer.
> 0 votes

---
Tags: led, button
---


title: XBee not connecting

text:
# Question
Title: XBee not connecting
Recently, I bought an XBee shield along with a dongle and two XBee's. After assembling them, I tried to connect them using XCTU. Although the XBee on the dongle connected correctly, the computer did not detect the XBee on the shield. I tried switching the XBee's, and there was no difference. I continually an error message telling me to reset the shield. Nothing happens when I reset the shield. Although the computer recognizes that the Arduino is plugged in, it seems as though it doesn't recognize the XBee. I have tried this with every possible configuration, and I keep getting the same message. I have also tried many other things I found online. I have been stuck on this problem for over a week, and any help would be

Here are the materials I am using

2x Series 1 XBee

1x Sparkfun XBee Explorer Dongle

1x Sparkfun XBee Shield

1x Arduino Uno R3

Thanks in advance!

# Answer
> 1 votes
Check the baud rate on xctu software, make sure it is on 9600 or you can click on default button and make sure you connect the xbee on the right port

---
Tags: arduino-uno, xbee
---


# Question
Title: What difference makes resistance of thermistors?
Following this thermistor tutorial i used 1k thermistors (and resistors) instead of 100k as in video.

1. What difference does it make?
2. What about 10k thermistors?
3. Is it good idea to use 1k/10k/100k potentiometer instead of resistors to tune up readings?

# Answer
Skip to the end to get the easy answer!

Your choice of thermistor and bias resistor values depends on the following: 1. How much current do you want to spend? 2. How do you want the thermistor resistance to compare with the wiring resistance? 3. How much filtering do you need? 4. What kind of linearization do you want to apply?

1. A lower value thermistor will pull more current than a higher value one. More current means less battery life but also affects (2) and (3) below.
2. For a given system wiring resistance, increasing the thermistor resistance reduces the measurement error due to the wiring. If your thermistor is 100 ohms (25C nominal) and your wiring is 1 ohm, then you would have a 1% error at 25C. For an NTC (Negative Temperature Coefficient) thermistor, as it gets hotter and it resistance decreases, the wiring error increases because the wiring represents a greater percentage of the total resistance.
3. Filtering a resistive sensor in front of an ADC can be done by simply putting a capacitor across the ADC input. As your sensor resistance increases, the size of the capacitor required decreases for the same cutoff frequency. Even if filtering is not needed, be sure to check the ADC input impedance requirement as sample and hold circuits need their minimum AC input impedances to be satisfied as well as the DC input currents: Too much sensor impedance does not go well with too high ADC input current.
4. Unless you are using a platinum RTD with its linear response curve, your thermistor resistance vs temperature curve is going to be logarithmic where each end of the curve will be asymptotic. This means you will get good resolution around the 25C reference temperature but at one end you'll get very little resistance change for a large change in temperature and at the other end you'll get a lot of resistance change for very little change in temperature. By putting a resistor in parallel with the thermistor you can flatten out the curve to fit your measurement needs.

All this being said, your best bet is to put the thermistor curve into a spreadsheet and adjust the values until you get current consumption you can live with with a curve that gives you the information you need. See this example for a 10K NTC sensor with linearization (Either the RT/R25 or RT-vs-Temp values are almost always listed in the data sheet for each thermistor): Spreadsheet for this graph
> 4 votes

# Answer
The standard way to measure a resistive sensor is to make a voltage divider with the sensor and a fixed resistance between Vcc and GND, like this:

```
Vcc
 │
 Rb
 │
 ├─── analog input
 │
 Rx
 │
GND

```

where Rx is the resistance you want to measure and Rb is a known bias resistance. The only unknown is the choice of the bias resistance.

The simple rule of thumb is to choose a bias resistance close to the typical values of the resistance you want to measure, as this will optimize your measurement resolution. More specifically, the *relative* measurement resolution, which could be stated as the number of ADC steps you get per percent change in resistance, is maximal when Rx = Rb, and decreases only slowly as Rx gets further from Rb.

Now, one could argue that the *relative* resistance resolution is not always the best performance metric. You may want to maximize the *absolute* resistance resolution instead, or maybe the *absolute conductance* resolution. Each of these choices would lead to a different choice of bias resistor. For the case of a thermistor, however, the choice is pretty clear: the resistance varies almost exponentially with temperature, which means that the *absolute* temperature variations are practically proportional to the *relative* resistance variations. If you want to use temperature resolution as a metric, you could go through a tedious calculation only to find out that the optimal Rb is darn close to Rx.

In short, if your thermistor is 1 kΩ at 25 °C, and you will use it near 25 °C, then a 1 kΩ pullup will give you the best temperature resolution.

Now, measurement resolution may not be the only issue you care about, and you may want to sacrifice some of it in order to improve something else. For example:

* Current consumption: a 1 kΩ thermistor in series with a 1 kΩ pullup will draw 2.5 mA (assuming Vcc = 5 V), which could rise to near 5 mA if it gets really hot. If you are running off battery power this could be an issue.
* Self heating: in that 1 kΩ + 1 kΩ configuration, the thermistor will dissipate 6.25 mW. I've seen the datasheet of a typical thermistor stating a thermal dissipation constant of 7 mW/K. This means the measurement current would heat the thermistor to 0.9 °C above ambient temperature, which you would need to take into account in your temperature calculations.

Both of these issues would be mitigated by using a larger value for Rb, only at the cost of measurement resolution. Switching to a 10 kΩ thermistor would mitigate these issues without sacrificing resolution.
> 3 votes

# Answer
**Related:**

---

I was trying to figure this out myself and was going to ask a question to verify my results. Since this question is so close, I'll just post my results as an answer and comments/votes can help me figure out if it's correct!

I've been going by this tutorial on Adafruit which, unfortunately, doesn't talk about *why* they use a 10k Ohm thermistor paired with a matching fixed/bias resistor.

So we're on the same page, here's the circuit used (voltage divider, pic taken from the second related answer above):

The formula used to get from resistance to temperature (taken from the Adafruit guide, which uses the Steinhart-Hart equation):

Here's the full code used to find the temperature based on the voltage divider created by the fixed/bias resistor and the thermistor:

```
int pin_therm = A0;    // analog read pin
float reading;         // hold thermistor resistance
float stein;           // hold calculated temp

int res_fixed = 10000; // 10k fixed resistor
int res_therm = 10000; // 10k thermistor
int therm_nom = 25;    // nominal thermistor temp
int therm_b = 3950;    // thermistor B coefficient

reading = analogRead(pin_therm);
reading = (1023 / reading) - 1;
reading = res_fixed / reading;

// apply the S-H equation
stein = reading / res_therm;    // (R/Ro)
stein = log(stein);             // ln(R/Ro)
stein /= therm_b;               // 1/B * ln(R/Ro)
stein += 1.0 / (25.0 + 273.15); // + (1/To)
stein = 1.0 / stein;            // Invert
stein -= 273.15;                // convert to C

```

My aim is to measure around 150-250C, and I was curious what my resolution was after seeing very specific, "steppy" values when watching serial output. For example, as temps rose I'd see values like 202, 211, 222 but nothing in between.

I used `R` to send all possible ADC values of 0-1023 through the equation to find the corresponding calculated temperature.

In my case, I modified the code above for the Honeywell 135-104LAG-J01 thermistor I was using (T = 25C, B = 3974). Using the rule of thumb to match the fixed resistor, here's what I get with 100k Ohms, showing ADC values for 150-250C. It revealed that this setup would only give me ~5 readings over 200-250C!

Going back to the math, it looked like I could drop the fixed resistance for better resolution. Here is the same 100k thermistor, but comparing the resolution obtained with 22k, 47k and 100k fixed resistors:

Using a lower fixed resistor, I have substantially more data points in my range of interest! We can simply compare the ADC ranges that make up this 150-250C span: ~20 for 100k and ~80 for 22k.

I'm not really worried about current consumption, but since it came up in the other answers, we can also increase the thermistor nominal resistance. Here's a plot breaking down by thermistor (100k - 1M) and matching fixed resistor (same 22k-100k values). I've removed the dots to make it less busy and the gray "mini-plot" titles are the thermistor values I looked at:

Lastly, to spare you from having to calculate the min vs. max ADC ranges covering the desired 150-250C range, here's a simple bar plot showing how many steps we get in this range.

So, with a 1M Ohm thermistor and 22k fixed resistor, we could have ~0.5C resolution in this high range (100C span divided by ~200 ADC steps).

---

I echo the suggestion of John Taylor to plot things out, but in my case, the datasheet *didn't* list the key values required for his spreadsheet. I think spelling out the Adafruit code and putting my `R` code at the end can help understand how to do this (approximated) in order to compare temperatures of interest vs. ADC steps which cover it.

---

As a last aside, I ran into the mention of "source impedance" on one of the related questions. I'm not an electrical engineer, but some answers suggest that there may be a time delay issue with reading ADC values when the circuit resistance is very high:

That said, since I'm measuring high on the temp scale, an NTC thermistor will have less than max resistance. We're also helped by the fact that the equivalent resistance is:

`1/((1/R_fixed) + (1/R_therm))`

So, even with a 1M thermistor an 100k fixed, our equivalent resistance at room temperature is:

`1/((1/1000000) + (1/100000)) = ~91k`

This will only reduce further at higher temps, but I thought I'd mention it for the sake of thoroughness!

---

Here's the R code used to generate the multi plot covering 100k-1M thermistors vs. 22k-100k fixed resistors:

```
## for plotting
library(ggplot2)

## R kept wanting scientific notation, e.g. 10e5
options(scipen=10)

## range for ADC reading
inputs <- 0:1023

## create all combos of fixed resistor, thermistor, and ADC values
combos <- expand.grid(res = c(22000, 47000, 100000),
                      therm = c(100000, 250000, 500000, 1000000),
                      adc = 0:1023)

## make sure it's sorted the right way
## also, give it a unique identifier per combo
combos <- combos[order(combos$therm, combos$res, combos$adc), ]
combos$grp <- paste0(combos$res, "_", combos$therm)

## calculate the temps for each thermistor/fixed res combo
dat_lst <- lapply(unique(combos$grp), function(grp) {

  temp <- combos[combos$grp == grp, ]
  res <- unique(temp$res) / ((1023 / inputs) - 1)
  stein <- res / unique(temp$therm);
  stein <- log(stein);
  stein <- stein / 3974.0;
  stein <- stein + (1.0 / (25.0 + 273.15));
  stein <- 1.0 / stein;
  stein <- stein - 273.15;

  temp$temp <- stein

  return(temp)

})

## combine results
data <- do.call(rbind, dat_lst)

## some factor re-labeling to make plots more readable
data$res <- factor(data$res,
                   levels = c(22000, 47000, 100000),
                   labels = c("22k", "47k", "100k"))
data$therm <- factor(data$therm,
                     levels = c(100000, 250000, 500000, 1000000),
                     labels = c("100k", "250k", "500k", "1M"))

## reduce to only values in our range of interest
data <- data[data$temp > 150 & data$temp < 250, ]

## the plot itself
p <- ggplot(data, aes(x = adc, y = temp, colour = as.factor(res),
            group = grp)) + geom_line()
p <- p + scale_x_continuous("adc value")
p <- p + scale_y_continuous("calculated temp, C")
p <- p + facet_grid(therm ~ .) + theme_bw()
p <- p + scale_colour_discrete("fixed resistor")
p

## to save it out
png("./therm-vs-fixed.png", res = 200, width = 1600, height = 900)
p
dev.off()

```
> 1 votes

---
Tags: temperature-sensor, potentiometer, resistor
---


title: Detecting which pin called the ISR Uno

text:
# Question
Title: Detecting which pin called the ISR Uno
I need an answer fast.I want to make a keyboard class to handle a few buttons attached to my arduino. I want to use interrupts.The problem is I have to use the same interrupt function for all my buttons(it would beimpractical to create a routine for each button).So inside the routine I must know at least what pin fired the interrupt. How can I solve this?(I belive it can be solved by changing some registers but that would be too complicated).PS:there are only two buttons(pins 2 and 3 are enough)

Edit: Isn't possible to create/call an interrupt routine inside a class? (I know that the routine actually doesn't exist initially because the object of the class type wasn't created). Can this be done?

```
class Keyboard{
  private:
    struct btn{
      boolean pressed;
      uint32_t pressTime;
    };
    btn button1;

  public:
    void int_handler(){

    }
    Keyboard(){
      attachInterrupt(digitalPinToInterrupt(2),this->int_handler,RISING);
      attachInterrupt(digitalPinToInterrupt(3),this->int_handler,RISING);
    }
};

```

# Answer
I solved this in a more..compressed way. I already store the state of the buttons(pushed down or up-that is if they set their connected pin to 0 or 1).So I can have a single routine called by the microcontroller and then inside it decide what pin changed states(clever):

```
#define btn1Pin 2
#define btn2Pin 3

class Timer{
  //....
};
uint32_t Timer::start_time;
class KeyboardBtn{
  private:
    const static byte clicksDelay=255;
    struct btn{
      byte state=1;   //(0-keyDown / 1-keyUp) 2-Click
      byte pin;
      Timer clickLapse;
    };
    volatile static btn buttons[2];

  public:
    KeyboardBtn(){
      buttons[0].pin=btn1Pin;
      buttons[1].pin=btn2Pin;
      attachInterrupt(digitalPinToInterrupt(btn1Pin),keyPress,CHANGE );
      attachInterrupt(digitalPinToInterrupt(btn2Pin),keyPress,CHANGE );
    }
    static void keyPress(){
      //digitalRead ==1 then button up
      for(int i=0;i<2;i++){
        if(bitRead(buttons[i].state,0)==digitalRead(buttons[i].pin)) continue;
        //i is the switched button
      }
    }
    byte stateChanged(byte key){
      //code
    }
};
volatile KeyboardBtn::btn KeyboardBtn::buttons[2];

KeyboardBtn btn;
void setup() {
  pinMode(btn1Pin,INPUT_PULLUP);
  pinMode(btn2Pin,INPUT_PULLUP);
}

void loop(){
}

```
> 1 votes

# Answer
You only have two external interrupts on the Uno, so a simple solution would be to call an "intermediate" routine, which remembers the button number. eg.

```
  attachInterrupt(digitalPinToInterrupt(2),this->int_handler2,RISING);
  attachInterrupt(digitalPinToInterrupt(3),this->int_handler3,RISING);

```

Those two functions could then call your main function passing down 2 or 3 depending on which one was called.

eg.

```
void int_handler2 ()
  {
  int_handler (2);
  }

void int_handler3 ()
  {
  int_handler (3);
  }

```

If you have more switches than that you can use pin-change interrupts. The typical way of detecting which one fired is to see which bits are different this time, compared to last time.

See my page about interrupts.
> 4 votes

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


# Question
Title: Do motors need to have capacitor even if being used with motor shield
I'm using a 12V DC geared motor with an Adafruit motor shield which is connected to Arduino.

So, I want to know inspite of using the motor shield, do I need to add capacitors to the motor?

# Answer
If the motors have a lot of "brush noise" you need to add capacitors to the motor. It is written in the FAQ.

The noise must be suppressed at the source or the motor leads will act like antennae and broadcast it to the rest of the system link.
> 3 votes

---
Tags: motor
---


title: Loop inside switch statement

text:
# Question
Title: Loop inside switch statement
I am using voice command to start/stop display of LDR readings over Arduino. The module I am using is voice module V3. I have downloaded some of its examples. First we need to train the module with specific commands. I have trained it as "on" and "off". Hence I could turn on and off the led using voice command . code:

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

/**
  Connection
  Arduino    VoiceRecognitionModule
   2   ------->     TX
   3   ------->     RX
*/
VR myVR(2,3);    // 2:RX 3:TX, you can choose your favourite pins.

uint8_t records[7]; // save record
uint8_t buf[64];
int led = 13;

#define onRecord    (0)
#define offRecord   (1)

/**
  @brief   Print signature, if the character is invisible,
           print hexible value instead.
  @param   buf     --> command length
           len     --> number of parameters
*/
void printSignature(uint8_t *buf, int len) {
  int i;
  for(i=0; i<len; i++) {
    if(buf[i]>0x19 && buf[i]<0x7F){
      Serial.write(buf[i]);
    } else {
      Serial.print("[");
      Serial.print(buf[i], HEX);
      Serial.print("]");
    }
  }
}

/**
  @brief   Print signature, if the character is invisible,
           print hexible value instead.
  @param   buf  -->  VR module return value when voice is recognized.
             buf[0]  -->  Group mode(FF: None Group, 0x8n: User, 0x0n:System
             buf[1]  -->  number of record which is recognized.
             buf[2]  -->  Recognizer index(position) value of the recognized record.
             buf[3]  -->  Signature length
             buf[4]~buf[n] --> Signature
*/
void printVR(uint8_t *buf) {
  Serial.println("VR Index\tGroup\tRecordNum\tSignature");
  Serial.print(buf[2], DEC);
  Serial.print("\t\t");
  if(buf[0] == 0xFF) {
    Serial.print("NONE");
  } else if(buf[0]&0x80) {
    Serial.print("UG ");
    Serial.print(buf[0]&(~0x80), DEC);
  } else {
    Serial.print("SG ");
    Serial.print(buf[0], DEC);
  }
  Serial.print("\t");
  Serial.print(buf[1], DEC);
  Serial.print("\t\t");
  if(buf[3]>0){
    printSignature(buf+4, buf[3]);
  } else {
    Serial.print("NONE");
  }
  Serial.println("\r\n");
}

void setup() {
  /** initialize */
  myVR.begin(9600);
  Serial.begin(115200);
  Serial.println("Elechouse Voice Recognition V3 Module\r\nControl LED sample");
  pinMode(led, OUTPUT);
  if(myVR.clear() == 0) {
    Serial.println("Recognizer cleared.");
  } else {
    Serial.println("Not find VoiceRecognitionModule.");
    Serial.println("Please check connection and restart Arduino.");
    while(1);
  }
  if(myVR.load((uint8_t)onRecord) >= 0){
    Serial.println("onRecord loaded");
  }
  if(myVR.load((uint8_t)offRecord) >= 0){
    Serial.println("offRecord loaded");
  }
}

void loop() {
  int ret;
  ret = myVR.recognize(buf, 50);
  if(ret>0) {
    switch(buf[1]) {
      case onRecord:
        /** turn on LED */
        digitalWrite(led, HIGH);
        break;
      case offRecord:
        /** turn off LED*/
        digitalWrite(led, LOW);
        break;
      default:
        Serial.println("Record function undefined");
        break;
    }
    /** voice recognized */
    printVR(buf);
  }
}

```

The code is running fine. Now to start/stop display on OLED I have included all the necessary OLEd libraries and all and changed the above code only in the switch case as:

```
void loop() {
  int ret;
  ret = myVR.recognize(buf, 50);
  if(ret>0) {
    switch(buf[1]) {
      case OnRecord:
        display.clearDisplay();
        sensorValue = analogRead(sensorPin);
        display.setCursor(30,0);
        display.setTextSize(1);
        display.print("LDR Reading:");
        display.setCursor(30,10);
        display.setTextSize(2);
        display.print(sensorValue);
        delay(500);
        break;
      case OffRecord:
        display.clearDisplay();
        break;
      default:
        Serial.println("Record function undefined");
        break;
    }
    display.display();
    printVR(buf);
  }
}

```

Here when I say "on" the OLEd is starting on my voice command. But it remains frozen in the first reading. When I say "off" it turns of the display(as required). The process runs in loop.

I just want to keep on displaying LDR values by running all the statements in "case Onrecord" until case "offrecord" is encountered. Any idea how to do this?

The entire code for the voice controlled LDR readings on OLED is:

```
#include <SoftwareSerial.h>
#include "VoiceRecognitionV3.h"
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
int sensorPin = A0; // select the input pin for ldr
int sensorValue = 0;

#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);

 char inChar;
 String string;
/**
  Connection
  Arduino    VoiceRecognitionModule
   2   ------->     TX
   3   ------->     RX
*/
VR myVR(2,3);    // 2:RX 3:TX, you can choose your favourite pins.
uint8_t records[7]; // save record
uint8_t buf[64];

#define OnRecord    (0)
#define OffRecord   (1)

/**
  @brief   Print signature, if the character is invisible,
           print hexable value instead.
  @param   buf     --> command length
           len     --> number of parameters
*/
void printSignature(uint8_t *buf, int len) {
  int i;
  for(i=0; i<len; i++) {
    if(buf[i]>0x19 && buf[i]<0x7F) {
      Serial.write(buf[i]);
    } else {
      Serial.print("[");
      Serial.print(buf[i], HEX);
      Serial.print("]");
    }
  }
}

/**
  @brief   Print signature, if the character is invisible,
           print hexible value instead.
  @param   buf  -->  VR module return value when voice is recognized.
             buf[0]  -->  Group mode(FF: None Group, 0x8n: User, 0x0n:System
             buf[1]  -->  number of record which is recognized.
             buf[2]  -->  Recognizer index(position) value of the recognized record.
             buf[3]  -->  Signature length
             buf[4]~buf[n] --> Signature
*/
void printVR(uint8_t *buf) {
  Serial.println("VR Index\tGroup\tRecordNum\tSignature");
  Serial.print(buf[2], DEC);
  Serial.print("\t\t");
  if(buf[0] == 0xFF) {
    Serial.print("NONE");
  } else if(buf[0]&0x80) {
    Serial.print("UG ");
    Serial.print(buf[0]&(~0x80), DEC);
  } else {
    Serial.print("SG ");
    Serial.print(buf[0], DEC);
  }
  Serial.print("\t");

  Serial.print(buf[1], DEC);
  Serial.print("\t\t");
  if(buf[3]>0) {
    printSignature(buf+4, buf[3]);
  }
  else{
    Serial.print("NONE");
  }
  Serial.println("\r\n");
}

void setup() {
  /** initialize */
  myVR.begin(9600);
  pinMode(13, OUTPUT);
  // initialize with the I2C addr 0x3C / mit I2C-Adresse 0x3c initialisieren
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.display();
  display.clearDisplay();
  display.setTextColor(INVERSE);
  Serial.begin(115200);
  Serial.println("Elechouse Voice Recognition V3 Module\r\nControl LED sample");
  pinMode(sensorPin, INPUT);
  if(myVR.clear() == 0) {
    Serial.println("Recognizer cleared.");
  } else {
    Serial.println("Not find VoiceRecognitionModule.");
    Serial.println("Please check connection and restart Arduino.");
    while(1);
  }
  if(myVR.load((uint8_t)OnRecord) >= 0) {
    Serial.println("startRecord loaded");
  }
  if(myVR.load((uint8_t)OffRecord) >= 0) {
    Serial.println("endRecord loaded");
  }
}

void loop() {
  int ret;
  ret = myVR.recognize(buf, 50);
  if(ret>0) {
    switch(buf[1]) {
      case OnRecord:
        display.clearDisplay();
        sensorValue = analogRead(sensorPin);
        display.setCursor(30,0);
        display.setTextSize(1);
        display.print("LDR Reading:");
        display.setCursor(30,10);
        display.setTextSize(2);
        display.print(sensorValue);
        delay(500);
        break;
      case OffRecord:
        display.clearDisplay();
        break;
      default:
        Serial.println("Record function undefined");
        break;
    }
    display.display();
    printVR(buf);
  }
}

```

I am able to control the display of LDR readings on OLED using pushbutton. Initially it will be in "off" mode. Once I push the button it starts displaying LDr values in the interval of 500 milli seconds. Once I press the button again, It will clear the display.This will run in a loop.

```
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
int sensorPin = A0; // select the input pin for ldr
int sensorValue = 0;
bool toggle = false;
int buttonpin;

#define OLED_RESET 4 // not used / nicht genutzt bei diesem Display
Adafruit_SSD1306 display(OLED_RESET);

 char inChar;
 String string;

void setup()   {

  pinMode(13, OUTPUT);

  buttonpin = 2;
  pinMode(buttonpin, INPUT_PULLUP);
  // initialize with the I2C addr 0x3C / mit I2C-Adresse 0x3c initialisieren
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);

  Serial.begin(9600);
  display.display();
  delay(2000);
  display.clearDisplay();

  display.setTextColor(INVERSE);
}

void loop()
{
     if (digitalRead(buttonpin) == HIGH)
     {
      toggle = !toggle;
      while(digitalRead(buttonpin) == HIGH);
     }
      switch( toggle )
         {

          case 1:
           display.clearDisplay();
            sensorValue = analogRead(sensorPin);
            Serial.println(sensorValue);
            display.setCursor(30,0);
            display.setTextSize(1);
            display.print("LDR Reading:");
            display.setCursor(30,10);
            display.setTextSize(2);
            display.print(sensorValue);
            delay(500);

            break;

           case 0:
            display.clearDisplay();

            break;
           }
       display.display();

 }

```

If you could suggest how I should merge my previous code and the above code so that I could control the display using voice commands, It'll be great!!.

Thanks in advance!

# Answer
> But it remains frozen in the first reading.

because in the next run of loop(), the "ret = myVR.recognize(buf, 50);" returns a value of 0 -\> no voice command is recognized.

the way to do it is to have a state machine like this:

```
  ret = myVR.recognize(buf, 50);  //read the voice command
  switch(buf[1]) {
      case OnRecord:
        if (vr_state == OffRecord) vr_state = OnRecord; //from previous off to on now
        break;
      case OffRecord:
        vr_state = OffRecord; //now to be off
        break;
      default:
        break; //do nothing -> keep status quo
  }
  //process vr_state
  switch (vr_state) ...

```

basically, there is potentially information even if no voice command is received (aka. previously OnRecord and now silence). your code's reaction to "ret" is dependent on its value now and its value previously.
> 1 votes

# Answer
To keep reading and reporting a sensor within `loop()` after each `On` command, until an `Off` command occurs, add a flag variable – eg, `tellSensor` – to control that reading and reporting. Declare the variable outside `loop()`, or declare it static within `loop()`, and initialize it false.

In the code for `case OnRecord:`, initialize the display (eg, clear display and print the `LDR Reading:` heading) and set `tellSensor` true.

In the code for `case OffRecord:`, clear the display and set `tellSensor` false.

After the end of the `if(ret>0) { ... }` if statement, say something like

```
if (tellSensor) {
   display.setCursor(30,10);
   display.setTextSize(2);
   display.print(sensorValue);
   delay(500);
}

```
> 0 votes

---
Tags: programming, display
---


title: Using Arduino and Motor Shield

text:
# Question
Title: Using Arduino and Motor Shield
I am a beginner in Arduino.I want to connect 2 motors to Arduino. Do I require a motor shield?And if yes please tell why? Also can i use an amplifier to increase the voltage for the motors?

And one last important question, I have just seen the motor shield's pic. Does it restrict arduino's pin usage? I mean we can't use the arduino pins if we use the motor shield right?

PS: I am talking about this model: SLAEX039 L293D Motor Shield

Thank a lot

# Answer
Yes. To use standard D.C. motors, you must use a motor shield or the L239D chip. This is mainly due to motor noise, and control to run the motor at different speeds and directions. Also you get very easy to use libraries!
> -1 votes

---
Tags: arduino-uno, motor, arduino-motor-shield
---


# Question
Title: Can I compile a sketch for my attiny85 without an arduino board?
I have a lot of Raspberry Pi's laying around, so I want to use those to program my attiny85 chips. The problem is that most of the code examples, libraries, and documentation out there assume you're using Arduino. Can I run Arduino commandline software on my Raspberry Pi, and use that to program the attiny85?

I'm trying to compile an RF24 program for the attiny using avr-g++, but I'm running into too many dependency errors, and I wonder if things will just be easier if I use Arduino software.\`

# Answer
> 3 votes
Why wouldn't you be able to?

The compiler runs on the computer, not on the Arduino board. You don't need a board to be connected to compile either. If you enable verbose output during compile in the Arduino IDE settings it will tell you where it puts the resulting .hex file, after which you can use `avr-dude` to upload it to the target MCU.

If you want to use Arduino libraries you'll need to use an core for ATTiny devices (e.g. ATTinyCore). But either way you don't need an Arduino board to compile.

---

I'd also echo what @Marcus says, for the small devices you are better off completely ditching the Arduino stuff (it's such badly written, bloated, and inefficient), and simply starting with a nice clean C file.

There is nothing stopping you using the Arduino IDE or the `avr-libc` tools which it uses. If you add your own `main()` function in a C file and don't put anything in the `.ino` file you will be able to compile without any of the bloat.

# Answer
> 0 votes
"Arduino" makes a statement on the mcu in use.

Technologically, it's extremely unlikely you could run most sketches on devices with less than 1kB of RAM (largest SRAM in Attiny85 is 512 B; most models are smaller).

So, no. The idea "microcontrollers are by now capable enough to run a C++ subset on them directly" behind arduino simply doesn't seem to apply to the Attiny85.

However, there's the "cuteduino", which actually should work with a small set of basic Arduino libraries. It's based on the Attiny85.

I'd argue that you simply *don't want to* use Arduino on Attinies; these devices are so resource-constrained, that you probably want to keep in control.

Now, the RF24 lib comes with non-arduino attiny85 support, so go for that? http://tmrh20.github.io/RF24/ATTiny.html

# Answer
> 0 votes
You can disregard the answers that say you can't compile for the ATtiny85 using the Arduino IDE. I have done so many times, for example my torch locator project which uses the ATtiny85 and the Arduino IDE to compile for it.

Here's my "board":

View from other side:

Code:

```
// ATtiny85 torch detector
// Author: Nick Gammon
// Date: 25 February 2015

// ATMEL ATTINY 25/45/85 / ARDUINO
// Pin 1 is /RESET
//
//                  +-\/-+
// Ain0 (D 5) PB5  1|    |8  Vcc
// Ain3 (D 3) PB3  2|    |7  PB2 (D 2) Ain1
// Ain2 (D 4) PB4  3|    |6  PB1 (D 1) pwm1
//            GND  4|    |5  PB0 (D 0) pwm0
//                  +----+

/*

  Pin 2 (PB3) <-- LDR (GL5539) --> Pin 7 (PB2) <----> 56 k <----> Gnd

  Pin 5 (PB0) <---- LED ---> 100 R <-----> Gnd

*/

#include <avr/sleep.h>    // Sleep Modes
#include <avr/power.h>    // Power management
#include <avr/wdt.h>      // Watchdog timer

const byte LED = 0;          // pin 5
const byte LDR_ENABLE = 3;   // pin 2
const byte LDR_READ = 1;     // Ain1 (PB2) pin 7
const int LIGHT_THRESHOLD = 200;  // Flash LED when darker than this

 // when ADC completed, take an interrupt
EMPTY_INTERRUPT (ADC_vect);

// Take an ADC reading in sleep mode (ADC)
float getReading (byte port)
  {
  power_adc_enable() ;
  ADCSRA = bit (ADEN) | bit (ADIF);  // enable ADC, turn off any pending interrupt

  // set a2d prescale factor to 128
  // 8 MHz / 128 = 62.5 KHz, inside the desired 50-200 KHz range.

  ADCSRA |= bit (ADPS0) | bit (ADPS1) | bit (ADPS2);

  if (port >= A0)
    port -= A0;

#if defined(__AVR_ATtiny85__)
  ADMUX = (port & 0x07);  // AVcc
#else
  ADMUX = bit (REFS0) | (port & 0x07);  // AVcc
#endif

  noInterrupts ();
  set_sleep_mode (SLEEP_MODE_ADC);    // sleep during sample
  sleep_enable();

  // start the conversion
  ADCSRA |= bit (ADSC) | bit (ADIE);
  interrupts ();
  sleep_cpu ();
  sleep_disable ();

  // reading should be done, but better make sure
  // maybe the timer interrupt fired

  // ADSC is cleared when the conversion finishes
  while (bit_is_set (ADCSRA, ADSC))
    { }

  byte low  = ADCL;
  byte high = ADCH;

  ADCSRA = 0;  // disable ADC
  power_adc_disable();

  return (high << 8) | low;

  }  // end of getReading

// watchdog interrupt
ISR (WDT_vect)
{
   wdt_disable();  // disable watchdog
}  // end of WDT_vect

#if defined(__AVR_ATtiny85__)
  #define watchdogRegister WDTCR
#else
  #define watchdogRegister WDTCSR
#endif

void setup ()
  {
  wdt_reset();
  pinMode (LED, OUTPUT);
  pinMode (LDR_ENABLE, OUTPUT);
  ADCSRA = 0;            // turn off ADC
  power_all_disable ();  // power off ADC, Timer 0 and 1, serial interface
  }  // end of setup

void loop ()
  {
  // power up the LDR, take a reading
  digitalWrite (LDR_ENABLE, HIGH);
  int value = getReading (LDR_READ);
  // power off the LDR
  digitalWrite (LDR_ENABLE, LOW);

  // if it's dark, flash the LED for 2 mS
  if (value < LIGHT_THRESHOLD)
    {
    power_timer0_enable ();
    delay (1);  // let timer reach a known point
    digitalWrite (LED, HIGH);
    delay (2);
    digitalWrite (LED, LOW);
    power_timer0_disable ();
    }

  goToSleep ();
  }  // end of loop

void goToSleep ()
  {
  set_sleep_mode (SLEEP_MODE_PWR_DOWN);
  noInterrupts ();       // timed sequence coming up

  // pat the dog
  wdt_reset();

  // clear various "reset" flags
  MCUSR = 0;
  // allow changes, disable reset, clear existing interrupt
  watchdogRegister = bit (WDCE) | bit (WDE) | bit (WDIF);
  // set interrupt mode and an interval (WDE must be changed from 1 to 0 here)
  watchdogRegister = bit (WDIE) | bit (WDP2) | bit (WDP1) | bit (WDP0);    // set WDIE, and 2 seconds delay

  sleep_enable ();       // ready to sleep
  interrupts ();         // interrupts are required now
  sleep_cpu ();          // sleep
  sleep_disable ();      // precaution
  }  // end of goToSleep

```

Compiled under the IDE it uses 16% of program memory:

```
Sketch uses 1,370 bytes (16%) of program storage space. Maximum is 8,192 bytes.
Global variables use 9 bytes of dynamic memory.

```

Claims that the Arduino IDE is badly written and inefficient are not generally true. To a certain extent the Arduino libraries favour ease-of-use over compactness, however you don't have to use them.

The IDE is just a front-end to the avr-g++ compiler. It is easy to use, and produces a .hex file which you can then upload to your chip using a suitable ICSP interface.

The avr-g++ compiler itself does aggressive code optimization. You won't get any advantage from ditching the IDE and using the avr-g++ compiler yourself - it's the same compiler. And if you think you can do better in assembler, good luck! The compiler-writers know all the tricks for storing variables in registers, and minimizing code in various ways. You will be hard pressed to write better code than the compiler generates anyway.

---

Claims that the IDE generates bloated code are Complete Nonsense. Take this sketch:

```
int main ()
  {
  DDRB = bit (2);  // pin 7 on chip

  while (true)
    {
    PINB = bit (2); // blink it
    }
  }

```

Compiled for the ATtiny85 under the IDE 1.6.9 I get this program memory usage:

```
Sketch uses 60 bytes (0%) of program storage space. Maximum is 8,192 bytes.
Global variables use 0 bytes of dynamic memory.

```

There are 15 interrupt vectors at the start of program memory, for which space has to be reserved. So 30 of those bytes are accounted for by that unavoidable overhead.

Here is the full disassembly of the above:

```
Disassembly of section .text:

00000000 <__vectors>:
   0:   0e c0           rjmp    .+28        ; 0x1e <__ctors_end>
   2:   15 c0           rjmp    .+42        ; 0x2e <__bad_interrupt>
   4:   14 c0           rjmp    .+40        ; 0x2e <__bad_interrupt>
   6:   13 c0           rjmp    .+38        ; 0x2e <__bad_interrupt>
   8:   12 c0           rjmp    .+36        ; 0x2e <__bad_interrupt>
   a:   11 c0           rjmp    .+34        ; 0x2e <__bad_interrupt>
   c:   10 c0           rjmp    .+32        ; 0x2e <__bad_interrupt>
   e:   0f c0           rjmp    .+30        ; 0x2e <__bad_interrupt>
  10:   0e c0           rjmp    .+28        ; 0x2e <__bad_interrupt>
  12:   0d c0           rjmp    .+26        ; 0x2e <__bad_interrupt>
  14:   0c c0           rjmp    .+24        ; 0x2e <__bad_interrupt>
  16:   0b c0           rjmp    .+22        ; 0x2e <__bad_interrupt>
  18:   0a c0           rjmp    .+20        ; 0x2e <__bad_interrupt>
  1a:   09 c0           rjmp    .+18        ; 0x2e <__bad_interrupt>
  1c:   08 c0           rjmp    .+16        ; 0x2e <__bad_interrupt>

0000001e <__ctors_end>:
  1e:   11 24           eor r1, r1
  20:   1f be           out 0x3f, r1    ; 63
  22:   cf e5           ldi r28, 0x5F   ; 95
  24:   d2 e0           ldi r29, 0x02   ; 2
  26:   de bf           out 0x3e, r29   ; 62
  28:   cd bf           out 0x3d, r28   ; 61
  2a:   02 d0           rcall   .+4         ; 0x30 <main>
  2c:   05 c0           rjmp    .+10        ; 0x38 <_exit>

0000002e <__bad_interrupt>:
  2e:   e8 cf           rjmp    .-48        ; 0x0 <__vectors>

00000030 <main>:
  30:   84 e0           ldi r24, 0x04   ; 4
  32:   87 bb           out 0x17, r24   ; 23
  34:   86 bb           out 0x16, r24   ; 22
  36:   fe cf           rjmp    .-4         ; 0x34 <main+0x4>

00000038 <_exit>:
  38:   f8 94           cli

0000003a <__stop_program>:
  3a:   ff cf           rjmp    .-2         ; 0x3a <__stop_program>

```

I can't see much bloat there.

---

> I wonder if things will just be easier if I use Arduino software

Yes, much easier.

---
Tags: avr, nrf24l01+
---


# Question
Title: Move a servo slowly between 2 positions based on input
I am trying to move model railroad crossing gates from a vertical position to a horizontal position when a train is detected. I have the electronics in for the sensing of train position but want the gates to go down and stay down while the train passed.

To do this, I am looking to be able to use an Arduino to slowly move a servo between two different positions based on a digital input (HIGH or LOW) to one of the digital input pins.

When this digital input goes HIGH, the servo needs to slowly move to the other end of travel and then stop. It must stay there until the digital input goes LOW, at which time it needs to slowly move back to the starting position and again await for a HIGH input.

I cannot figure out how to move the servo slowly to each position and keep it there.

# Answer
> 1 votes
Lacking information about the context of the servo action (ie, what needs to happen at the same time), I'll assume your paradigm uses a `loop()` function that executes fairly rapidly, and from time to time invokes any necessary actions.

Servo angles can be measured in degrees (typically 0 to 180) or microseconds (typically 1000 to 2000, corresponding to 0° to 180°). The servo library will accept numbers in either range, and act according to which range the numbers are in. Note that representing servo angles in microseconds instead of degrees gives about 5.55 times better resolution. The method outlined below doesn't care which you use.

Also assume the two servo angles mentioned in the question are A and B, with the servo at A if the input pin is low for a long time; and that the desired rate of swing is ±U units of angle every S milliseconds. Let P = current servo position; T = `millis()` value at most recent step, initially 0; and V = previous value of input pin.

In each pass through `loop()`:

• Test the input pin. If it isn't equal to V, toggle V and take a step. (See below.).
• If `millis()`-T \> S, take a step. (See below.)
• Do any other brief per-loop actions

To take a step:
• Add (2\*(V\>0)-1) * U to P. The expression (V\>0) equals 1 or 0, so (2\*(V\>0)-1) is 1 if V is true, and -1 if V is false.
• If (V) and P \> B, set P = B
• If (!V) and P \< A, set P = A
• Servo to position P
• Set T = `millis()`

*Edit:* You should create meaningful variable or constant names to represent the quantities A, B, P, S, T, U, V. Note that S and T should be declared as constants; and if A, B won't change, make them constants also. State-maintaining quantities P and T should be declared via file-scope variables or globals (outside `loop()`) or with static allocation (inside `loop()`), so that their values are maintained as `main()` repeatedly calls `loop()`.

---
Tags: servo
---


# Question
Title: Programming Attiny45 using Arduino Uno with weird behavior
I bought an Arduino Uno a few days ago.

I programmed an ATtiny45 using an Arduino Uno following "How-To: Shrinkify Your Arduino Projects" video on YouTube.

I uploaded the blink example successfully. I altered the sketch in a way so there is also a blinking on pin 4 (which is ATtiny45 pin 3).

Now, if I connect +5V from the Arduino to ATtiny45 pin 8, ground to pin 4 and the LEDs from pin 2 and 3 to ground everything works as expected.

But if I use 4 AA batteries instead of the power from the Arduino I only get a blinking on ATtiny pin2.

What could be the reason for this behavior? Is it because I use 4 AA -\> 6 V instead of 5 V? I tested it also with 3 AA batteries and got the same result.

So why does it work if I use power and ground from the Arduino but not from the batteries?

# Answer
If you take a look at Attiny45 datasheet, you will find at the very first page:

> Operating Voltage
>
> * 1.8 - 5.5V for ATtiny25V/45V/85V
> * 2.7 - 5.5V for ATtiny25/45/85

Your circuit will have unpredictable behavior out of this range. If you want to use four AA cels, you can organize them to have a 3V output or use a step-down voltage regulator.
> 1 votes

---
Tags: arduino-uno, attiny, battery
---


# Question
Title: how to get precise value from float variable?
```
#include <NeoSWSerial.h>

//#include <SoftwareSerial.h>
#include <AltSoftSerial.h>
#include <NMEAGPS.h>

NeoSWSerial GSM(2, 3); // RX, TX: Connect TXD to RX & RXD to TX

static const int RXPin = 8, TXPin = 9;
AltSoftSerial gpsPort(RXPin, TXPin);
static const uint32_t GPSBaud = 9600;

NMEAGPS gps;
gps_fix fix;
uint8_t fixCount = 0;
char dt[15],tm[15];
float lati,longi;
//int block = 0;

enum _parseState {
  PS_DETECT_MSG_TYPE,

  PS_IGNORING_COMMAND_ECHO,

  PS_HTTPPARA_RESPONSE,

  PS_HTTPACTION_TYPE,
  PS_HTTPACTION_RESULT,
  PS_HTTPACTION_LENGTH,

  PS_HTTPREAD_LENGTH,
  PS_HTTPREAD_CONTENT
};

enum _actionState {
  AS_IDLE,
  AS_WAITING_FOR_RESPONSE
};

byte actionState = AS_IDLE;
unsigned long lastActionTime = 0;

float s;

byte parseState = PS_DETECT_MSG_TYPE;
char buffer[160],url[160];
byte pos = 0;

int contentLength = 0;

void resetBuffer() {
  memset(buffer, 0, sizeof(buffer));
  pos = 0;
}

void sendGSM(const char* msg, int waitMs = 500) {
  GSM.println(msg);
  while(GSM.available()) {
    parseATText(GSM.read());
  }
  //delay(waitMs);
}

void setup()
{
  GSM.begin(9600);
  Serial.begin(9600);
  gpsPort.begin(GPSBaud);

  Serial.println(F("Hinder LOADING....."));
  Serial.println(F("obtain gps and store data to database"));
  Serial.println(F("Testing by : "));
  Serial.println(F("Nikhil,Muthumani and Mathews"));
  Serial.println();

  sendGSM("AT+SAPBR=3,1,\"APN\",\"vodafone\"");
  delay(500);
  sendGSM("AT+SAPBR=1,1",3000);
  delay(500);
  sendGSM("AT+HTTPINIT");
  delay(500);
  sendGSM("AT+HTTPPARA=\"CID\",1");
  delay(500);
}

void loop()
{
  unsigned long now = millis();
  while (gps.available( gpsPort )) {
    fix = gps.read();
     //Serial.println(F("b"));
    // Once every 5 seconds...
    if (++fixCount >= 5) {
       //Serial.println(F("a"));
      displayInfo();

      //send the next report if previous one is finished
      if ( actionState == AS_IDLE ) {
      sprintf(url, "AT+HTTPPARA=\"URL\",\"http://**************/***.php?lat=%d&lng=%d&speed=%d&date=%s&time=%s\"",lati,longi,s,dt,tm );
      sendGSM(url);
     // lastActionTime = now;
      parseState = PS_HTTPPARA_RESPONSE; // a new state
      actionState = AS_WAITING_FOR_RESPONSE;
      fixCount = 0;
    }

    }
  }

/*  if ((gps.statistics.chars < 10) && (millis() > 5000)) {
     Serial.println( F("No GPS detected: check wiring.") );
     while(true);
     block=1;
    }*/

  while(GSM.available()) {
    //lastActionTime = now;
    parseATText(GSM.read());
  }
 }

void displayInfo()
{
  Serial.print(F("Location: "));
  if (fix.valid.location) {
    lati=( fix.latitude());
    //sprintf(lati,"%d",fix.latitude(),5);
    Serial.print(lati);
    Serial.print( ',' );
    longi= ( fix.longitude());
    //sprintf(longi,"%d",fix.longitude(),5);
    Serial.print(longi);
  } else {
    Serial.print(F("INVALID"));
  }

  Serial.print(F("  Speed: "));
  if (fix.valid.speed) {
    s=fix.speed_kph();
    Serial.print(s);
    Serial.print(F(" KMPH "));
  } else {
    Serial.print(F("INVALID"));
  }

  // Shift the date/time to local time
  NeoGPS::clock_t localSeconds;
  NeoGPS::time_t  localTime;
  if (fix.valid.date && fix.valid.time) {
    using namespace NeoGPS; // save a little typing below...

    localSeconds = (clock_t) fix.dateTime; // convert structure to a second count
    localSeconds += 5 * SECONDS_PER_HOUR + 30 * SECONDS_PER_MINUTE; // shift timezone
    localTime = localSeconds;              // convert back to a structure
  }

  Serial.print(F("  Date : "));
  if (fix.valid.date) {
    sprintf(dt,"%02d/%02d/20%d",fix.dateTime.date,fix.dateTime.month,fix.dateTime.year);
    Serial.print(dt);
  } else {
    Serial.print(F("INVALID"));
  }

  Serial.print(F("  Time : "));
  if (fix.valid.time) {
    if (localTime.hours>12)localTime.hours-=12;//To convert 24 hr format to 12 hr format
    sprintf(tm,"%02d:%02d:%02d",localTime.hours,localTime.minutes,localTime.seconds);
    Serial.print(tm);
    //block=1;
  } else {
    Serial.print(F("INVALID"));
  }

  Serial.println();
}

void parseATText(byte b) {

  buffer[pos++] = b;

  if ( pos >= sizeof(buffer) )
    resetBuffer(); // just to be safe

  /*
   // Detailed debugging
   Serial.println();
   Serial.print("state = ");
   Serial.println(state);
   Serial.print("b = ");
   Serial.println(b);
   Serial.print("pos = ");
   Serial.println(pos);
   Serial.print("buffer = ");
   Serial.println(buffer);*/

  switch (parseState) {

  case PS_HTTPPARA_RESPONSE:
    {
      parseState = PS_DETECT_MSG_TYPE;
      sendGSM("AT+HTTPACTION=0");
     /*  while(GSM.available()) {
    //lastActionTime = now;
    parseATText(GSM.read());
  }*/

    }
    break;

  case PS_DETECT_MSG_TYPE:
    {
      if ( b == '\n' )
        resetBuffer();
      else {
        if ( pos == 3 && strcmp(buffer, "AT+") == 0 ) {
          parseState = PS_IGNORING_COMMAND_ECHO;
        }
        else if ( b == ':' ) {
          //Serial.print("Checking message type: ");
          //Serial.println(buffer);

          if ( strcmp(buffer, "+HTTPACTION:") == 0 ) {
            Serial.println("Received HTTPACTION");
            parseState = PS_HTTPACTION_TYPE;
          }
          else if ( strcmp(buffer, "+HTTPREAD:") == 0 ) {
            Serial.println("Received HTTPREAD");
            parseState = PS_HTTPREAD_LENGTH;
          }
          resetBuffer();
        }
      }
    }
    break;

  case PS_IGNORING_COMMAND_ECHO:
    {
      if ( b == '\n' ) {
        Serial.print("Ignoring echo: ");
        Serial.println(buffer);
        parseState = PS_DETECT_MSG_TYPE;
        resetBuffer();
      }
    }
    break;

  case PS_HTTPACTION_TYPE:
    {
      if ( b == ',' ) {
        Serial.print("HTTPACTION type is ");
        Serial.println(buffer);
        parseState = PS_HTTPACTION_RESULT;
        resetBuffer();
      }
    }
    break;

  case PS_HTTPACTION_RESULT:
    {
      if ( b == ',' ) {
        Serial.print("HTTPACTION result is ");
        Serial.println(buffer);
        parseState = PS_HTTPACTION_LENGTH;
        resetBuffer();
      }
    }
    break;

  case PS_HTTPACTION_LENGTH:
    {
      if ( b == '\n' ) {
        Serial.print("HTTPACTION length is ");
        Serial.println(buffer);

        // now request content
        GSM.print("AT+HTTPREAD=0,");
        GSM.println(buffer);

        parseState = PS_DETECT_MSG_TYPE;
        resetBuffer();
      }
    }
    break;

  case PS_HTTPREAD_LENGTH:
    {
      if ( b == '\n' ) {
        contentLength = atoi(buffer);
        Serial.print("HTTPREAD length is ");
        Serial.println(contentLength);

        Serial.print("HTTPREAD content: ");

        parseState = PS_HTTPREAD_CONTENT;
        resetBuffer();
      }
    }
    break;

  case PS_HTTPREAD_CONTENT:
    {
      // for this demo I'm just showing the content bytes in the serial monitor
      Serial.write(b);

      contentLength--;

      if ( contentLength <= 0 ) {

        // all content bytes have now been read

        parseState = PS_DETECT_MSG_TYPE;
        resetBuffer();

        Serial.print("\n\n\n");

        actionState = AS_IDLE;
      }
    }
    break;
  }
}

```

in this I try obtain the GPS latitude and longitude at every 5 secs and and use that values to find the name of the location.I need to pass the value of latitude and longitude over the URL to the php code and there it is converted to the location name.I also need to pass the speed,date and time (speed and date works fine). When i try to sent them the command displayed on the window is `Ignoring echo: AT+HTTPPARA="URL","http://[link]/hinder.php?lat=?&lng=?&speed=?&date=&time=16/04/2017"` here you can see instead of value of latitude,speed and longitude a question mark appears.So i tried

```
sprintf(url, "AT+HTTPPARA=\"URL\",\"http://masp203.000webhostapp.com/hinder.php?lat=%f&lng=%f&speed=%d&date=%s&time=%s\"",fix.latitude(),fix.longitude(),fix.speed_kph(),dt,tm ); sendGSM(url);

```

but that too didnt worked.I need a presice value of latitude and longitude (about 5 decimal points) since it is used to find the location.Can any one tell me hoe can i do that .

# Answer
> 1 votes
Floating point values aren't precise.

However you problem has nothing to do with precision, but purely how you are representing the value as text. You are asking for the format `%f` which, by default on Arduino, is not supported by `sprintf`.

Instead you have to use the function `dtostrf()` (a non-standard libavr specific function).

```
char floatval[10]; // Room for 9 characters + NULL
float myVal = 48.53927853;

dtostrf(myVal, 9, 5, floatval);

```

Selection of the right numbers is critical. The first is the total space you have available in the target character array (not including the required NULL, so one less than the size of the array). The second is the number of decimal places to render. So you have to make sure you have enough room for the integer portion, any sign (if it's negative) and the decimal point, plus the number of decimal places you want to render - in this case:

* 1 - Sign
* 2 - Integer
* 1 - Decimal point
* 5 - Decimal portion

Total: 1+2+1+5 = 9.

The first value, width, can also be given as a negative value, in which case left alignment of the content will be performed.

# Answer
> 1 votes
If you aren't going to be computing with the GPS coordinates, I'd suggest keeping the character strings just as they were delivered by the device. You'll keep all of the precision available without introducing any quantization or roundoff errors.

# Answer
> 0 votes
> how to get precise value from float variable?

possible solutions:

1) don't use float where precise values are needed - by far the best solution;

2) use fixed point types;

3) use integer types;

...

# Answer
> 0 votes
> I need a precise value of latitude and longitude (about 5 decimal points) since it is used to find the location. Can any one tell me how can I do that.

If you only need 5 decimal points, you can continue to use `float` values. If you would like more precision, you can use the 32-bit integer forms of lat/lon provided by NeoGPS.

For `float` values, you can do as Majenko suggested. Just like the date and time arrays, you format that floating-point lat and lon values into their own character arrays. Then put them in the `url` array with `sprintf` and "%s", just like the `dt` and `tm` arrays.

To get the extra digits of precision, you have to use the `fix.latitudeL()` and `fix.longitudeL()` functions. They return integers that have 10 significant digits. They are scaled by 10000000, so you have to insert the decimal point at the right place. The example program NMEAloc.ino shows how to print those integers as if they were floating-point values.

Since you are using `sprintf`, you could format latitude like this:

```
char lat[16];
int deg = fix.latitudeL() / 10000000L; // possibly negative
int decimals = abs( fix.latitude() - deg * 10000000L );
sprintf( lat, "%d.%07d", deg, decimals );

```

Then format this into the `url` array with %s:

```
sprintf( url, " ... &lat=%s&...", ... , lat, ... );

```

That gives you 7 decimals, like `9.7451145`

---
Tags: gsm, gps, float
---


# Question
Title: why there is errorneous output on start up and how to avoid it?
I wrote an Arduino code to get the latitude,longitude,speed,date and time using the GPS SKG 13BL at every 5 secs and sent it to the database with the help of a php code using GSM 900A.The code is as follows :

```
#include <NeoSWSerial.h>

#include <AltSoftSerial.h>
#include <NMEAGPS.h>

NeoSWSerial GSM(2, 3); // RX, TX: Connect TXD to RX & RXD to TX

static const int RXPin = 8, TXPin = 9;
AltSoftSerial gpsPort(RXPin, TXPin);
static const uint32_t GPSBaud = 9600;

NMEAGPS gps;
gps_fix fix;
uint8_t fixCount = 0;
char dt[15],tm[15],lati[10],longi[10];

enum _parseState {
  PS_DETECT_MSG_TYPE,

  PS_IGNORING_COMMAND_ECHO,

  PS_HTTPPARA_RESPONSE,

  PS_HTTPACTION_TYPE,
  PS_HTTPACTION_RESULT,
  PS_HTTPACTION_LENGTH,

  PS_HTTPREAD_LENGTH,
  PS_HTTPREAD_CONTENT
};

enum _actionState {
  AS_IDLE,
  AS_WAITING_FOR_RESPONSE
};

byte actionState = AS_IDLE;
unsigned long lastActionTime = 0;

int s;

byte parseState = PS_DETECT_MSG_TYPE;
char buffer[160],url[160];
byte pos = 0;

int contentLength = 0;

void resetBuffer() {
  memset(buffer, 0, sizeof(buffer));
  pos = 0;
}

void sendGSM(const char* msg, int waitMs = 500) {
  GSM.println(msg);
  while(GSM.available()) {
    parseATText(GSM.read());
  }
  //delay(waitMs);
}

void setup()
{
  GSM.begin(9600);
  Serial.begin(9600);
  gpsPort.begin(GPSBaud);

  Serial.println(F("Hinder LOADING....."));
  Serial.println(F("obtain gps and store data to database"));
  Serial.println(F("Testing by : "));
  Serial.println(F("Nikhil,Muthumani and Mathews"));
  Serial.println();

  sendGSM("AT+SAPBR=3,1,\"APN\",\"vodafone\"");
  delay(500);
  sendGSM("AT+SAPBR=1,1",3000);
  delay(500);
  sendGSM("AT+HTTPINIT");
  delay(500);
  sendGSM("AT+HTTPPARA=\"CID\",1");
  delay(500);
}

void loop()
{
  unsigned long now = millis();
  while (gps.available( gpsPort )) {
    fix = gps.read();
     //Serial.println(F("b"));
    // Once every 5 seconds...
    if (++fixCount >= 5) {
       //Serial.println(F("a"));
      displayInfo();

      //send the next report if previous one is finished
      if ( actionState == AS_IDLE ) {
      sprintf(url, "AT+HTTPPARA=\"URL\",\"http://********.com/***er.php?lat=%s&lng=%s&speed=%d&date=%s&time=%s\"",lati,longi,s,dt,tm );
      sendGSM(url);
     // lastActionTime = now;
      parseState = PS_HTTPPARA_RESPONSE; // a new state
      actionState = AS_WAITING_FOR_RESPONSE;
      fixCount = 0;
    }

    }
  }

/*  if ((gps.statistics.chars < 10) && (millis() > 5000)) {
     Serial.println( F("No GPS detected: check wiring.") );
     while(true);
     block=1;
    }*/

  while(GSM.available()) {
    //lastActionTime = now;
    parseATText(GSM.read());
  }
 }

void displayInfo()
{
  Serial.print(F("Location: "));
  if (fix.valid.location) {
    dtostrf( fix.latitude(),7,5,lati);
    //sprintf(lati,"%d",fix.latitude(),5);
    Serial.print(lati);
    Serial.print( ',' );
    dtostrf( fix.longitude(),8,5,longi);
    //sprintf(longi,"%d",fix.longitude(),5);
    Serial.print(longi);
  } else {
    Serial.print(F("INVALID"));
  }

  Serial.print(F("  Speed: "));
  if (fix.valid.speed) {
    s=fix.speed_kph();
    Serial.print(s);
    Serial.print(F(" KMPH "));
  } else {
    Serial.print(F("INVALID"));
  }

  // Shift the date/time to local time
  NeoGPS::clock_t localSeconds;
  NeoGPS::time_t  localTime;
  if (fix.valid.date && fix.valid.time) {
    using namespace NeoGPS; // save a little typing below...

    localSeconds = (clock_t) fix.dateTime; // convert structure to a second count
    localSeconds += 5 * SECONDS_PER_HOUR + 30 * SECONDS_PER_MINUTE; // shift timezone
    localTime = localSeconds;              // convert back to a structure
  }

  Serial.print(F("  Date : "));
  if (fix.valid.date) {
    sprintf(dt,"%02d/%02d/20%d",fix.dateTime.date,fix.dateTime.month,fix.dateTime.year);
    Serial.print(dt);
  } else {
    Serial.print(F("INVALID"));
  }

  Serial.print(F("  Time : "));
  if (fix.valid.time) {
    if (localTime.hours>12)localTime.hours-=12;//To convert 24 hr format to 12 hr format
    sprintf(tm,"%02d:%02d:%02d",localTime.hours,localTime.minutes,localTime.seconds);
    Serial.print(tm);
    //block=1;
  } else {
    Serial.print(F("INVALID"));
  }

  Serial.println();
}

void parseATText(byte b) {

  buffer[pos++] = b;

  if ( pos >= sizeof(buffer) )
    resetBuffer(); // just to be safe

  /*
   // Detailed debugging
   Serial.println();
   Serial.print("state = ");
   Serial.println(state);
   Serial.print("b = ");
   Serial.println(b);
   Serial.print("pos = ");
   Serial.println(pos);
   Serial.print("buffer = ");
   Serial.println(buffer);*/

  switch (parseState) {

  case PS_HTTPPARA_RESPONSE:
    {
      parseState = PS_DETECT_MSG_TYPE;
      sendGSM("AT+HTTPACTION=0");
     /*  while(GSM.available()) {
    //lastActionTime = now;
    parseATText(GSM.read());
  }*/

    }
    break;

  case PS_DETECT_MSG_TYPE:
    {
      if ( b == '\n' )
        resetBuffer();
      else {
        if ( pos == 3 && strcmp(buffer, "AT+") == 0 ) {
          parseState = PS_IGNORING_COMMAND_ECHO;
        }
        else if ( b == ':' ) {
          //Serial.print("Checking message type: ");
          //Serial.println(buffer);

          if ( strcmp(buffer, "+HTTPACTION:") == 0 ) {
            Serial.println("Received HTTPACTION");
            parseState = PS_HTTPACTION_TYPE;
          }
          else if ( strcmp(buffer, "+HTTPREAD:") == 0 ) {
            Serial.println("Received HTTPREAD");
            parseState = PS_HTTPREAD_LENGTH;
          }
          resetBuffer();
        }
      }
    }
    break;

  case PS_IGNORING_COMMAND_ECHO:
    {
      if ( b == '\n' ) {
        Serial.print("Ignoring echo: ");
        Serial.println(buffer);
        parseState = PS_DETECT_MSG_TYPE;
        resetBuffer();
      }
    }
    break;

  case PS_HTTPACTION_TYPE:
    {
      if ( b == ',' ) {
        Serial.print("HTTPACTION type is ");
        Serial.println(buffer);
        parseState = PS_HTTPACTION_RESULT;
        resetBuffer();
      }
    }
    break;

  case PS_HTTPACTION_RESULT:
    {
      if ( b == ',' ) {
        Serial.print("HTTPACTION result is ");
        Serial.println(buffer);
        parseState = PS_HTTPACTION_LENGTH;
        resetBuffer();
      }
    }
    break;

  case PS_HTTPACTION_LENGTH:
    {
      if ( b == '\n' ) {
        Serial.print("HTTPACTION length is ");
        Serial.println(buffer);

        // now request content
        GSM.print("AT+HTTPREAD=0,");
        GSM.println(buffer);

        parseState = PS_DETECT_MSG_TYPE;
        resetBuffer();
      }
    }
    break;

  case PS_HTTPREAD_LENGTH:
    {
      if ( b == '\n' ) {
        contentLength = atoi(buffer);
        Serial.print("HTTPREAD length is ");
        Serial.println(contentLength);

        Serial.print("HTTPREAD content: ");

        parseState = PS_HTTPREAD_CONTENT;
        resetBuffer();
      }
    }
    break;

  case PS_HTTPREAD_CONTENT:
    {
      // for this demo I'm just showing the content bytes in the serial monitor
      Serial.write(b);

      contentLength--;

      if ( contentLength <= 0 ) {

        // all content bytes have now been read

        parseState = PS_DETECT_MSG_TYPE;
        resetBuffer();

        Serial.print("\n\n\n");

        actionState = AS_IDLE;
      }
    }
    break;
  }
}

```

When I test the code it shows the output as :  as you can see after `Ignoring echo: AT+HTTPREAD=0,0` the GPS output is printed out at every sec (not at 5 sec interval) and also does not perform rest of the actions (i.e Sending to database is not performed). And I press reset button and the output is : Even though it prints the GPS output at every sec it inserted the values into database.And once again I press reset button then it works fine.So why do this error occurs and is there a way to solve this.And can I make the program run only when GPS data is available (because now if GPS data is not available it shows some error nature ).

# Answer
> 0 votes
:)

> Why does this error occur, and is there a way to solve this?

Because the GSM operations take time, the GPS data has time to accumulate. Then the `while (gps.available` loop will execute multiple times without breaking. It calls `displayInfo` every time because `fixCount >= 5`. `fixCount` is 6, 7, 8, etc. in consecutive seconds.

To solve this problem, you need to be more restrictive about starting the sending process:

```
void loop()
{
  while (gps.available( gpsPort )) {
    fix = gps.read();
     //Serial.println(F("b"));

    //send a report once every 5 seconds if previous one is finished
    if ((++fixCount >= 5) && (actionState == AS_IDLE)) {

      //Serial.println(F("a"));
      displayInfo();

      sprintf(url, "AT+HTTPPARA=\"URL\",\"http://********.com/***er.php?lat=%s&lng=%s&speed=%d&date=%s&time=%s\"",lati,longi,s,dt,tm );
      sendGSM(url);
      parseState  = PS_HTTPPARA_RESPONSE; // a new state
      actionState = AS_WAITING_FOR_RESPONSE;
      fixCount    = 0;
    }
  }

  while(GSM.available()) {
    parseATText(GSM.read());
  }
}

```

The combined `if` test displays GPS info only when the GSM process begins. Then it will continue to read fixes, keeping the queue emptied. When the state goes back to AS\_IDLE, it can send another update. Notice how this loop structure will continue counting fixes while the GSM process is completing. If the GSM process takes 5 seconds or more, it will immediately send another update when the previous GSM send has completed.

If you want it to wait an *additional* 5 seconds between each GSM update, don't increment the `fixCount` until the GSM process has completed (AS\_IDLE). Then the updates will be sent once every 5 + (GSM send time) seconds, perhaps once every 15 seconds.

> can I make the program run only when GPS data is available (because now if GPS data is not available it shows some error nature ).

Yes, make the `if` test even *more* restrictive by testing the valid flags:

```
    //send a report once every 5 seconds if the data is valid
    //   and the previous one is finished
    if ((fix.valid.location && fix.valid.date && fix.valid.time) &&
        (++fixCount >= 5) &&
        (actionState == AS_IDLE)) {

```

This only counts valid fixes; the `fixCount` will not increment unless those 3 pieces are valid.

NOTE: You probably don't have to test `fix.valid.speed`, as it will be marked as invalid when you are stationary. Testing the valid flags could be removed from `displayInfo()`:

```
void displayInfo()
{
  Serial.print(F("Location: "));
  dtostrf( fix.latitude(),7,5,lati);
  Serial.print(lati);
  Serial.print( ',' );
  dtostrf( fix.longitude(),8,5,longi);
  Serial.print(longi);

  Serial.print(F("  Speed: "));
  if (fix.valid.speed) {
    s=fix.speed_kph();
  } else {
    s=0;
  }
  Serial.print(s);
  Serial.print(F(" KMPH "));

  // Shift the date/time to local time
  NeoGPS::clock_t localSeconds;
  NeoGPS::time_t  localTime;
  {
    using namespace NeoGPS; // save a little typing below...

    localSeconds = (clock_t) fix.dateTime; // convert structure to a second count
    localSeconds += 5 * SECONDS_PER_HOUR + 30 * SECONDS_PER_MINUTE; // shift timezone
    localTime = localSeconds;              // convert back to a structure
  }

  Serial.print(F("  Date : "));
  sprintf(dt,"%02d/%02d/20%d",fix.dateTime.date,fix.dateTime.month,fix.dateTime.year);
  Serial.print(dt);

  Serial.print(F("  Time : "));
  if (localTime.hours>12)localTime.hours-=12;//To convert 24 hr format to 12 hr format
  sprintf(tm,"%02d:%02d:%02d",localTime.hours,localTime.minutes,localTime.seconds);
  Serial.print(tm);
  //block=1;

  Serial.println();
}

```

`displayInfo` still checks `fix.valid.speed` and uses `0` when there is no speed (i.e., when you're stationary).

---
Tags: arduino-uno, gps
---


# Question
Title: Powering 4 servos with an external source
I am powering 4 tower pro sg90's and I NEED them to run at maximum torque for at least a few minutes, so 4.8volts. I am wondering how many AA batteries I will need to power all 4 servos at maximum torque for a short amount of time (like 5minutes type of thing). The servos are basically lifting different 3d printed objects.

# Answer
**When choosing a power source, you'll have to consider a few requirements:**

* Required max amperage (max draw of power)
* Required voltages (AC or DC, and available voltages)
* Does it have to be mobile?
    + How long does it have to be powered? (how to recharge/refuel?)

Also see this tutorial it explains that you need a certain voltage for a device to work, too high voltage can result in permanent damage. For amperage, you need to have at least the minimal required, too much is no problem.

Since you don't really have a problem to fix, I can only tell you what I've worked with or what I've liked.

**Bench supplies**

Bench supplies are great while prototyping, they don't run out (like batteries) and can have a large range of voltage and supply a lot of power. I've looked around to get a nice bench power supply, but I found that they're quite expensive. If you want a variable supply that can do up to 5A, it'll cost you some real money (though it usually is well worth it).

Though my setup has always worked great for me, I use:

For the PSU, you could also add indicator LED's, they're great because they can supply very much power at very convenient voltages (12v, 5v, 3.3v, -12v). Also since it's a PSU it has overcurrent protection and thus is reasonably safe.

I've also bought the "adjustable step down module" from E-bay, you can power it from a 24V or 19V source like a laptop charger. You can set the output voltage and output max amperage. You can even see when the supply is limiting on power or on amperage. (So you can check if your device is taking more current than set)

**"Moving" projects**

The easiest thing here is (multiple) batteries, check the tutorial of sparkfun again. If you put them in series, you will sum up the voltage. If you put them in parallel, you will sum up the capacity.

I think batteries are the easiest way to power your device. You can check different types of batteries, they have different voltages and "ampere hours". Battery holders are cheap and you can easily replace them if they run out.

On the subject of rechargeables, I would go with an Ni-Mh pack. I've got a Ni-Mh pack for airsoft and it's very reliable and easy to charge. Li-Ion requires much more care in handling and charging.

Other options can be solar-cells or other harvestable energy, but these often aren't really viable.

**Extra**

When starting to move, a servo can suddenly pull a lot of power. Not all supplies can handle this well. So the other servo's may "jiggle". Often, it's good to have a capacitor that can act as a "reservoir" or for smoothing. Same goes with devices that reset in some scenario's.

\*I hope this gives you an idea on some possibilities, I haven't highlighted all options (there are too many), you should check tutorials/video's and see what works for you.

For example, check this instructable that focusses on some (analog) points that I didn't mention.\*
> 0 votes

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


# Question
Title: Arduino constant vs Microchip PIC constant
2.2 THE BASICS OF C PROGRAMMING LANGUAGE book is has like this,

> CONSTANTS
>
> A constant is a number or a character having fixed value that cannot be changed during program execution. Unlike variables, **constants are stored in the flash program memory** of the microcontroller for the purpose of saving valuable space of RAM. The compiler recognizes them by their name and prefix const.

And Arduino references has not said where is constant variables are stored either program memory or RAM.

My questions are, where is the saving location of Arduino constant variables? Is it same to Microchip PIC? Those two compilers are same or not in this case?

# Answer
> 6 votes
`const` means different things in different contexts as far as storage goes.

For a simple numeric value the compiler will generally replace the constant with the literal value. Any mathematics using purely constants or literals will be replaced at compile time with the result.

For instance, the code:

```
const int a = 3;
const int b = 4;

void setup() {
    int c = a + b;
    Serial.println(c);
}

void loop() {

}

```

results in the AVR assembly:

```
be: 4a e0           ldi r20, 0x0A   ; 10
c0: 50 e0           ldi r21, 0x00   ; 0

c2: 67 e0           ldi r22, 0x07   ; 7
c4: 70 e0           ldi r23, 0x00   ; 0

c6: 80 e2           ldi r24, 0x20   ; 32
c8: 91 e0           ldi r25, 0x01   ; 1
ca: 0c 94 4a 01     jmp 0x294   ; 0x294 <_ZN5Print7printlnEii>

```

Registers `r22` and `r23` store the second integer parameter to the Serial.println() - the actual function call generated is `_ZN5Print7printlnEii(&Serial, 7, 10)`.

So you see that the literal value 7 has replaced both the sum of the constants and the variable it is placed in.

However it is very different when more complex values are called for - such as arrays (either numeric or character arrays, AKA "C Strings"). In this case yes the values are stored in Flash, however the startup code `crt0.o` copies that data into SRAM so that the software can access it easily.

Generally flash is hard for software to read from. In some architectures it requires special instructions to be executed. In others it requires setting values in SFRs (Special Function Registers) and reading from other SFRs to get the data. In other words it's far harder than just reading from a memory location (a limitation of Harvard Architecture). So it's copied at boot time into SRAM so that it then becomes easy to access, as it's just now accessing a memory location.

However that then defeats one of the objectives of using a constant value - reduction of SRAM usage by placing the data in Flash. So the Arduino has a specific macro `PROGRMEM`, which sets attributes on the variable to say "Never copy this data to SRAM".

More specifically it's actually provided by the file `avr/pgmspace.h` in the avr-gcc compiler:

```
#define __ATTR_PROGMEM__ __attribute__((__progmem__))
#define PROGMEM __ATTR_PROGMEM__

```

But now of course you can't access the data using simple memory accesses, so there are special functions to allow it to be done. Some are alternate versions of standard C library routines, for instance `strcmp_P()` shadows `strcmp()` with the second parameter being a PROGMEM variable. Others are special functions for reading bytes or words from locations in flash, such as `pgm_read_byte_near()`.

The Arduino API also provides an extra little trick, called the `__FlashStringHelper` which is an empty class used to identify strings held in flash for the purpose of *function overloading* so that the `F()` macro can be used to call the right variant of a function to use the flash reading functions instead of assuming the string is in SRAM.

So as you can see it's not as straight forward as "consts are in Flash, non-consts are in RAM".

---

Highlighting the differences between how the AVR accesses Flash and how the various PIC sub-families access Flash:

* The AVR has one single instruction that can read Flash - LPM:

> There is only one instruction for the read access to the program storage space. It is defined for the pointer pair Z and it is named LPM (Load from Program Memory). The instruction copies the byte at program flash address Z to the register R0. As the program memory is organized word-wise (one instruction on one address consists of 16 bits or two bytes or one word) the least significant bit selects the lower or upper byte (0=lower byte, 1= upper byte). Because of this the original address must be multiplied by 2 and access is limited to 15-bit or 32 kB program memory. Like this:
>
> ```
> LDI ZH,HIGH(2*address)
> LDI ZL,LOW(2*address)
> LPM
>
> ```

* PIC10, PIC12 and PIC16 chips have no way of reading the flash.

Instead a "lookup table" of "RETLW" calls is used. For instance the string "Hello" would be stored in flash as:

```
RETLW 72    ; H
RETLW 101   ; e
RETLW 108   ; l
RETLW 108   ; l
RETLW 111   ; o
RETLW 0     ; NULL

```

`RETLW` returns from a `CALL` with the `W` register set to the literal value in the instruction. The entire command, that is both the `RETLW` and the 8 bit literal value, fits into a single 14-bit opcode.

* PIC18 uses SFRs to access the Flash memory. Set the three registers `TBLPTRU`, `TBLPTRH` and `TBLPTRL` to the three bytes of the address in flash you want to read, a `TBLRD` instruction is issued through the `EECON1` register, then you can read the byte from `TABLAT`.
* PIC24 / dsPIC33 uses PSV - Program Space Visibility. This gives you the ability to map a 32kB chunk of the flash memory into the upper 32kB portion of the data space. This allows direct reading of data from within that 32kB chunk as if it were in RAM.
* PIC32 uses a *Von Neumann* architecture which means that Flash and SRAM both share the same 32-bit address space. There is no difference reading from Flash or SRAM, so no special instructions are needed.

The only chip from those above where `const` really means `const` is the PIC32 where there is no need to copy from Flash to SRAM during startup since all the Flash memory can be directly accessed with normal MIPS `LW` and `LB` etc instructions.

# Answer
> 1 votes
Constants can still use RAM. The decision whether to store it or not in RAM is up to the compiler. It may, for example, put the constant into RAM and then reference that constant throughout the code. The main use of constants is to act as a remainder that you cannot change that value. My personal experience tells me that `const` occupy the same RAM that `int` type does.

Using `const` does not prevent the values to be stored in RAM. If you want to prevent this behavior you should use PROGMEM

> Store data in flash (program) memory instead of SRAM. There's a description of the various types of memory available on an Arduino board. The PROGMEM keyword is a variable modifier, it should be used only with the datatypes defined in pgmspace.h. It tells the compiler "put this information into flash memory", instead of into SRAM, where it would normally go.

This link may also be useful.

# Answer
> 0 votes
> My questions are, where is the saving location of Arduino constant variables? Is it same to Microchip PIC? Those two compilers are same or not in this case?

how compilers handle "const" declarations varies greatly. "const" does nothing but telling that compiler that no modification to that variable is possible.

in the embedded world, that's typically done by putting that variable in flash / rom.

however, that treatment isn't universal. gcc-avr (my winavr from 2009) for example treats "const" just as any other ram types, putting it in either data section or bss section, depending on their initialization (or lack of).

PROGMEM attributes can forcefully change that, however.

---
Tags: arduino-uno, memory-usage, sram, memory, compiler
---