title: OLED display wrong (using SPI )

text:
# Question
Title: OLED display wrong (using SPI )
I can't figure out where I doing wrong

https://www.youtube.com/watch?v=35NqOANmgUE

This is my question in videos

The both of two connect the same pin

(so the right display result is the correct OLED)

My connecting table (using SPI )

GND gnd

VCC 5V

D0(OLED\_CLK) 10

D(OLED\_MOSI) 9

RES(OLED\_RESET) 13

D/C(OLED\_DC) 11

CS（OLED\_CS） 12

but the left OLED doesn't have the "RES" pin (so I didn't connect it)

the left OLED just display the upper part (and its the position of display picture is also wired ,too)

this is my code

```
/*********************************************************************
This is an example for our Monochrome OLEDs based on SSD1306 drivers
This example is for a 128x64 size display using SPI to communicate
4 or 5 pins are required to interface

Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!

Written by Limor Fried/Ladyada  for Adafruit Industries.
BSD license, check license.txt for more information
All text above, and the splash screen must be included in any redistribution
*********************************************************************/

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

// If using software SPI (the default case):
#define OLED_MOSI   9
#define OLED_CLK   10
#define OLED_DC    11
#define OLED_CS    12
#define OLED_RESET 13
Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);

/* Uncomment this block to use hardware SPI
#define OLED_DC     6
#define OLED_CS     7
#define OLED_RESET  8
Adafruit_SSD1306 display(OLED_DC, OLED_RESET, OLED_CS);
*/

#define NUMFLAKES 10
#define XPOS 0
#define YPOS 1
#define DELTAY 2

#define LOGO16_GLCD_HEIGHT 16
#define LOGO16_GLCD_WIDTH  16
static const unsigned char PROGMEM logo16_glcd_bmp[] =
{ B00000000, B11000000,
  B00000001, B11000000,
  B00000001, B11000000,
  B00000011, B11100000,
  B11110011, B11100000,
  B11111110, B11111000,
  B01111110, B11111111,
  B00110011, B10011111,
  B00011111, B11111100,
  B00001101, B01110000,
  B00011011, B10100000,
  B00111111, B11100000,
  B00111111, B11110000,
  B01111100, B11110000,
  B01110000, B01110000,
  B00000000, B00110000 };

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

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

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

  // Show image buffer on the display hardware.
  // Since the buffer is intialized with an Adafruit splashscreen
  // internally, this will display the splashscreen.
  display.display();
  delay(2000);

  // Clear the buffer.
  display.clearDisplay();

  // draw a single pixel
  display.drawPixel(10, 10, WHITE);
  // Show the display buffer on the hardware.
  // NOTE: You _must_ call display after making any drawing commands
  // to make them visible on the display hardware!
  display.display();
  delay(2000);
  display.clearDisplay();

  // draw many lines
  testdrawline();
  display.display();
  delay(2000);
  display.clearDisplay();

  // draw rectangles
  testdrawrect();
  display.display();
  delay(2000);
  display.clearDisplay();

  // draw multiple rectangles
  testfillrect();
  display.display();
  delay(2000);
  display.clearDisplay();

  // draw mulitple circles
  testdrawcircle();
  display.display();
  delay(2000);
  display.clearDisplay();

  // draw a white circle, 10 pixel radius
  display.fillCircle(display.width()/2, display.height()/2, 10, WHITE);
  display.display();
  delay(2000);
  display.clearDisplay();

  testdrawroundrect();
  delay(2000);
  display.clearDisplay();

  testfillroundrect();
  delay(2000);
  display.clearDisplay();

  testdrawtriangle();
  delay(2000);
  display.clearDisplay();

  testfilltriangle();
  delay(2000);
  display.clearDisplay();

  // draw the first ~12 characters in the font
  testdrawchar();
  display.display();
  delay(2000);
  display.clearDisplay();

  // draw scrolling text
  testscrolltext();
  delay(2000);
  display.clearDisplay();

  // text display tests
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0,0);
  display.println("Hello, world!");
  display.setTextColor(BLACK, WHITE); // 'inverted' text
  display.println(3.141592);
  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.print("0x"); display.println(0xDEADBEEF, HEX);
  display.display();
  delay(2000);

  // miniature bitmap display
  display.clearDisplay();
  display.drawBitmap(30, 16,  logo16_glcd_bmp, 16, 16, 1);
  display.display();

  // invert the display
  display.invertDisplay(true);
  delay(1000);
  display.invertDisplay(false);
  delay(1000);

  // draw a bitmap icon and 'animate' movement
  testdrawbitmap(logo16_glcd_bmp, LOGO16_GLCD_HEIGHT, LOGO16_GLCD_WIDTH);
}

void loop() {

}

void testdrawbitmap(const uint8_t *bitmap, uint8_t w, uint8_t h) {
  uint8_t icons[NUMFLAKES][3];

  // initialize
  for (uint8_t f=0; f< NUMFLAKES; f++) {
    icons[f][XPOS] = random(display.width());
    icons[f][YPOS] = 0;
    icons[f][DELTAY] = random(5) + 1;

    Serial.print("x: ");
    Serial.print(icons[f][XPOS], DEC);
    Serial.print(" y: ");
    Serial.print(icons[f][YPOS], DEC);
    Serial.print(" dy: ");
    Serial.println(icons[f][DELTAY], DEC);
  }

  while (1) {
    // draw each icon
    for (uint8_t f=0; f< NUMFLAKES; f++) {
      display.drawBitmap(icons[f][XPOS], icons[f][YPOS], logo16_glcd_bmp, w, h, WHITE);
    }
    display.display();
    delay(200);

    // then erase it + move it
    for (uint8_t f=0; f< NUMFLAKES; f++) {
      display.drawBitmap(icons[f][XPOS], icons[f][YPOS],  logo16_glcd_bmp, w, h, BLACK);
      // move it
      icons[f][YPOS] += icons[f][DELTAY];
      // if its gone, reinit
      if (icons[f][YPOS] > display.height()) {
    icons[f][XPOS] = random(display.width());
    icons[f][YPOS] = 0;
    icons[f][DELTAY] = random(5) + 1;
      }
    }
   }
}

void testdrawchar(void) {
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0,0);

  for (uint8_t i=0; i < 168; i++) {
    if (i == '\n') continue;
    display.write(i);
    if ((i > 0) && (i % 21 == 0))
      display.println();
  }
  display.display();
}

void testdrawcircle(void) {
  for (int16_t i=0; i<display.height(); i+=2) {
    display.drawCircle(display.width()/2, display.height()/2, i, WHITE);
    display.display();
  }
}

void testfillrect(void) {
  uint8_t color = 1;
  for (int16_t i=0; i<display.height()/2; i+=3) {
    // alternate colors
    display.fillRect(i, i, display.width()-i*2, display.height()-i*2, color%2);
    display.display();
    color++;
  }
}

void testdrawtriangle(void) {
  for (int16_t i=0; i<min(display.width(),display.height())/2; i+=5) {
    display.drawTriangle(display.width()/2, display.height()/2-i,
                     display.width()/2-i, display.height()/2+i,
                     display.width()/2+i, display.height()/2+i, WHITE);
    display.display();
  }
}

void testfilltriangle(void) {
  uint8_t color = WHITE;
  for (int16_t i=min(display.width(),display.height())/2; i>0; i-=5) {
    display.fillTriangle(display.width()/2, display.height()/2-i,
                     display.width()/2-i, display.height()/2+i,
                     display.width()/2+i, display.height()/2+i, WHITE);
    if (color == WHITE) color = BLACK;
    else color = WHITE;
    display.display();
  }
}

void testdrawroundrect(void) {
  for (int16_t i=0; i<display.height()/2-2; i+=2) {
    display.drawRoundRect(i, i, display.width()-2*i, display.height()-2*i, display.height()/4, WHITE);
    display.display();
  }
}

void testfillroundrect(void) {
  uint8_t color = WHITE;
  for (int16_t i=0; i<display.height()/2-2; i+=2) {
    display.fillRoundRect(i, i, display.width()-2*i, display.height()-2*i, display.height()/4, color);
    if (color == WHITE) color = BLACK;
    else color = WHITE;
    display.display();
  }
}

void testdrawrect(void) {
  for (int16_t i=0; i<display.height()/2; i+=2) {
    display.drawRect(i, i, display.width()-2*i, display.height()-2*i, WHITE);
    display.display();
  }
}

void testdrawline() {
  for (int16_t i=0; i<display.width(); i+=4) {
    display.drawLine(0, 0, i, display.height()-1, WHITE);
    display.display();
  }
  for (int16_t i=0; i<display.height(); i+=4) {
    display.drawLine(0, 0, display.width()-1, i, WHITE);
    display.display();
  }
  delay(250);

  display.clearDisplay();
  for (int16_t i=0; i<display.width(); i+=4) {
    display.drawLine(0, display.height()-1, i, 0, WHITE);
    display.display();
  }
  for (int16_t i=display.height()-1; i>=0; i-=4) {
    display.drawLine(0, display.height()-1, display.width()-1, i, WHITE);
    display.display();
  }
  delay(250);

  display.clearDisplay();
  for (int16_t i=display.width()-1; i>=0; i-=4) {
    display.drawLine(display.width()-1, display.height()-1, i, 0, WHITE);
    display.display();
  }
  for (int16_t i=display.height()-1; i>=0; i-=4) {
    display.drawLine(display.width()-1, display.height()-1, 0, i, WHITE);
    display.display();
  }
  delay(250);

  display.clearDisplay();
  for (int16_t i=0; i<display.height(); i+=4) {
    display.drawLine(display.width()-1, 0, 0, i, WHITE);
    display.display();
  }
  for (int16_t i=0; i<display.width(); i+=4) {
    display.drawLine(display.width()-1, 0, i, display.height()-1, WHITE);
    display.display();
  }
  delay(250);
}

void testscrolltext(void) {
  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.setCursor(10,0);
  display.clearDisplay();
  display.println("scroll");
  display.display();

  display.startscrollright(0x00, 0x0F);
  delay(2000);
  display.stopscroll();
  delay(1000);
  display.startscrollleft(0x00, 0x0F);
  delay(2000);
  display.stopscroll();
  delay(1000);
  display.startscrolldiagright(0x00, 0x07);
  delay(2000);
  display.startscrolldiagleft(0x00, 0x07);
  delay(2000);
  display.stopscroll();
}

```

# Answer
Check the connections with that required by the software/library. If you intend to use SPI the pins on Arduino Uno are:

```
SS   10
MOSI 11
MISO 12
SCK  13

```

You connections above are:

```
VCC             => 5V
D0(OLED_CLK)    => 10 (SPI SS ??)
D(OLED_MOSI)    => 9
RES(OLED_RESET) => 13 (SPI SCK ??)
D/C(OLED_DC)    => 11 (SPI MOSI ??)
CS（OLED_CS）     => 12 (SPI MISO ??)
GND             => GND (??)

```

That is not correct for SPI. Post link to library, oled hardware, and snippet of your code for more help.

It is more than the video that is out of focus :)

Cheers!
> 0 votes

---
Tags: arduino-uno, spi
---


# Question
Title: Can anyone tell me about the onboard accelerometer of LightBlue Bean?
I would like to know the specs of the accelerometer used on a LightBlue Bean before buying one, but I couldn't find any info online. Anybody has an idea?

# Answer
> 1 votes
There is a reference to the accelerometer datasheet from the Arduino Reference page

# Answer
> 0 votes
> I would like to know the specs of the accelerometer used on a LightBlue Bean before buying one, but I couldn't find any info online. Anybody has an idea?

Start by checking the Adafruit LightBlue Bean product description. There you can find a link to the schematics and board layout. On page two there is accelerometer, a BMA250 just as @Jason links to.

That took "30 seconds" web search plus writing this answer :)

Cheers!

---
Tags: accelerometer
---


# Question
Title: RC drag strip finish line with mph calculation (using 1" spaced lasers)
My question is: how do I read multiple inputs at the same time without using interrupts on an UNO. I'm building an RC drag strip with tree and finish line that will calculate run time as well as calculate each run in mph. I'm using lasers and non modulated laser detectors for the beams and I'm using a 1" beam gap(between 1st beam and 2nd beam) at the finish line(for mph calculation). My concern comes in when two cars come close enough at the finish line for one to break the first beam at set the win flag but the car in the other lane is close enough to cross the 1st beam before the 1st car actually crosses the 2nd beam then the detection loop is going to miss one of them. (just a note: a few of these cars can top 100 mph when crossing the line)

# Answer
> 2 votes
**ONE:**

What you can do is use a while loop waiting for the first pulse and then wait until the last pulse, for an idea look at this code fromGadjet, he made a chronograph with a similar operation, you would just need to adapt the design, this might not be as accurate for an 1". Also it will be the issue of having ties between cars. This is short as I don't like this option.

**TWO:**

Another option, although using what you don't want to use, would be using the interrupts on the Arduino. *I am basing the following on the fact that you are using two cars.*

What you can do is have a `finish line` for *both vehicles* and detect a break with a interrupt, one interrupt pin per lane(UNO has to interrupts).

The trick here is that you place both the outputs from one lane onto a single interrupt pin with a edge detector type of circuit1 to generate a pulse while the vehicle crosses a point, especially important as it will be in the inch area for a while. The code handles the double pulse on one pin. I know this works as I used this on a ballistic chronograph which works in microseconds detecting shots \>2000fps over a 0.406 foot distance.

1 This is an example of the circuit you would use at the output of each sensor before the OR gates:

The hardware would just become a duplicate for each lane, and to combine the input on one pin you can use an OR gate IC or you can use diode OR gate:

Interrupts are actually easy to use with Arduinos, and there are a lot of examples out there.

Have a look at the below flow chart to get an idea of operation in the code:

A small thing would be that the code ignores a interrupt once the cars have passed so it doesn't calculate a second time.

# Answer
> 2 votes
Building upon Nick Gammon's excellent answer at How many interrupt pins can an Uno handle? here's some untested code:

```
 const int events = 256; // events to store
 unsigned volatile int index;
 byte pinStates[events];
 unsigned int times[events];

 ISR (PCINT1_vect) //  Watch for pin changes on the C port (Uno pins A0-A5)
 {
   if (index == 0) { // start clock
    TCCR1B = bit(CS12) | bit (CS10) ;    // clock/1024 for <4.19s x 64us
    //TCCR1B = bit(CS12);                // clock/256  for <1.05s x 16us
    //TCCR1B = bit(CS11) | bit (CS10) ;  // clock/64   for <0.25s x 4us
    //TCCR1B = bit(CS11) ;               // clock/8    for <0.03s x 0.5us
    //TCCR1B = bit(CS10) ;               // clock/1    for <0.004s x 62ns
   }
   times[index] = TCNT1;
   pinStates[index] = PORTC;
   index = (index+1) & 0xff; // increment and protect from overflow

 }  // end of PCINT1_vect

void setup ()
  {
  // activate pin change interrupts on port C / pins A0-A5

  PCICR   =  bit (PCIE1);    // enable PCINT[14:8] pin triggers
  PCMSK1 |=  bit (PCINT8) |
             bit (PCINT9) |
             bit (PCINT10) |
             bit (PCINT11) |
             bit (PCINT12) |
             bit (PCINT13);     // enable individual pins

  // stop and clear 16 bit timer  CS1[0-2]=0; TCNT1 = 0;
  TCCR1A = 0;  // no comparisons, normal WGM mode, stop the counting
  TCCR1B = 0;
  TCNT1  = 0;  // Clear the counter

  pinMode (A0, INPUT_PULLUP);
  pinMode (A1, INPUT_PULLUP);
  pinMode (A2, INPUT_PULLUP);
  pinMode (A3, INPUT_PULLUP);
  pinMode (A4, INPUT_PULLUP);
  pinMode (A5, INPUT_PULLUP);

  index = 0 ; // nothing happened yet

  pinMode (5, OUTPUT);
  }  // end of setup

void loop ()
  {

   // check index, parse and report times, check for arming, etc...

  }

```

The point is to use the pin change interrupt to record state changes on the pins and the times. The clock/1024 prescaler would give a 1/16MhZ\*1024\*65536= 4.19s window at 64us resolution timing counts, but you could go to higher resolution with a tighter window by using a smaller prescaler.

Also, if you wanted longer timing windows, you could cascade timer1 into timer0 (messing up millis(), etc.,) and get 24 bits of range before overflow, but a better way than cascading timers might be to add another interrupt to increment a variable. For much longer timing windows add another quick interrupt to handle for timer1 overflow.

```
...
volatile unsigned long int t1Cycles,times[events];
...

ISR(TIMER1_OVF_vect){t1Cycles++;}

void setup(){
    ...
    TIMSK1 = bit(TOIE1);
    t1Cycles = 0;
    ...
}

ISR (PCINT1_vect)
{
    ...
    times[index] = t1Cycles << 16 | TCNT1; // store 32 bit count of clocks
    ...
}

```

This is still untested, but it looks like it could be capable of 268 seconds worth of 62ns resolution multichannel timing. With the longer period, you could move the conditional clock-starting code out of the pin-change ISR.

# Answer
> 0 votes
One option, if you want very-real-time processing, for a task like this that break neatly into chunks: Have one Arduino per vehicle.

Arduinos are cheap. If they are too expensive, use AtTiny's - they can be had for about a dollar a piece (depending on your currency). You can share a clock/power between a large number of them.

You can either have a "master" Arduino talk to each individual one, to collect the information, or have daisy-chained bus - each one can pass it's data to the next one in the chain (once is has the data, and the next one in the chain indicates it's ready for it).

---
Tags: arduino-uno, c++, timers
---


title: millis() not working properly

text:
# Question
Title: millis() not working properly
I'm doing a little project that, on a press of a button, will light up three LEDs and then will turn off the LEDs in different times. I'm using the `millis()` function to control the time that each LED will be on.

On the first time that I press the button, everything works fine. But the problem starts when I press the button for the second time.

If I press the button soon after the loop ends, something goes wrong and the behavior of the LED become a mess (just one or two LEDs light up in weird times). But, if I wait about 2 seconds before pressing the button for the second time, everything goes right.

Here's my code:

```
const int ledPin1 =  11;
  const int ledPin2 =  12;
  const int ledPin3 =  13;
  const int buttonPin = 2;

  int buttonState = 0;
  long previousMillis1 = 0;
  long previousMillis2 = 0;
  long previousMillis3 = 0;

  int state = 0;

  void setup()
  {
    pinMode(ledPin1, OUTPUT);
    pinMode(ledPin2, OUTPUT);
    pinMode(ledPin3, OUTPUT);
    pinMode(buttonPin, INPUT);

    Serial.begin(9600);
  }

  void loop()
  {

       buttonState = digitalRead(buttonPin);

       if (buttonState == HIGH) {
        state = 1;
       }

       if (state == 1)
       {
        taskExecute(3000, 2000, 4000);
       }
  }

  void taskExecute(int tMotor1, int tMotor2, int tMotor3)
  {

    int ledState1 = HIGH;
    int ledState2 = HIGH;
    int ledState3 = HIGH;

    digitalWrite(ledPin1, ledState1);
    digitalWrite(ledPin2, ledState2);
    digitalWrite(ledPin3, ledState3);

    do
    {
      unsigned long currentMillis = millis();

      if(currentMillis - previousMillis1 > tMotor1)
      {
        previousMillis1 = currentMillis;

        if (ledState1 == HIGH)
          ledState1 = LOW;

        digitalWrite(ledPin1, ledState1);
      }

      if(currentMillis - previousMillis2 > tMotor2)
      {
        previousMillis2 = currentMillis;

        if (ledState2 == HIGH)
          ledState2 = LOW;

        digitalWrite(ledPin2, ledState2);
      }

      if(currentMillis - previousMillis3 > tMotor3)
      {
        previousMillis3 = currentMillis;

        if (ledState3 == HIGH)
          ledState3 = LOW;

        digitalWrite(ledPin3, ledState3);
      }
    } while (ledState1 == HIGH || ledState2 == HIGH || ledState3 == HIGH);
    state = 0;
  }

```

Other strange thing that happens is that sometimes the time that i've been set in millis for the led get on become a little different. Example: when I press the button, the LED 1 needs to light up for 3 seconds, but he lights up just 2.5 seconds.

What i'm doing wrong? Thanks!!

# Answer
> 1 votes
The variables `previousMillis` (1-3) are not properly initialised. So if you wait a while before pressing the button, that delay time becomes part of the time that the LED is illuminated for.

If your `taskExecute()` function sets them before the loop, this will fix that:

```
void taskExecute(int tMotor1, int tMotor2, int tMotor3)
{
    int ledState1 = HIGH;
    int ledState2 = HIGH;
    int ledState3 = HIGH;

    digitalWrite(ledPin1, ledState1);
    digitalWrite(ledPin2, ledState2);
    digitalWrite(ledPin3, ledState3);

    unsigned long time_now = millis();
    previousMillis1 = time_now;
    previousMillis2 = time_now;
    previousMillis3 = time_now;

    do
    {
        ...
    } while (ledState1 == HIGH || ledState2 == HIGH || ledState3 == HIGH);
    state = 0;
}

```

On a coding-style note - I did not initially see the resetting of the global variable `state=0` at the end of the `taskExecute()` function. It might be better to move this up to underneath the initial call to `taskExecute()` so all the `state` handling is in one place.

---
Tags: millis
---


# Question
Title: Arduino on breadboard Tension is 4.4V instead of 5 V,looking for some guidance
I build a circuit that work on breadboard now i try to prototype it,so i start solder it on a prototype board and the arduino is out of sync.So i check the tension and for some reason it's 4.4~4.6 on the Vin pin of Atmega328 so i try to find how to debug.I don't have a lot of theorical knowledge on electronic,but my thougt was as long as everything is plug in parrallel the tension should remain the same ( and i don't have any thing in serie) so for the tension to drop i may have something acting as Resistor, and i try to find how and what. I use 22AWG 0.7mm wire o create a 5V line and my GND line on each side of the Atmega ( roughly 7 cm on each side),i start to wondering if it was not a bad idea. I have picture of my prototype bellow,but it's messy so not sure it help. My question is how to you proceed to troubleshoot this thing ? What are the step you do to find out where is the problem

# Answer
The yellow-boxed 5V and Gnd buses on the freetronics.com.au ProtoShield Basic for Arduino \[like you used\] already have copper strips connecting the holes. The strips run on both sides of the board and the holes are plated-through, so there's no need (for this kind of circuit) to have additional bus wire running along above the boxes. Having that extra wire there gets in the way of making changes, whether for debugging the circuit or for adding or replacing components.

From the frontside picture, it appears you may have a voltage regulator on board. (However, I don't see the connections to 5V and Gnd, so might be misinterpreting things.)

If your board input is 5 VDC from an external supply, feeding that 5 V into a regulator will lose half a volt or so, which may account for what you are seeing.

However, let's instead suppose you are putting 7 to 12 VDC into an on-board 5V regulator and then measuring 4.4-4.6 V out. One possibility is the regulator isn't working. This can happen if the regulator's input or output capacitors are the wrong sizes or wrong kinds, and cause oscillation. Diagnosing that kind of problem is straightforward if you look at the 5V line with an oscilloscope. Another possibility is something drawing a *lot* of current (eg a couple of amps) and taking the 5V line out of regulation. That's usually easy to diagnose because of all the resulting smoke and heat.

Drawing a good schematic is an excellent step to take to allow better problem debugging.

Other steps to take:

* Measure the amount of current the whole board is drawing, or that the NRF24L01 is drawing. (For the latter measurement, you might need to lift your ground lead off the NRF24L01 board and put the ammeter into the ground circuit. In general you want all the grounds to be at the same voltage, so the voltage drop across the ammeter is a problem, but not much of one.)
* Pull the '328P chip and see if that makes any difference. In general, it's a good idea to work out a prototype board's power supply problems – such as shorts, reversed electrolytics, incorrect resistors – in advance of installing a microcontroller chip onto the board.
* Remove the NRF24L01, if feasible, while debugging the power supply. If you can't easily remove it, check your schematic and see if all of its pins except 5V and Gnd are open when the '328P chip is pulled. If so, you can detach the NRF24L01 ground lead to take it out of the circuit. If, during testing, you unsolder and remove the NRF24L01 board, consider making a socket for it from two 5-pin female header strips.
> 0 votes

---
Tags: arduino-uno, atmega328, electronics, prototype
---


title: How to use ITG-3500 evb

text:
# Question
Title: How to use ITG-3500 evb
I am trying to make motion capture and someone gave me these boards.

I think it's a test board for MPU 9500. I tried to google but I only found datasheets. What boards are these?

"ITG-3500 evb" is written on the back of the green board.
I think this is datasheet of green board maybe

"EV\_ARM\_XXAXA\_D" is written on the back of the blue board.

# Answer
> 0 votes
I have had to, briefly, play with these boards a while back, and although I used different revisions and versions of the boards, they are probably the same functionally. Unfortunately, I don't have any of my old notes as I have moved country. Regardless...

As Majenko says in his answer the green board is an evaluation board for the ITG-3500 3-axis gyroscope, which is presumably the SMD chip (in a QFN format) mounted on it, in the lower part of the board (looking at your photo). A data sheet on the *similar* ITG-3200 (note *not* the evaluation board itself) can be found on SparkFun. To quote part of the product description:

> The ITG-3200 is the world’s first single-chip, digital-output, 3-axis MEMS gyro IC optimized for gaming, 3D mice, and 3D remote control applications. The part features enhanced bias and sensitivity temperature stability, reducing the need for user calibration. Low frequency noise is lower than previous generation devices, simplifying application development and making for more-responsive remote controls.
>
> The ITG-3200 features three 16-bit analog-to-digital converters (ADCs) for digitizing the gyro outputs, a user-selectable internal low-pass filter bandwidth, and a Fast-Mode I2C (400kHz) interface. Additional features include an embedded temperature sensor and a 2% accurate internal oscillator. This breakthrough in gyroscope technology provides a dramatic 67% package size reduction, delivers a 50% power reduction, and has inherent cost advantages compared to competing multi-chip gyro solutions.

In addition, in case it is of any use, here is the datasheet for the, again similar, ITG-3701, which I located on the Digi sales site. Frustratingly, I am unable to locate a datasheet for the ITG-3500 - however, you mentioned that you found some datasheets - could you edit your answer to include the links, please?

The Blue board is a "Gyroscope Evaluation Board: EV\_INV-ARM" manufactured by InvenSense Inc., and to quote its product description:

> The InvenSense ARM reference board provides a bridge function between InvenSense evaluation boards and a PC. It connects to a PC via USB and to InvenSense evaluation boards via SPI or I2C. The ARM processor on the reference board is not meant to be reprogrammed by the user. It contains all code necessary to be used in conjunction InvenSense evaluation boards. (Note that separate demonstration software may accompany the individual evaluation boards with which this device connects.)

Here is a link to the EV\_INV-ARM DataSheet. The Atmel chip on it is possibly the AT91SAM7SE512 MCU, and here is a link to its product specification.

Software wise, you may find this Linux kernel driver for the ITG-3500 extremely useful.

---

### TL;DR

It seems like you need to get hold of the separate demonstration software for the ITG-3500 evaluation board, according to the EV-INV\_ARM's product description, in order to *easily* make it do something.

# Answer
> 1 votes
The green board is an ITG-3500 (3 axis gyroscope) evaluation board of some form.

The blue board is some form of microcontroller evaluation board. It probably has one of the Atmel SAM chips on it since it mentions ARM.

That's about all you'll get from us I'm afraid, unless there is the highly unlikely situation that someone here happens to have the exact same boards as you.

---
Tags: sensors
---


title: Connect function generator to Arduino

text:
# Question
Title: Connect function generator to Arduino
How do I connect a function generator that generates an analog signal to an Arduino Uno?

I don't know how to begin, so could you also tell me the settings for the function generator, e.g. its amplitude, frequency, etc, that won't damage my Arduino?

I plan to visualize the output on Processing.

(source: sonoma.edu)

# Answer
## Confirm with an oscilloscope

When I connect my function generator I ~~usually~~ always make sure that the output is in the range 0 to 5V, with my oscilloscope. The default is probably more like ±2.5V - but I don't have an Agilent so you would have to check. Press the `Ampl` button to check. (Mine reads 5VPP).

You can see from the above image that we indeed have (roughly) 5VPP \- and that there is a -2.56V component, which will damage the Arduino, being negative.

---

## Add an offset

So press the `Offset` button and add a 2.5V DC offset. Now the voltage jumps 2.5V and is between 0 and 5V:

The scope confirms that the minimum is 80mV and the maximum is 4.96V, which is in range for an Arduino pin (assuming you are running an Arduino at 5V, which is not always the case).

Now you should be safe to experiment with different frequencies and wave-forms. Just leave the Amplitude and Offset alone. :)

---

## Extra precautions

You could feed the function generator through an input protection circuit, just in case you absent mindedly forget to carry out the appropriate steps.

The zener diode will conduct negative voltages to ground (dissipated through the 1k resistor) and will also limit positive voltages to around 5.1V.
> 3 votes

# Answer
> I don't know how to begin, so could you also tell me the settings for the function generator, e.g. its amplitude, frequency, etc, that won't damage my Arduino?

That is not an Arduino question. That is a question about how to operate the function generator. Please check the users manual. You need to set the voltage output (DC + AC) so that it matches the Arduino.

An analog signal should go to an analog pin on the Arduino (not pin 8). It is also important to connect GND.

Cheers!
> 1 votes

# Answer
Looking at the Agilent 33220A 20 MHz Waveform Generator User's Guide, I can see that the Function Generator has a USB port. If you have, or can get hold of, a USB *Host* shield for the Arduino, you should be able to link the two together physically. Then, using the USB Host Library for Arduino, you could get the two talking to each other.

Alternatively, if you fancy a bit more hard work, then you could get a MAX3421E, and wired it up yourself as an interface, but I wouldn't recommended it.

Note: If you have an Arduino Due (I know that you say that you have an Uno, but just in case) then you could use the USBHost library to connect the two directly, without the need for a USB Host shield.

Regarding, getting the two to talk together, that may not be exactly easy. From the manual I can see that the PC software can auto-configure the function generator, however, for receiving data it may not be so easy. You appear to have to send a **GTL** command to get the data sent to the USB (p251, and onwards, of the manual). Good Luck! :-)
> 0 votes

---
Tags: arduino-uno, signal-processing
---


# Question
Title: How to change Multiple variable values through Serial Monitor
I am trying ... with minimal success to change/Check and also run voids through the serial monitor .the code i put i am having probles is that when i am try to send a value larger than 9 the value assigns a diffrent number Ex i set to 200 but arduino sets it as 512.. i got around it deviding the value by 1.6 and got me the new number and only works upto 90 , but i am tryn to see how it should be done correctly...

```
const uint16_t inputLength = 512;
int ss = 0;
int bHold = 0;

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

 void loop() {
  if ( Serial.available() > 0 )
  {
    static char input[inputLength];
    static uint16_t i;
    char c = Serial.read();

    if ( c != '\r' && c != '\n' && i < inputLength - 1)
      input[i++] = c;

    else
    {
      input[i] = '\0';
      i = 0;

      uint16_t array[80];
      uint16_t j = 0;

      if ( !strncmp(input, "ss", 2) )
      {
        char* p = input + 2;
        while ( (p = strchr(p, ' ')) != NULL )
          array[j++] = strtol(p, &p, 10); //< changed from 16

        for ( uint8_t i = 0; i < j; i++ )
        {
          ss = array[i];
          Serial.println(ss);
        }
      }

      if ( !strncmp(input, "bHold", 5) )
      {
        char* p = input + 5;
        while ( (p = strchr(p, ' ')) != NULL )
          array[j++] = strtol(p, &p, 10);   //< changed from 16

        for ( uint8_t i = 0; i < j; i++ )
        {
         bHold = array[i];
        // bHold=bHold /1.6;
         Serial.println(bHold);
        }
      }

      if ( !strncmp(input, "Whos There", 10) )
      {
        Serial.print("me");
      }
      if ( !strncmp(input, "hello", 5) )
      {
        Serial.print("hi");
      }
      if ( !strncmp(input, "sa", 2) )
      {
        Serial.print("  ss= ");
        Serial.print(ss);

        Serial.print("  bHold= ");
        Serial.print(bHold);

        Serial.println(" ");
        Serial.println("==============================");
      }
    }
  }
}

```

Thank you for any tips you can give...

EDIT: I am trying to pass a new value with command on the serial monitor "ss 500"..so that in the arsuino ss = 500. but in this case it makes it equal to 1280.

EDIT2: Chaged the strol to 10...works perfectly ...Thank you TisteAndii!!!!

# Answer
You are setting the input string's base to 16 instead of 10 in your `strtol` conversions, which is why you are getting 1280 when you expect 500.
> 0 votes

---
Tags: serial, variables
---


# Question
Title: For loop question-Simulating a robot' s movement on a 2d array
i' m trying to simulate a robot' s movement on a 2d array. In my case, robot goes forward firstly, if it sees a engel, it turns left and continues its movement. The problem is that, i could not present turning left and moving on left-direction on the initial matrix.

Here' s my code:

```
#include <Servo.h>
#define x 7                                         //Matrix dimensions
#define y 7

const int trigPin = 12;
const int echoPin = 11;

Servo myServo;                                     //variable definations
Servo myServo2;

int pos = 0;

int counter;
int counter1 = 0;
int counter2;
int counter3;

int integer;
int integer2;
int integer4;

long duration;
long distance;

void setup() {
    Serial.begin(9600);
    myServo.attach(9);
    myServo2.attach(10);
    pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
    pinMode(echoPin, INPUT); // Sets the echoPin as an Input
}

void loop() {
    int my2dArray[x][y] = {                          // initial matrix
        {1, 1, 1, 1, 1, 1, 1},
        {1, 1, 1, 1, 1, 1, 1},
        {1, 1, 1, 1, 1, 1, 1},
        {1, 1, 1, 0, 1, 1, 1},
        {1, 1, 1, 1, 1, 1, 1},
        {1, 1, 1, 1, 1, 1, 1},
        {1, 1, 1, 1, 1, 1, 1},
    };
    // Clears the trigPin
    digitalWrite(trigPin, LOW);
    delayMicroseconds(2);
// Sets the trigPin on HIGH state for 10 micro seconds
    digitalWrite(trigPin, HIGH);
    delayMicroseconds(10);
    digitalWrite(trigPin, LOW);
// Reads the echoPin, returns the sound wave travel time in microseconds
    duration = pulseIn(echoPin, HIGH);
// Calculating the distance
    distance = duration * 0.034 / 2;
    int robot = my2dArray[3][3];                   // first place of robot

    if (counter1 > 0) {
        for (integer = 0;  integer < counter1; integer += 1) {
            if (distance < 10) {                                  //seeing     the object
                for (pos = 0; pos <= 180 ; pos += 1) {              //turning left
                    myServo.write(pos);
                }

                for (pos = 0; pos <= 180  ; pos += 1) {            //moving on after turning
                    myServo.write(pos);
                    myServo2.write(pos);

                    if (pos == 180) {
                        counter3 +=  1;
                    }
                }

                Serial.println(integer);

                for (integer4 = 0;  integer4 < counter3; integer4 += 1) {     //modifying matrix if there is an object
                    my2dArray[3 + integer][3 + integer4] = robot * my2dArray[3 + integer][3 + integer4];
                }

                Serial.println("Break condition.");
                break;
            } else {
                my2dArray[3 + integer][3] = robot * my2dArray[3 + integer][3];    //modifying matrix in case of there is no object
            }
        }
    }

    for (integer2 = 0; integer2 < 7; integer2++) {                          //displaying matrix
        Serial.print(my2dArray[integer2][0]);
        Serial.print("|");
        Serial.print(my2dArray[integer2][1]);
        Serial.print("|");
        Serial.print(my2dArray[integer2][2]);
        Serial.print("|");
        Serial.print(my2dArray[integer2][3]);
        Serial.print("|");
        Serial.print(my2dArray[integer2][4]);
        Serial.print("|");
        Serial.print(my2dArray[integer2][5]);
        Serial.print("|");
        Serial.println(my2dArray[integer2][6]);
    }

    Serial.println();

    for (pos = 0; pos <= 180  ; pos += 1) {                               // moving forward as first movement
        myServo.write(pos);
        myServo2.write(pos);

        if (pos == 180) {
            counter1 +=  1;
        }
    }

    delay(1000);
}

```

The problem part is:

```
for (integer4 = 0;  integer4 < counter3; integer4 += 1){      //modifying matrix if there is an object

    my2dArray[3 + integer][3+integer4] = robot * my2dArray[3 + integer][3+integer4];

     }

```

"integer" value does not change in the problem part, it' s always 0 in despite of the first for loop. How can i pass the "integer" to the problem part properly?

# Answer
> 0 votes
Your program is hard to follow with all those meaningless "integer" and "counter" variables, and the logic seems a little odd in places, but I believe the cause of your problems is the `break` statement:

```
for (integer = 0; integer < counter1; integer += 1) {
    if (distance < 10) {
        // ...
        for (integer4 = 0;  integer4 < counter3; integer4 += 1) {     //modifying matrix if there is an object
            my2dArray[3 + integer][3 + integer4] = robot * my2dArray[3 + integer][3 + integer4];
        }
        break; // << HERE
    } else {
        // ...
    }
}

```

What is the purpose of that `break`? I think you are using it to jump out of the `if` so that it doesn't run the `else`, which it *won't run anyway since it's an else condition*. Instead, what the `break` is actually doing is terminating the `for` loop after the first iteration that hits that inner `if` condition. That is, as long as the distance is less than 10 it will only ever run the `for` once, and so `integer` will only ever be 0.

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


# Question
Title: How to get the MAC address of an Ethernet shield, if it is not printed on it?
Help me to find out how to connect an Ethernet shield over the internet using a LAN cable. I have tried many times but I'm not getting a MAC and IP address.

# Answer
If you do not have a MAC address then you have to make one up. There are a couple of rules and regulations about what a MAC address can be, but most of the time you can just make one up:

1. It must be unique on *your* network
2. There are a set of prefixes that are reserved for special purposes:
    * The lowest bit of the first byte must be 0
    * The second bit of the first byte must be 1

You can read more about it here: https://en.wikipedia.org/wiki/MAC\_address

Once you have provided a MAC address and physically connected it to the network then you need an IP address and netmask. There are two ways you can get the IP address and netmask:

1. Through DHCP - For example your home internet router would provide the IP address for you.
2. By allocating your own. This must be within the range of your network's IP addresses, typically something like 192.168.0.x where x is between 1 and 255. The IP address must be unique on your network.

The netmask, again, can be given by DHCP, otherwise you will have to enter the netmask of your network, typically 255.255.255.0

Then to access the internet itself you need to provide (or be provided with through DHCP) the address of the internet gateway and possibly a DNS server address. On a home network they are typically the address of the router, which may well be 192.168.0.1 or something similar.
> 1 votes

---
Tags: arduino-uno
---


# Question
Title: Addressing EACH of the 3x3x3 LEDs separately
I read a few 3x3x3 LED tutorials, e.g. let us take this one:

http://www.instructables.com/id/Making-an-Arduino-3X3-LED-Cube-in-Less-Than-30-Min/?ALLSTEPS

As far as I understand, you can address any of the 3x3 *light columns*:

```
*  *  *       1  2  3
*  *  *       4  5  6
*  *  *       7  8  9

```

and each of the three vertical layers:

```
top
middle
bottom

```

But can I address each of the 27 leds separately? In other words, can I light up:

```
1+  2   3         bottom layer
4   5+  6
7   8   9

1   2+  3         middle layer
4+  5   6
7   8   9

```

# Answer
3 * 3 * 3 = 27

**The easy/overkill way**

You could do this by assigning a pin to every LED (on an arduino Mega)

**The overkill way**

Use shift registers, almost any arduino will do. The shift register will set it's outputs according to the amount of high/low signals being clocked in. In theory, you can address an infinite amount of LED's (only limited by space, time or funds).

**Breaking it down**

You can break it down, so that you control each layer at once. Effectively you only drive 9 LED's (1 layer). And attach a transistor to the negative side of the layer. This way you can choose a LED with the positive side, and a layer with the negative (per layer) control.

Switching these layers rapidly, will make the changes invisible to the eye. So it seems that the LED's are on all the time.

**To infinity**

Combine the overkill way (shift registers) with breaking it down (to reduce cost/size) and you'll be able to create a (somewhat) scalable design.

There are an awfull lot of tutorials, I suggest you choose one you can understand, try to make a smaller cube, and scale up from there!

***Scaling issues***

* You'll need a better powersupply for each series of LED's you add.
* Costs.
* Processing time, the arduino might not be able to clock the signals fast enough, making it visible for eyes. (depends on the amount of LED's)

Be sure to check/measure/calculate these things along the project.
> 2 votes

# Answer
No, the three transistors are there to select the layer you want to control. At every moment only ONE layer can be on. But if you switch through controlling these layers fast enough, you can create the illusion of having multiple leds on even across layers. THis is because the human eyes are just not capable of seeing lights flashing at a high rate.

TL;DR No you can't address them individually, but you can create the illusion that you can.
> 4 votes

---
Tags: programming, led
---


title: Maxbotixs LV-EZ4 analog read question

text:
# Question
Title: Maxbotixs LV-EZ4 analog read question
I am using an external 5 volt power supply to power my Sonar, and I am using a Teensy 3.1 to read in analog signal from the sonar. my question is since the teensy is only 3.3v tolerant with analog in, is it safe to use with the maxbotix sonar?

# Answer
> 0 votes
*Converted Gerben's comment to an answer*

---

That is not safe. Maximum voltage on the analog pins is 3.3v, according to the datasheet. But why don't you power it from 3.3v? Minimal voltage for that unit is 2.5v. And it uses only 2mA.

---
Tags: teensy
---


# Question
Title: Get the uploaded code from arduino by using arduino IDE 1.0.6
Recently bought a arduino device which already have program,

it is model AR-293D and I have already connect it with my PC(windows 7) through usb

when I open the IDE , It seems there is no function that read the uploaded program?

And after searching a while , like some beginner tutorial , it only tell you how to upload the program but not how to get the uploadded program

http://www.forefront.io/a/beginners-guide-to-arduino

So, I wonder how to get the code? Thanks a lot for helping, I worried erase the uploadded program so I need to take caution about this

# Answer
You can download the **hex machine code** from the Arduino by using an ISP programmer, like this one:

A command like this could be used to read the flash memory and save it into `myfile.hex`:

```
avrdude -c avrisp -p m328p -U flash:r:myfile.hex:i

```

However be warned that this file will look like this:

```
:100000000C945C000C946E000C946E000C946E00CA
:100010000C946E000C946E000C946E000C946E00A8
:100020000C946E000C946E000C946E000C946E0098
:100030000C946E000C946E000C946E000C946E0088
:100040000C9488000C946E000C946E000C946E005E
:100050000C946E000C946E000C946E000C946E0068
:100060000C946E000C946E00000000080002010069
:100070000003040700000000000000000102040863
:100080001020408001020408102001020408102002
:10009000040404040404040402020202020203032E
:1000A0000303030300000000250028002B000000CC
:1000B0000000240027002A0011241FBECFEFD8E043
:1000C000DEBFCDBF21E0A0E0B1E001C01D92A930AC
:1000D000B207E1F70E94F1010C9401020C940000B8

```

As you can see, you haven't really got "the program" back.

---

As Mikael Patel points out, you can at least turn it into assembler by doing this:

```
avr-objdump -j .sec1 -d -m avr5 myfile.hex

```

However the output is still not C code like you see in the IDE:

```
  d4:   0e 94 f1 01     call    0x3e2   ;  0x3e2
  d8:   0c 94 01 02     jmp 0x402   ;  0x402
  dc:   0c 94 00 00     jmp 0   ;  0x0
  e0:   61 e0           ldi r22, 0x01   ; 1
  e2:   8d e0           ldi r24, 0x0D   ; 13
  e4:   0c 94 81 01     jmp 0x302   ;  0x302
  e8:   61 e0           ldi r22, 0x01   ; 1
  ea:   8d e0           ldi r24, 0x0D   ; 13
  ec:   0e 94 ba 01     call    0x374   ;  0x374
  f0:   68 ee           ldi r22, 0xE8   ; 232
  f2:   73 e0           ldi r23, 0x03   ; 3
  f4:   80 e0           ldi r24, 0x00   ; 0
  f6:   90 e0           ldi r25, 0x00   ; 0
  f8:   0e 94 f5 00     call    0x1ea   ;  0x1ea
  fc:   60 e0           ldi r22, 0x00   ; 0
  fe:   8d e0           ldi r24, 0x0D   ; 13
 100:   0e 94 ba 01     call    0x374   ;  0x374
 104:   68 ee           ldi r22, 0xE8   ; 232
 106:   73 e0           ldi r23, 0x03   ; 3
 108:   80 e0           ldi r24, 0x00   ; 0
 10a:   90 e0           ldi r25, 0x00   ; 0
 10c:   0c 94 f5 00     jmp 0x1ea   ;  0x1ea

```

Unless you are an assembler expert, making sense of that would be pretty hard, and the time taken to do it would be better spent simply rewriting the code from scratch.
> 3 votes

---
Tags: programming, programmer
---


title: Why is there a clock in my arduino?

text:
# Question
Title: Why is there a clock in my arduino?
Of course I know it is usefull to control the time of a delay, but any other use?

With a 16Mhz clock, each line of my program will take 1/16000000 second, right?

even a very very big line will only take 1/16000000 of a second ?

With a 8MHz clock, each line will take the double of the time, right? So the whole "main loop" will take the double time too, right?

# Answer
> Why is there a clock in my arduino?

Because that is how computers and microcontrollers, etc, work.

> With a 16mhz clock, each line of my program will take 1/16000000 second, right?

No.

> even a very very big line will only take 1/16000000 of a second ?

No.

The clock defines at what speed the *machine code instructions* are fetched from memory and executed. Most instructions take 1 clock cycle, but some take more.

One line of C code may be compiled into any number of assembly instructions, which then get converted into machine code (raw numbers). That could be anywhere from 1 assembly instruction to thousands of assembly instructions, depending on what the line does.

> With a 8mhz clock, each line will take the double of the time, right? So the whole "main loop" will take the double time too, right?

Every operation in the chip is governed by the clock. If the clock is half the speed the chip is running at half the speed, so every operation will take twice as long, yes.
> 13 votes

# Answer
Not answered in @Majenko's post: Yes, with a 8MHz clock, each line will take the double of the time. Unless the line waits for something that is not clock driven - e.g. external input.

In addition to @Majenko's answer, a CPU has a clock to ensure the instructions are complete, before the next step starts. A CPU is made out of lots of transistors (I found a reference that indicated the AtMega was in the range of low millions, give-or-take an order of magnitude).

During a cycle, the electricity flows through the chip, turning transistors on/off, the results of which will turn more transistors on/off, and so forth down the line. While this is happening, some parts of the chip have a "wrong" value - you can think of this as being half-way through a calculation (you've added the one's column and the 10s column, and are about to start on the 100s column). You don't want this to affect the outside world, so (for example) your output pins are latched - held at whatever value they are - until the instruction is complete. How long it takes to complete an instruction varies, but the manufacturer works out the slowest instruction under the worst circumstances.

For the AtMega (which is the chip on the Arduino), Atmel (who designed the chip) has declared this is 1/20,000,000 of a second - this is 20MHz.

Note that not all microprocessors run all their instructions at 1 instruction per cycle - some instructions might take 1, or 2, or 10 cycles. Pipelining makes things even more complicated - a processor might do some of the work (e.g. fetch the next instruction) in one cycle, execute it in the next - but while it is executing instruction 1, it can also fetch the next instruction. To do this, it might need to take a guess at what instruction comes next (in the case of the machine-code equivalent of a "goto" - such is used for loops), and if it guesses wrong, it has to cope with that; throw away the instruction it retrieved and retrieve the next one, losing a cycle.

The Wikipedia page on instruction pipelining shows an example of a RISC chip pipelining in 5 stages - instruction fetch, instruction decode, execute, memory access, and write-back. So, you can have 5 instructions at some stage of execution, overlapping. Until the "writeback" phase, the instructions have no real effect. You can think of this as an assembly line - it takes 7 minutes to put a widget together, but it can be broken down into 5 stages, the longest stage taking 2 minutes. Once every two minutes, each partly completed widget is moved by the assembly line to the next station. You get one widget out every two minutes - The "clock" can only tick as fast as the slowest step. If you push the widget out any faster, the "bottleneck" will get more and more widgets queued up.
> 10 votes

---
Tags: oscillator-clock
---


title: Arduino at 20 MHz?

text:
# Question
Title: Arduino at 20 MHz?
I wonder why Arduino doesn't run at 20 MHz, the frequency the AVR is specified for. Now, running at 16 MHz, we're wasting 20% performance for nothing.

I don't think there are *any* implications when you replace the 16 MHz resonator with a 20 MHz type, with probably the sole exception for the baudrate in the bootloader. Or is there?

Does anybody know why the Arduino designers chose 16 MHz?

# Answer
There's no hardware reason (as far as I'm aware) that you couldn't run a suitable Arduino at 20 MHz. You'd run into minor timing inaccuracies in software though, as the standard Arduino configuration apparently works best if the clock speed is either 8 or 16MHz.

I suspect this is largely for historical reasons. Early Arduino boards were based on chips which only went up to 16 MHz, such as the `ATmega8`. Using the same configuration for all chips just keeps everything a bit simpler and more consistent.

There is more information here about the timing issues: http://forum.arduino.cc/index.php?topic=158223.0#msg\_1186708
> 6 votes

# Answer
You can, and I do.

It's not technically an Arduino anymore, I guess. I made my own board, replacing a resonator on a board will require some fine soldering, but it is definitely possible.

There are some gotchas: Anything time-related (e.g. millis() ) will be run faster than is should - 25% more millis() per second. Also, the bootloader expects 16mhz, so you won't be able to reprogram it at this speed. I purchased a USBASP programmer - it hooks into the 2x3 pin grid on one side of the board, and lets you reprogram it without the bootloader (this is how the bootloader is put on in the first place!). You will need at least 4.5 volts at 20mhz to avoid problems, compared to 3.78 volts for 16mhz - this means batteries will drain somewhat quicker (3x1.5v batteries will run down pretty quick), and if you have any motors or other draw on the batteries, 3 1.5v batteries will probably not work even if they are fresh.

Alternatively, going in the exact opposite direction, the lower the clock speed, the less voltage is required - for some projects, you might not need the clock speed - you can go down to 1.8v running at 4mhz.
> 4 votes

---
Tags: oscillator-clock
---


# Question
Title: How to limit the number of message that an Arduino sends to a phone without terminating it
I just stayed on `delay()` since that is the only thing I know but the thing is `delay()` cannot be interrupted. What I'm trying to achieve with this code is:

1. When the soilSensor detects moisture it would send a text message to a number only ONCE without terminating the program even if in the next loop the soilSensor is still detecting moisture.
2. The soilSensor's delay is `delay(60000)` and we would still wait for while to finish the delay but what if in the middle of the soilSensor's `delay(60000)` there is a movement for just about 5 seconds? What to do so that the tiltSensor can overlap the soilSensor's delay and sends a message to a number?

I want this program to run forever. Please help me! I needed this ASAP!

```
#include <SoftwareSerial.h>
SoftwareSerial SIM900(7, 8);
int led=22;

void setup()
{
  Serial.begin(9600);
  SIM900.begin(19200);
  pinMode(led, OUTPUT);
  delay(1000);
}

void sendSMS1()
{
  SIM900.println("AT + CMGS = \"+************\"");
  delay(100);
  Serial.println("Water Detected");
  delay(100);
  SIM900.println("Water Detected");
  delay(100);
  SIM900.println((char)26);
  delay(100);
  SIM900.println();
  delay(100);
}

void sendSMS2()
{
  SIM900.println("AT + CMGS = \"+************\"");
  delay(100);
  Serial.println("Movement Detected");
  delay(100);
  SIM900.println("Movement Detected");
  delay(100);
  SIM900.println((char)26);
  delay(100);
  SIM900.println();
  delay(100);
}

void loop()
{
  int soilSensor = analogRead(A0);
  int tiltSensor = analogRead(A1);

  if(soilSensor >= 10)
  {
    digitalWrite(22, HIGH);
    Serial.println(soilSensor);
    sendSMS1();
    delay(60000);
  }
  else
  {
    digitalWrite(22, LOW);
    delay(60000);
  }

  if (tiltSensor >= 100)
  {
    digitalWrite(led, HIGH);
    Serial.println(tiltSensor);
    sendSMS2();
    delay(60000);
  }
  else
  {
    digitalWrite(led, LOW);
    Serial.println(tiltSensor);
    delay(60000);
  }
}

```

# Answer
You use millis() to keep track of time and also prevent blocking. Replicating your program logic:

```
long soil_timer = 0;
long tilt_timer = 0;
char soil_flag = 1;
char tilt_flag = 1;

void loop() {
    int soilSensor = analogRead(A0);
    int tiltSensor = analogRead(A1);

  if (soil_flag == 1) {
    if (soilSensor >= 10) {
      digitalWrite(22, HIGH);
      Serial.println(soilSensor);
      sendSMS1();
    }
   else {
      digitalWrite(22, LOW);
    }
    soil_timer = millis();
    soil_flag = 0;
  }

  if (tilt_flag == 1) {
    if (tiltSensor >= 100) {
       digitalWrite(led, HIGH);
       Serial.println(tiltSensor);
       sendSMS2();
    }
    else {
       digitalWrite(led, LOW);
       Serial.println(tiltSensor);
    }
    tilt_flag = 0;
    tilt_timer = millis();
  }
  if (millis() - soil_timer >= 60000){
     soil_flag = 1;
  }
  if (millis() - tilt_timer >= 60000){
     tilt_flag = 1;
  }
}

```
> 1 votes

---
Tags: programming, arduino-mega, sensors, gsm
---


# Question
Title: esp8266-01 and arduino UNO communicating over i2c
i am not able to communicate over i2c with my esp-01 as master and UNO as slave. i get special characters sent back to esp, but my esp is sending correctly... output on my esp-01  output on my UNO is

connections are esp-01 gpio-0 to uno A4 and gpio-2 to uno A5 is it because i am not using a level shifter or any mistake in my code..?

here is my esp master code

```
#include <Wire.h>
#define I2CAddressESPWifi 6
int x=32;

void setup()
{
  Serial.begin(115200);
  Wire.begin(0,2);//Change to Wire.begin() for non ESP.
}

void loop()
{
  Wire.beginTransmission(I2CAddressESPWifi);
  Wire.write(x);
  Wire.endTransmission();
  x++;
  delay(1);//Required. Not sure why!

  Wire.requestFrom(I2CAddressESPWifi,10);
  Serial.print("Request Return:[");
  while (Wire.available())
  {
    delay(100);
    char c = Wire.read();
    Serial.print(c);
  }
  Serial.println("]");
  delay(500);
}

```

and here is my Uno slave code

```
#include <Wire.h>
#define I2CAddressESPWifi 6

void setup()
{
  Serial.begin(115200);
  Wire.begin(I2CAddressESPWifi);
  Wire.onReceive(espWifiReceiveEvent);
  Wire.onRequest(espWifiRequestEvent);
}

void loop()
{
  delay(1);
}

void espWifiReceiveEvent(int count)
{
  Serial.print("Received[");
  while (Wire.available())
  {
    char c = Wire.read();
    Serial.print(c);
  }
  Serial.println("]");
}

void espWifiRequestEvent()
{
  String ts = getTime();
  Serial.print("Sending:[");
  Serial.print(ts.c_str());
  Serial.println("]");
  Wire.write(ts.c_str());
}

String getTime(){
  int sec = millis() / 1000;
  int min = sec / 60;
  int hr = min / 60;
  String ts = "U:";
  if (hr<10) ts+="0";
  ts += hr;
  ts +=":";
  if ((min%60)<10) ts+="0";
  ts += min % 60;
  ts +=":";
  if ((sec%60)<10) ts+="0";
  ts += sec % 60;
  return(ts);
}

```

# Answer
Perhaps the `Serial.print()`s in the slave's request event function are causing too much delay (clock stretching?). You should make the `Wire.write()` the second statement in that function right after the `getTime` call. Or you could use `Wire.write("Hello")` as the only statement in the function, so you can narrow down the problem.
> 0 votes

---
Tags: i2c, esp8266
---


# Question
Title: Using Arduino microcontrollers without board
I am new into Arduino. So if I program the microcontroller using the Arduino board and once it is doing what I want can I just take the microcontroller out of the board and use the microcontroller itself? If so could you please guide me to some tutorials on how to use it?

# Answer
> 5 votes
I have a post about a breadboard Arduino \- in that I demonstrate the minimal amount of parts you need to use the controller (which is not much).

Example of wiring it up:

If you want to use an external crystal or resonator you can add that to the board like this:

8 MHz crystal shown, but you could use 16 MHz. Or change the fuses and use the internal oscillator.

---

Schematic showing how you could (if you wanted) add an ICSP header and an FTDI header:

---
Tags: arduino-uno
---


# Question
Title: scroll text through multiple i2c connected dot matrix displays
I have 4 dot matrix displays, every one of them connected to an i2c and accessible with `0x70`, `0x71`, `0x72` and `0x73`. All these work just fine when I address them apart. What I want to achieve is a scrolling text throughout all 4 displays. How can I do this? Are there any libraries around that already do this? (I did not find any).

Basically, this is my code:

```
#include <Wire.h>
#include "Adafruit_LEDBackpack.h"
#include "Adafruit_GFX.h"

Adafruit_8x8matrix matrix[4];

void setup() {
  Serial.begin(9600);
  Serial.println("4x(8x8) LED Matrix Test");
  matrix[0].begin(0x70);
  matrix[1].begin(0x71);
  matrix[2].begin(0x72);
  matrix[3].begin(0x73);
}

```

# Answer
> 0 votes
This is what I found behind the link @mikael-patel posted, and with a little configuration it does exactly what I want. Basically the `scroll()`-method handles anything neccessary.

```
#include <Wire.h>
#include "Adafruit_LEDBackpack.h"
#include "Adafruit_GFX.h"

#define NUM_MATRICES 2
Adafruit_8x8matrix matrix[NUM_MATRICES];

void setup() {
  Serial.begin(9600);
  Serial.println("8x8 LED Matrix Test");

  for(uint8_t m=0; m<NUM_MATRICES; m++) {
    matrix[m].begin(0x70 + m);
    matrix[m].clear();
    matrix[m].setTextSize(1);
    matrix[m].setTextWrap(false);  // we dont want text to wrap so it scrolls nicely
    matrix[m].setTextColor(LED_GREEN);
  }
}

void loop() {
  scroll("Hello World!");
}

void scroll(char* text) {
  int scrollPositions = (strlen(text) * 8) + 32;

  for (int x=(8 * NUM_MATRICES); x>=-scrollPositions; x--) {
   for(uint8_t m=0; m<NUM_MATRICES; m++) {
    matrix[m].clear();
    matrix[m].setCursor((x - (m * 8)), 0);
    matrix[m].print(text);
    matrix[m].writeDisplay();
   }
   delay(80);
  }
}

```

---
Tags: arduino-uno, i2c
---


title: i2c address instead of assigning pins

text:
# Question
Title: i2c address instead of assigning pins
I found this sketch online and would like to reuse it. I do have a dot-matrix-display, that is accessable through an i2c with the address 0x70. How do I change the code to be able to use the hardware address instead of the `Data`, `Load` and `CLK` pins?

```
#include <DS1307RTC.h>
#include <Time.h>
#include <Wire.h>
#include "LedControl.h"

//Pin definition constants
const int mDataIn=12, mLoad=11, mClk=10;  //Max7219 LED matrix

int h1, h2, m1, m2, s1, s2; // Each digit
int tChange; //Scratch used during change time via pushbutton

// Matrix library instance
LedControl lc=LedControl(mDataIn, mClk, mLoad,1); //Pin assignments and number of matrices (1)

void setup() {

  // Notify Arduimo that the RTC is the external time provider
  setSyncProvider(RTC.get);

  //Initialize the MAX72XX in power-saving mode.
  lc.shutdown(0,false);
  lc.setIntensity(0,1); // Set brightness to a low value
  lc.clearDisplay(0); // Clear the display
  delay(100); // Wait after initializing display

  Serial.begin(9600);
}

void loop() {

  //Isolate hours, minutes, seconds, one digit to each LED matrix column.
  h1=n1(hour());
  h2=n2(hour());
  m1=n1(minute());
  m2=n2(minute());
  s1=n1(second());
  s2=n2(second());

  // Cast as (change integer to) byte, write to LED row.
  // (Row runs from pin to pin on model used.)
  lc.setRow(0,7,byte(h1));
  lc.setRow(0,6,byte(h2));
  lc.setRow(0,4,byte(m1));
  lc.setRow(0,3,byte(m2));
  lc.setRow(0,1,byte(s1));
  lc.setRow(0,0,byte(s2));
  }

  int n1(int num) {  // Function to isolate first digit of 2-digit integer
    num = num / 10; //Integer division by 10 (discard remainder)
    return num;
  }

  int n2(int num) {  // Function to isolate second digit of 2-digit integer
    num = num % 10; //Modulo division by 10 (keep remainder only)
    return num;
  }

```

# Answer
> 1 votes
> How do I change the code to be able to use the hardware address instead of the Data, Load and CLK pins?

That is not possible as this is two totally different LED drivers. MAX72XX uses a protocol with those signals, while the dot-matrix LED display uses I2C.

You can always port the library to the dot-matrix. Or rewrite the sketch with the dot-matrix library.

Cheers!

---
Tags: arduino-uno, i2c
---


# Question
Title: What is this temperature sensor module? (LM358, 103)
I got this sensor some time ago because I wanted to play with measuring the temperature. I don't remember how I got it or if it has a name.

I've Googled around, and obviously is has the following

1. LM358 op amp
2. "103" thermistor

When googling for help I mostly find stuff about how to use the LM358 which is way above my skill level.

What is this and how do use it? :)

# Answer
> 1 votes
"103" is standard resistor (and other component) numbering - the first two digits specify a value and the third is a power-of-ten multiplier:

```
1 0 3 = 10 * 10^3 = 10K

4 7 2 = 47 * 10^2 = 4.7K

```

For devices that are typically measured in *thousandths*, *millionths* or smaller (like a capacitor) then the third digit is a *minus* power-of-ten:

```
1 0 6 = 10 * 10^-6 = 1u

```

That black disc labelled '103' is a thermistor \- a temperature-controlled resistor. It is most likely NTC, or negative-temperature coeffiecient, thus the resistance decreases as the temperature increases. This is contrary to typical physics where an increase in the temperature of a generic conductive material results in an increase in its electrical resistance.

The LM358 is included to *buffer* the thermistor from the Arduino/microcontroller. In simple terms, this means that the effective resistance of the analogue input pin does not have to be taken into consideration when converting the voltage measured to into a value for the temperature.

Without a better picture of both sides of the board, or better yet a circuit diagram, it is not possible to determine what the voltage on pin `S` will be for a given temperature. However, it seems that the thermistor is in series with another 10K resistor (`R3`, marked '103' of course) such that an increase in temperature results in an increase in voltage. At roughly 20 degrees Celsius (it depends on the manufacturer and their specifications) the resistance of the thermistor will be 10K, thus the voltage at `S` will be `Vcc/2`. Calculating the voltage for different temperatures requires you to know the temperature coefficient, which can be found from the datasheet or by measuring the resistance at various known temperatures and plugging those values into an equation.

# Answer
> 0 votes
Connect VCC to +5V, GND to GND, then S to A0.

Do an analogRead() of A0 and then convert that to temperature using the Steinhart-Hart equation, inserting the three values A B and C which you don't know because you have no documentation for the thermistor.

---
Tags: temperature-sensor
---


title: Ideal power supply for ESP8266

text:
# Question
Title: Ideal power supply for ESP8266
What is the ideal power supply for this module? What do you use that works ok?

Will the AMS1117 work?

# Answer
Yes, that will work. However, ignore the entire description.

That is **NOT** a buck regulator - it is a low-dropout **linear** regulator. Thus it will waste power as heat - the more current you draw the hotter it will get.

The '1117' range of regulators are pretty much ubiquitous. I use them in a wide range of products and situations where power consumption isn't critical (i.e., not battery based products).

For lower power requirements you want to get a *real* buck regulator. Something more like this: http://www.ebay.co.uk/itm/301842020065

**Note that it's an adjustable module, and you will need to first use a multimeter to adjust the output to 3.3V before you connect it up.**

Because they are adjustable they are a great thing to keep around since you can use them for all sorts of different situations.
> 1 votes

---
Tags: esp8266
---


title: Edit variables through Serial?

text:
# Question
Title: Edit variables through Serial?
Hello in a previous question i was able to set variables through if statements

```
  const uint16_t inputLength = 512;
int ss = 0;
int bHold = 0;

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

 void loop() {
  if ( Serial.available() > 0 )
  {
    static char input[inputLength];
    static uint16_t i;
    char c = Serial.read();

    if ( c != '\r' && c != '\n' && i < inputLength - 1)
      input[i++] = c;

    else
    {
      input[i] = '\0';
      i = 0;

      uint16_t array[80];
      uint16_t j = 0;

      if ( !strncmp(input, "ss", 2) )
      {
        char* p = input + 2;
        while ( (p = strchr(p, ' ')) != NULL )
          array[j++] = strtol(p, &p, 10); //

        for ( uint8_t i = 0; i < j; i++ )
        {
          ss = array[i];
          Serial.println(ss);
        }
      }

      if ( !strncmp(input, "bHold", 5) )
      {
        char* p = input + 5;
        while ( (p = strchr(p, ' ')) != NULL )
          array[j++] = strtol(p, &p, 10);

        for ( uint8_t i = 0; i < j; i++ )
        {
         bHold = array[i];
         Serial.println(bHold);
        }
      }

      if ( !strncmp(input, "Whos There", 10) )
      {
        Serial.print("me");
      }
      if ( !strncmp(input, "hello", 5) )
      {
        Serial.print("hi");
      }
      if ( !strncmp(input, "sa", 2) )
      {
        Serial.print("  ss= ");
        Serial.print(ss);

        Serial.print("  bHold= ");
        Serial.print(bHold);

        Serial.println(" ");
        Serial.println("==============================");
      }
    }
  }
}

```

if works! but if i keep adding variables i have to keep adding if statements and this will get longer. so then i went with code like this that allows me to set all variables at once

```
#define INPUT_SIZE 30

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

}
void loop()
{

  while (Serial.available() > 0) {

    int _mode = Serial.parseInt();
    int _ss = Serial.parseInt();
    int _bHold = Serial.parseInt();

    if (Serial.read() == '\n') {
      ss = _ss;
      bHold = _bHold;
      mode = _mode;

    }
  }

}

```

this works awesome! but i have to set all variables at once. my question is is there a way i can simply input a command like ss = 10 press enter then bHold = 30 and not have to input any other variable? thanks i advance. please point me in right direction Maybe make a function?

# Answer
Somewhere along the line you have to tell your program how to map names to actual variables. Once you have compiled your program it forgets the names of the variables - those only exist in the source code.

So you have to have some other manual list of those variable names - be that in the form of `if(...)` statements, or an array of structs with the name in them, or whatever.

There's no getting away from it - you need that manual mapping in some form or other.

The closest you could get would be to set up some kind of *hash* system using structs and linked lists, whereby you could set any key/value pair, but then of course your program would still have to know to look for certain keys in the hash to do things with them, so that would be pretty pointless since you've just moved the variable mapping from one place to another.
> 0 votes

# Answer
You can store variables on the fly in a simple array or linked list. A linked list would probably be better, but for now we'll just use an array.

```
const int MAX_VARS = 10;
const int NAME_SIZE = 16;

typedef _var
{
    char  name[NAME_SIZE];
    int   value;
} Var;

Var variables[MAX_VARS];
unsigned int var_count = 0;

void loop()
{
    char *command = getSerialInput(); // get a line of input from the serial stream

    // parse the command "set varname=value"
    if (strncmp(command, "set ", 4) == 0)
    {
        char *new_name = command + 4; // skip the 'set '

        char *ptr = strchr(command,'='); // find the equals character
        if (ptr != NULL)
        {
             *ptr = '\0';              // Break the string in half about the '='
             char *new_value = ptr+1;  // Everything after the equals is the value

             // Now we have a parsed variable name, and value
             // Have we already stored this variable?
             int i;
             for (i=0; i<var_count; i++)
             {
                 if (strcmp(variables[i].name, new_name) == 0)
                 {
                     // Found an existing copy - update it
                     variables[i].value = new_value;
                     break;
                 }
             }

             // Did we find the variable already?  No - add a new one
             if (i == var_count && i< MAX_VARS)
             {
                 strncpy(variables[i].name, new_name, NAME_SIZE);
                 variables[i].name[NAME_SIZE-1] = '\0'; // fix any strncpy() overflow
                 variables[i].value = new_value;
                 var_count += 1;
             }
             else if (i == MAX_VARS)
             {
                 Serial.println("Out of variable slots");
             }
        }
    }
    // parse the command "get varname"
    else if (strncmp(command, "get ", 4) == 0)
    {
         char *new_name = command+4;
         int i;
         for (i=0; i<var_count; i++)
         {
             if (strcmp(variables[i].name, new_name) == 0)
             {
                 // Found an existing copy - output it
                 Serial.println(value, DEC);
                 break;
             }
         }

         // Did we find the variable already?  No - error
         if (i == var_count)
         {
              Serial.print(new_name);
              Serial.println(" - not found");
         }
    }
}
else
{
    Serial.println("HELP: \"set <name>=<value>\" or \"get <name>\"");
}

```

This would be better with dynamically allocated memory, so the programme only uses exactly what it needs. But I wanted to show a way of storing a list of user input without complications. Obviously this programme omits a lot of error checking too - like when you run out of array slots in `variables`; or when the user input is bad.
> 0 votes

---
Tags: serial
---


title: Why is my Arduino still working?

text:
# Question
Title: Why is my Arduino still working?
I read an article that said that shorting an IO pin to ground would destroy the pin. I've done this before when I connected a buzzer to an IO pin and to ground without resistors, the buzzer is only 14 ohms so the current would be quite high through the pins. Why is my Arduino still working, and how should I know when to use resistors or what rating to use?

# Answer
You don't necessarily destroy the pin, but it won't do it any good. To work out the resistors use Ohm's Law. The continuous output of a pin should not exceed 20 mA, thus:

```
V = I * R
R = V / I
R = 5 / 0.020
R = 250

```

Thus 250 ohms, from the pin to ground, would allow a safe amount of current to flow.

As for the rating, that resistor would dissipate:

```
W = V * I
W = 5 * 0.020
W = 0.1

```

Thus a resistor that could handle 100 mW would be required. More reasonably, a quarter watt resistor should be fine.
> 3 votes

# Answer
The Arduino is tougher than it looks. ;-) Or maybe you were just lucky.

The exact point of failure of an IC is hard to predict, because of part to part variations, and because it can depend on many uncontrolled factors (duration of fault, temperature, voltages and currents on other pins, part history...). Then, the *absolute maximum ratings* are not the predicted point of failure. They are rather a lower bound:

* The part *should not* fail if you do not exceed the ratings
* it *may* fail anywhere beyond those limits.

Time is, however, also a factor. The manufacturer says that operating the part close to the limits for an extended period may shorten its lifespan.
> 3 votes

---
Tags: arduino-mega
---


# Question
Title: Is it possible to setup a system based on Arduino Due running QNX?
I would like to create some QNX applications and test them in a hardware different than my virtual machine. Since Arduino Due board is based on the Atmel SAM3X8E ARM Cortex-M3 CPU and QNX® Neutrino® RTOS supports that processor, I was wondering if it is possible make them work together.

What would be the challenges to make it work?

# Answer
> Since Arduino Due board is based on the Atmel SAM3X8E ARM Cortex-M3 CPU and QNX® Neutrino® RTOS supports that processor, I was wondering if it is possible make them work together.

Does QNX really support ARM Cortex-M3? I believe that is not possible as the processor does not have the necessary hardware support.

Please see the BSP list.

Cheers!
> 1 votes

# Answer
Typically the challenge in porting a new OS to a board is to configure stuff like:

* system clock (to drive the scheduler of the OS at the right frequence)
* board specific I/O
* components that are not part of the SoC (but iirc DUE doesn't have any of these)
* individual HW blocks (like on which serial port redirect the character interface, if your application has any)
* wakeup sources, in case you have/want low power modes and you need the board to wake up when something specific happens

None of these are impossible tasks and they are all good to learn more about the system, but otoh it's unlikely you can rush through them.

The good news is that probably you will not need them all and not immediately.

But some you will have to perform and they will require understanding how your OS works and having the technical reference manual of your board and SoC.
> 0 votes

---
Tags: arduino-due
---


# Question
Title: Pin Mapping of nRF2401L01+ using Adafruit's nRF24L01+ library
I have an Arduino Uno and one of these nRF24L01+ from china (see image)

To use the module i wanted to use the library provided by Adafruit (http://playground.arduino.cc/InterfacingWithHardware/Nrf2401). My problem is, that they're using different names for some pins, because the library is designed for a different module with the following pin outs.

I don't know which PIN from the China module corresponds to the DAT and DR1 Pin on the Adafruit module.

So my questions are:

1. Is it OK to use the library in conjunction with the china module?
2. What are the DAT and DR1 PIN on the module from China ?

What I know so far: \- took a look into the library and into the documentation at playground.arduino.cc/InterfacingWithHardware/Nrf2401 and found out that the DR1 pin is for the available() function to check if data is available to be read.

# Answer
> 2 votes
```
DR1 is MISO
DAT is MOSI

```

Though I'd advice using the RF24 library, as it's a lot more recent than the one from 2009 you linked to.

---
Tags: communication, nrf24l01+
---


title: Error compiling code (tv-b gone)

text:
# Question
Title: Error compiling code (tv-b gone)
I have been getting started with the Arduino and found a great project online called TV-B-Gone. It includes some code which I cannot compile. Yes I have included `main.h` and `worldcodes.cpp`.

```
/*
TV-B-Gone for Arduino version 0.001
 Ported to Arduino by Ken Shirriff, Dec 3, 2009
 http://arcfn.com

 The original code is:
 TV-B-Gone Firmware version 1.2
 for use with ATtiny85v and v1.2 hardware
 (c) Mitch Altman + Limor Fried 2009
 Last edits, August 16 2009

 With some code from:
 Kevin Timmerman & Damien Good 7-Dec-07

 Distributed under Creative Commons 2.5 -- Attib & Share Alike

 This is the 'universal' code designed for v1.2 - it will select EU or NA
 depending on a pulldown resistor on pin B1 !
 */

#include "main.h"

void xmitCodeElement(uint16_t ontime, uint16_t offtime, uint8_t PWM_code );
void flashslowLEDx( uint8_t num_blinks );
void quickflashLEDx( uint8_t x );
void tvbgone_sleep( void );
void delay_ten_us(uint16_t us);
void quickflashLED( void );
uint8_t read_bits(uint8_t count);

#define putstring_nl(s) Serial.println(s)
#define putstring(s) Serial.print(s)
#define putnum_ud(n) Serial.print(n, DEC)
#define putnum_uh(n) Serial.print(n, HEX)

/*
This project transmits a bunch of TV POWER codes, one right after the other,
 with a pause in between each.  (To have a visible indication that it is
 transmitting, it also pulses a visible LED once each time a POWER code is
 transmitted.)  That is all TV-B-Gone does.  The tricky part of TV-B-Gone
 was collecting all of the POWER codes, and getting rid of the duplicates and
 near-duplicates (because if there is a duplicate, then one POWER code will
 turn a TV off, and the duplicate will turn it on again (which we certainly
 do not want).  I have compiled the most popular codes with the
 duplicates eliminated, both for North America (which is the same as Asia, as
 far as POWER codes are concerned -- even though much of Asia USES PAL video)
 and for Europe (which works for Australia, New Zealand, the Middle East, and
 other parts of the world that use PAL video).

 Before creating a TV-B-Gone Kit, I originally started this project by hacking
 the MiniPOV kit.  This presents a limitation, based on the size of
 the Atmel ATtiny2313 internal flash memory, which is 2KB.  With 2KB we can only
 fit about 7 POWER codes into the firmware's database of POWER codes.  However,
 the more codes the better! Which is why we chose the ATtiny85 for the
 TV-B-Gone Kit.

 This version of the firmware has the most popular 100+ POWER codes for
 North America and 100+ POWER codes for Europe. You can select which region
 to use by soldering a 10K pulldown resistor.
 */

/*
This project is a good example of how to use the AVR chip timers.
 */

/*
The hardware for this project uses an Arduino:
 Connect an IR LED to pin 3.
 Connect a visible LED to pin 13 (or use builtin LED in some Arduinos).
 Connect a pushbutton between pin 1 and ground.
 Pin 0 is floating for North America, or wired to ground for Europe.
 */

extern PGM_P *NApowerCodes[] PROGMEM;
extern PGM_P *EUpowerCodes[] PROGMEM;
extern uint8_t num_NAcodes, num_EUcodes;

/* This function is the 'workhorse' of transmitting IR codes.
 Given the on and off times, it turns on the PWM output on and off
 to generate one 'pair' from a long code. Each code has ~50 pairs! */
void xmitCodeElement(uint16_t ontime, uint16_t offtime, uint8_t PWM_code )
{
  TCNT2 = 0;
  if(PWM_code) {
    pinMode(IRLED, OUTPUT);
    // Fast PWM, setting top limit, divide by 8
    // Output to pin 3
    TCCR2A = _BV(COM2A0) | _BV(COM2B1) | _BV(WGM21) | _BV(WGM20);
    TCCR2B = _BV(WGM22) | _BV(CS21);
  }
  else {
    // However some codes dont use PWM in which case we just turn the IR
    // LED on for the period of time.
    digitalWrite(IRLED, HIGH);
  }

  // Now we wait, allowing the PWM hardware to pulse out the carrier
  // frequency for the specified 'on' time
  delay_ten_us(ontime);

  // Now we have to turn it off so disable the PWM output
  TCCR2A = 0;
  TCCR2B = 0;
  // And make sure that the IR LED is off too (since the PWM may have
  // been stopped while the LED is on!)
  digitalWrite(IRLED, LOW);

  // Now we wait for the specified 'off' time
  delay_ten_us(offtime);
}

/* This is kind of a strange but very useful helper function
 Because we are using compression, we index to the timer table
 not with a full 8-bit byte (which is wasteful) but 2 or 3 bits.
 Once code_ptr is set up to point to the right part of memory,
 this function will let us read 'count' bits at a time which
 it does by reading a byte into 'bits_r' and then buffering it. */

uint8_t bitsleft_r = 0;
uint8_t bits_r=0;
PGM_P code_ptr;

// we cant read more than 8 bits at a time so dont try!
uint8_t read_bits(uint8_t count)
{
  uint8_t i;
  uint8_t tmp=0;

  // we need to read back count bytes
  for (i=0; i<count; i++) {
    // check if the 8-bit buffer we have has run out
    if (bitsleft_r == 0) {
      // in which case we read a new byte in
      bits_r = pgm_read_byte(code_ptr++);
      // and reset the buffer size (8 bites in a byte)
      bitsleft_r = 8;
    }
    // remove one bit
    bitsleft_r--;
    // and shift it off of the end of 'bits_r'
    tmp |= (((bits_r >> (bitsleft_r)) & 1) << (count-1-i));
  }
  // return the selected bits in the LSB part of tmp
  return tmp;
}

/*
The C compiler creates code that will transfer all constants into RAM when
 the microcontroller resets.  Since this firmware has a table (powerCodes)
 that is too large to transfer into RAM, the C compiler needs to be told to
 keep it in program memory space.  This is accomplished by the macro PROGMEM
 (this is used in the definition for powerCodes).  Since the C compiler assumes
 that constants are in RAM, rather than in program memory, when accessing
 powerCodes, we need to use the pgm_read_word() and pgm_read_byte macros, and
 we need to use powerCodes as an address.  This is done with PGM_P, defined
 below.
 For example, when we start a new powerCode, we first point to it with the
 following statement:
 PGM_P thecode_p = pgm_read_word(powerCodes+i);
 The next read from the powerCode is a byte that indicates the carrier
 frequency, read as follows:
 const uint8_t freq = pgm_read_byte(code_ptr++);
 After that is a byte that tells us how many 'onTime/offTime' pairs we have:
 const uint8_t numpairs = pgm_read_byte(code_ptr++);
 The next byte tells us the compression method. Since we are going to use a
 timing table to keep track of how to pulse the LED, and the tables are
 pretty short (usually only 4-8 entries), we can index into the table with only
 2 to 4 bits. Once we know the bit-packing-size we can decode the pairs
 const uint8_t bitcompression = pgm_read_byte(code_ptr++);
 Subsequent reads from the powerCode are n bits (same as the packing size)
 that index into another table in ROM that actually stores the on/off times
 const PGM_P time_ptr = (PGM_P)pgm_read_word(code_ptr);
 */

uint16_t ontime, offtime;
uint8_t i,j, Loop;
uint8_t region = US;     // by default our code is U

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

  TCCR2A = 0;
  TCCR2B = 0;

  digitalWrite(LED, LOW);
  digitalWrite(IRLED, LOW);
  pinMode(LED, OUTPUT);
  pinMode(IRLED, OUTPUT);
  pinMode(REGIONSWITCH, INPUT);
  pinMode(TRIGGER, INPUT);
  digitalWrite(REGIONSWITCH, HIGH); //Pull-up
  digitalWrite(TRIGGER, HIGH);

  delay_ten_us(5000);            // Let everything settle for a bit

  // determine region
  if (digitalRead(REGIONSWITCH)) {
    region = US; // US
    DEBUGP(putstring_nl("US"));
  }
  else {
    region = EU;
    DEBUGP(putstring_nl("EU"));
  }

  // Tell the user what region we're in  - 3 is US 4 is EU
  quickflashLEDx(3+region);

  // Indicate how big our database is
  DEBUGP(putstring("\n\rNA Codesize: ");
  putnum_ud(num_NAcodes);
  );
  DEBUGP(putstring("\n\rEU Codesize: ");
  putnum_ud(num_EUcodes);
  );
}

void sendAllCodes() {
  // We may have different number of codes in either database
  if (region == US) {
    j = num_NAcodes;
  }
  else {
    j = num_EUcodes;
  }

  // for every POWER code in our collection
  for (i=0 ; i < j; i++) {
    PGM_P data_ptr;

    // print out the code # we are about to transmit
    DEBUGP(putstring("\n\r\n\rCode #: ");
    putnum_ud(i));

    // point to next POWER code, from the right database
    if (region == US) {
      data_ptr = (PGM_P)pgm_read_word(NApowerCodes+i);
    }
    else {
      data_ptr = (PGM_P)pgm_read_word(EUpowerCodes+i);
    }

    // print out the address in ROM memory we're reading
    DEBUGP(putstring("\n\rAddr: ");
    putnum_uh((uint16_t)data_ptr));

    // Read the carrier frequency from the first byte of code structure
    const uint8_t freq = pgm_read_byte(data_ptr++);
    // set OCR for Timer1 to output this POWER code's carrier frequency
    OCR2A = freq;
    OCR2B = freq / 3; // 33% duty cycle

    // Print out the frequency of the carrier and the PWM settings
    DEBUGP(putstring("\n\rOCR1: ");
    putnum_ud(freq);
    );
    DEBUGP(uint16_t x = (freq+1) * 2;
    putstring("\n\rFreq: ");
    putnum_ud(F_CPU/x);
    );

    // Get the number of pairs, the second byte from the code struct
    const uint8_t numpairs = pgm_read_byte(data_ptr++);
    DEBUGP(putstring("\n\rOn/off pairs: ");
    putnum_ud(numpairs));

    // Get the number of bits we use to index into the timer table
    // This is the third byte of the structure
    const uint8_t bitcompression = pgm_read_byte(data_ptr++);
    DEBUGP(putstring("\n\rCompression: ");
    putnum_ud(bitcompression);
    putstring("\n\r"));

    // Get pointer (address in memory) to pulse-times table
    // The address is 16-bits (2 byte, 1 word)
    PGM_P time_ptr = (PGM_P)pgm_read_word(data_ptr);
    data_ptr+=2;
    code_ptr = (PGM_P)pgm_read_word(data_ptr);

    // Transmit all codeElements for this POWER code
    // (a codeElement is an onTime and an offTime)
    // transmitting onTime means pulsing the IR emitters at the carrier
    // frequency for the length of time specified in onTime
    // transmitting offTime means no output from the IR emitters for the
    // length of time specified in offTime

#if 0

    // print out all of the pulse pairs
    for (uint8_t k=0; k<numpairs; k++) {
      uint8_t ti;
      ti = (read_bits(bitcompression)) * 4;
      // read the onTime and offTime from the program memory
      ontime = pgm_read_word(time_ptr+ti);
      offtime = pgm_read_word(time_ptr+ti+2);
      DEBUGP(putstring("\n\rti = ");
      putnum_ud(ti>>2);
      putstring("\tPair = ");
      putnum_ud(ontime));
      DEBUGP(putstring("\t");
      putnum_ud(offtime));
    }
    continue;
#endif

    // For EACH pair in this code....
    cli();
    for (uint8_t k=0; k<numpairs; k++) {
      uint16_t ti;

      // Read the next 'n' bits as indicated by the compression variable
      // The multiply by 4 because there are 2 timing numbers per pair
      // and each timing number is one word long, so 4 bytes total!
      ti = (read_bits(bitcompression)) * 4;

      // read the onTime and offTime from the program memory
      ontime = pgm_read_word(time_ptr+ti);  // read word 1 - ontime
      offtime = pgm_read_word(time_ptr+ti+2);  // read word 2 - offtime
      // transmit this codeElement (ontime and offtime)
      xmitCodeElement(ontime, offtime, (freq!=0));
    }
    sei();

    //Flush remaining bits, so that next code starts
    //with a fresh set of 8 bits.
    bitsleft_r=0;

    // delay 250 milliseconds before transmitting next POWER code
    //delay_ten_us(25000);
    delay_ten_us(10000);

    // visible indication that a code has been output.
    quickflashLED();
  }
  while (Loop == 1);

  // flash the visible LED on PB0  4 times to indicate that we're done
  delay_ten_us(65500); // wait maxtime
  delay_ten_us(65500); // wait maxtime
  quickflashLEDx(4);

}

void loop() {
  if (digitalRead(TRIGGER) == 0) {
    sendAllCodes();
  }
}

/****************************** LED AND DELAY FUNCTIONS ********/

// This function delays the specified number of 10 microseconds
// it is 'hardcoded' and is calibrated by adjusting DELAY_CNT
// in main.h Unless you are changing the crystal from 8mhz, dont
// mess with this.
void delay_ten_us(uint16_t us) {
  uint8_t timer;
  while (us != 0) {
    // for 8MHz we want to delay 80 cycles per 10 microseconds
    // this code is tweaked to give about that amount.
    for (timer=0; timer <= DELAY_CNT; timer++) {
      NOP;
      NOP;
    }
    NOP;
    us--;
  }
}

// This function quickly pulses the visible LED (connected to PB0, pin 5)
// This will indicate to the user that a code is being transmitted
void quickflashLED( void ) {
  digitalWrite(LED, HIGH);
  delay_ten_us(30);       // 30 millisec delay
  digitalWrite(LED, LOW);
}

// This function just flashes the visible LED a couple times, used to
// tell the user what region is selected
void quickflashLEDx( uint8_t x ) {
  quickflashLED();
  while(--x) {
    delay_ten_us(DELAY);  // 150 millisec delay between flahes
    quickflashLED();
  }
}

```

When I try compile and upload to my Arduino Mega 2560, I get this error

```
In file included from main.h:9:0,
                 from TVB.pde:21:
TVB:78: error: variable 'NApowerCodes' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
TVB:79: error: variable 'EUpowerCodes' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
variable 'NApowerCodes' must be const in order to be put into read-only section by means of '__attribute__((progmem))'

```

Is there any way I can fix this?

# Answer
> 1 votes
Try:

```
extern  PGM_P * const NApowerCodes[] PROGMEM;
extern  PGM_P * const EUpowerCodes[] PROGMEM;

```

The definition of PGM\_P is:

```
#define PGM_P const char *

```

which gives "const const" and gives "error: duplicate 'const'". But it is the variable that should be const.

Cheers!

---
Tags: arduino-mega, compile, ir
---