text:
Connecting Arduino with Philips Hue
I'm trying to control Philips Hue lights through an Arduino Uno (with a WiFi shield Model R3). Both the shield and the Philips Hue Bridge are connected to the same network and I'm trying to send JSON commands from the Arduino to the Hue Bridge from the following code taken from here.
#include <SPI.h>
#include <WiFi.h>
#include <WiFiClient.h>

char ssid[] = "mynetwork";     //  your network SSID (name)
char pass[] = "mypass";  // your network password
int status = WL_IDLE_STATUS;     // the Wifi radio's status

//Hue constants
const char hueHubIP[] = "192.168.0.50";  //Hue Bridge IP
const char hueUsername[] = "myhue";  //Hue username
const int hueHubPort = 80;

IPAddress server(192,168,0,50);
WiFiClient client;

//Hue variables
boolean hueOn;  // on/off
int hueBri;  // brightness value
long hueHue;  // hue value
String hueCmd;  // Hue command

unsigned long buffer=0;  //buffer for received data storage
unsigned long addr;
IPAddress ip;

void setup()
{
 //Initialize serial and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  // check for the presence of the shield:
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present");
    // don't continue:
    while (true);
  }

  // attempt to connect to Wifi network:
  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to WPA SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network:
    status = WiFi.begin(ssid, pass);

    // wait 10 seconds for connection:
    delay(10000);
  }

  // you're connected now, so print out the data:
  Serial.print("You're connected to the network");
  printCurrentNet();
  printWifiData();

  ip = WiFi.localIP();
  Serial.println(ip);

}

void loop()
{

    String command = "{\"on\": true,\"hue\": 50100,\"sat\":255,\"bri\":255,\"transitiontime\":"+String(random(15,25))+"}";
    setHue(1,command);
    command = "{\"on\": true,\"hue\": 65280,\"sat\":255,\"bri\":255,\"transitiontime\":"+String(random(15,25))+"}";
    setHue(2,command);
    command = "{\"hue\": 65280,\"sat\":255,\"bri\":255,\"transitiontime\":"+String(random(15,25))+"}";
    setHue(1,command);
    command = "{\"hue\": 50100,\"sat\":255,\"bri\":255,\"transitiontime\":"+String(random(15,25))+"}";
    setHue(2,command);

}

/* setHue() is our main command function, which needs to be passed a light number and a
 * properly formatted command string in JSON format (basically a Javascript style array of variables
 * and values. It then makes a simple HTTP PUT request to the Bridge at the IP specified at the start.
 */
boolean setHue(int lightNum,String command)
{
  if (client.connect(server, 80))
  {
    Serial.println(F("connected to server"));
    while (client.connected()&& status == WL_CONNECTED)
    {
      client.print(F("PUT /api/"));
      client.print(hueUsername);
      client.print(F("/lights/"));
      client.print(lightNum);  // hueLight zero based, add 1
      client.println(F("/state HTTP/1.1"));
      client.println(F("keep-alive"));
      client.print(F("Host: "));
      client.println(hueHubIP);
      client.print(F("Content-Length: "));
      client.println(command.length());
      client.println(F("Content-Type: text/plain;charset=UTF-8"));
      client.println();  // blank line before body
      client.println(command);  // Hue command
    }
    client.stop();
    return true;  // command executed
  }
  else
    return false;  // command failed
}

  //client.flush();
  //client.stop();

/* A helper function in case your logic depends on the current state of the light.
 * This sets a number of global variables which you can check to find out if a light is currently on or not
 * and the hue etc. Not needed just to send out commands
 */
boolean getHue(int lightNum)
{
  if (client.connect(server, 80))
  {
    client.print(F("GET /api/"));
    client.print(hueUsername);
    client.print(F("/lights/"));
    client.print(lightNum);
    client.println(F(" HTTP/1.1"));
    client.print(F("Host: "));
    client.println(hueHubIP);
    client.println(F("Content-type: application/json"));
    client.println(F("keep-alive"));
    client.println();
    while (client.connected()&& status == WL_CONNECTED)
    {
      if (client.available())
      {
        client.findUntil("\"on\":", "\0");
        hueOn = (client.readStringUntil(',') == "true");  // if light is on, set variable to true

        client.findUntil("\"bri\":", "\0");
        hueBri = client.readStringUntil(',').toInt();  // set variable to brightness value

        client.findUntil("\"hue\":", "\0");
        hueHue = client.readStringUntil(',').toInt();  // set variable to hue value

        break;  // not capturing other light attributes yet
      }
    }
    client.stop();
    return true;  // captured on,bri,hue
  }
  else
    return false;  // error reading on,bri,hue
}

void printWifiData() {

  //WiFi shield's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);
}

  void printCurrentNet() {
  //SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());
  }

}
The above code gets my Arduino connected to mynetwork and I have also connected Hue Bridge to the same but it throws an error of No Socket Available.

UPDATE (9th March 2016):
I implemented suggestions 1 and 4 given by slash-dev and was able to get rid of No Socket Available error. Following is the updated code:
#include <SPI.h>
#include <WiFi.h>
#include <WiFiClient.h>

char ssid[] = "mynetwork";     //  your network SSID (name)
char pass[] = "mypass";  // your network password
int status = WL_IDLE_STATUS;     // the Wifi radio's status

//Hue constants
const char hueHubIP[] = "192.168.0.50";  //Hue hub IP
const char hueUsername[] = "myhue";  //Hue username
const int hueHubPort = 80;

IPAddress server(192,168,0,50);
WiFiClient client;

//Hue variables
boolean hueOn;  // on/off
int hueBri;  // brightness value
long hueHue;  // hue value
String hueCmd;  // Hue command

unsigned long buffer=0;  //buffer for received data storage
unsigned long addr;
IPAddress ip;

void setup()
{
 //Initialize serial and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  // check for the presence of the shield:
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println(F("WiFi shield not present"));
    // don't continue:
    while (true);
  }

  // attempt to connect to Wifi network:
  while (status != WL_CONNECTED) {
    Serial.print(F("Attempting to connect to WPA SSID: "));
    Serial.println(ssid);
    // Connect to WPA/WPA2 network:
    status = WiFi.begin(ssid, pass);

    // wait 10 seconds for connection:
    delay(10000);
  }

  // you're connected now, so print out the data:
  Serial.print(F("You're connected to the network"));
  printCurrentNet();
  printWifiData();
}

void loop()
{

    String command = "{\"on\": true,\"hue\": 50100,\"sat\":255,\"bri\":255,\"transitiontime\":"+String(random(15,25))+"}";
    setHue(1,command);
    command = "{\"on\": true,\"hue\": 65280,\"sat\":255,\"bri\":255,\"transitiontime\":"+String(random(15,25))+"}";
    setHue(2,command);
    command = "{\"hue\": 65280,\"sat\":255,\"bri\":255,\"transitiontime\":"+String(random(15,25))+"}";
    setHue(1,command);
    command = "{\"hue\": 50100,\"sat\":255,\"bri\":255,\"transitiontime\":"+String(random(15,25))+"}";
    setHue(2,command);

}

/* setHue() is our main command function, which needs to be passed a light number and a
 * properly formatted command string in JSON format (basically a Javascript style array of variables
 * and values. It then makes a simple HTTP PUT request to the Bridge at the IP specified at the start.
 */
boolean setHue(int lightNum,String command)
{
  client.stop();
  if (client.connect(server, 80))
  {
    Serial.println(F("connected to server"));
    while (client.connected()&& status == WL_CONNECTED)
    {
      client.print(F("PUT /api/"));
      client.print(hueUsername);
      client.print(F("/lights/"));
      client.print(lightNum);  // hueLight zero based, add 1
      client.println(F("/state HTTP/1.1"));
      client.println(F("Connection: keep-alive"));
      client.print(F("Host: "));
      client.println(hueHubIP);
      client.print(F("Content-Length: "));
      client.println(command.length());
      client.println(F("Content-Type: text/plain;charset=UTF-8"));
      client.println();  // blank line before body
      client.println(command);  // Hue command
    }
    client.flush();
    client.stop();
    return true;  // command executed
  }
  else
    return false;  // command failed
}

/* A helper function in case your logic depends on the current state of the light.
 * This sets a number of global variables which you can check to find out if a light is currently on or not
 * and the hue etc. Not needed just to send out commands
 */
boolean getHue(int lightNum)
{
  client.stop();
  if (client.connect(server, 80))
  {
    client.print(F("GET /api/"));
    client.print(hueUsername);
    client.print(F("/lights/"));
    client.print(lightNum);
    client.println(F(" HTTP/1.1"));
    client.print(F("Host: "));
    client.println(hueHubIP);
    client.println(F("Content-type: application/json"));
    client.println(F("Connection: keep-alive"));
    client.println();
    while (client.connected()&& status == WL_CONNECTED)
    {
      if (client.available())
      {
        client.findUntil("\"on\":", "\0");
        hueOn = (client.readStringUntil(',') == "true");  // if light is on, set variable to true

        client.findUntil("\"bri\":", "\0");
        hueBri = client.readStringUntil(',').toInt();  // set variable to brightness value

        client.findUntil("\"hue\":", "\0");
        hueHue = client.readStringUntil(',').toInt();  // set variable to hue value

        break;  // not capturing other light attributes yet
      }
    }
    client.flush();
    client.stop();
    return true;  // captured on,bri,hue
  }
  else
    return false;  // error reading on,bri,hue
}

void printWifiData() {

  //WiFi shield's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print(F("IP Address: "));
  Serial.println(ip);
}

  void printCurrentNet() {
  //SSID of the network you're attached to:
  Serial.print(F("SSID: "));
  Serial.println(WiFi.SSID());
}

See Arduino wifi shield - “No Socket available” thread in forum.arduino.cc

@jwpat: I have already seen that solution and appended the stated lines to my code but it doesn't work for me.

The error message seems to be coming from the network library code itself rather than anywhere in your sketch, which is a rather ugly practice by the library's author - what's to say that the Serial object is being used in a way that makes it an appropriate place to display errors?  To debug this more, you may need to dig into the networking library and add your own temporary (this project only) output that is more specific about why no socket is available.

I suspect a low RAM failure.  Here are some suggestions that will dramatically lower your RAM usage:
1) You still have Serial.print using double-quoted C string constants.  Use F("C string") for those, too.  For example:
  Serial.println( F("WiFi shield not present") );

Every double-quoted C string uses RAM in addition to FLASH program space.  You have already saved a bunch, but you should get rid of the above uses.

2) Don't use String for setHue.
TL;DR - it will use extra RAM, FLASH, CPU time, and cause inexplicable or random failures.
Instead, use C strings, aka char arrays for variables, or double-quoted string constants.  When the constants are wrapped with the F() macro, they don't use any RAM.
Here is an example of how to define and call a setHue with C strings instead of String:
--> See complete code below in UPDATE 3/9/2016 section <--

This just prints the C strings to Serial, but I hope you can see how they could also be printed to the client.

3) Don't use String for getHue.
Here is an example of how to define and call a getHue that uses C strings instead of String:
--> See complete code below in UPDATE 3/9/2016 section <--

Just copy and paste the displayed JSON into the Serial Monitor "Send" field.  The debug prints will display what gets parsed.

NOTE: It's not clear if the JSON attributes always come back in the same order.  This example expects the same order in which they were sent.  Other techniques would have to be used to accommodate any order.

4) Be sure to call client.flush() before every client.stop().

Summary:  I would guess that the combination of non-F() "C strings" wasting RAM, plus the String use of RAM (doubled or more), is leading to a low-RAM failure.  The above approach will lower RAM usage dramatically, and also save more than 1.6kB in program space.  After implementing these changes, almost all RAM will be available for the WiFi libraries.

UPDATE 3/9/2016
Here's my changes, merged into your second sketch.
#include <SPI.h>
#include <WiFi.h>
#include <WiFiClient.h>

char ssid[] = "mynetwork";     //  your network SSID (name)
char pass[] = "mypass";  // your network password
int status = WL_IDLE_STATUS;     // the Wifi radio's status

//Hue constants
const char hueHubIP[] = "192.168.0.50";  //Hue hub IP
const char hueUsername[] = "myhue";  //Hue username
const int hueHubPort = 80;

IPAddress server(192,168,0,50);

// Uncomment this to *really* use the Wi-Fi sheild.
// Comment this to read & write everything to the Serial Monitor for testing.
//#define REAL_WIFI
#ifdef REAL_WIFI
WiFiClient client;
#else
HardwareSerial & client = Serial; // redirect 'client' to the Serial Monitor
#endif

//Hue variables
boolean hueOn;  // on/off
int hueBri;  // brightness value
long hueHue;  // hue value
String hueCmd;  // Hue command

unsigned long buffer=0;  //buffer for received data storage
unsigned long addr;
IPAddress ip;

void setup()
{
 //Initialize serial and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  // check for the presence of the shield:
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println(F("WiFi shield not present"));
    // don't continue:
#ifdef REAL_WIFI
    while (true);
#else
    status = WL_CONNECTED;
#endif
  }

  // attempt to connect to Wifi network:
  while (status != WL_CONNECTED) {
    Serial.print(F("Attempting to connect to WPA SSID: "));
    Serial.println(ssid);
    // Connect to WPA/WPA2 network:
    status = WiFi.begin(ssid, pass);

    // wait 10 seconds for connection:
    delay(10000);
  }

  // you're connected now, so print out the data:
  Serial.print(F("You're connected to the network"));
  printCurrentNet();
  printWifiData();
}

void loop()
{
  setHue
    ( 1,
      F("{\"on\": true,\"hue\": 50100,\"sat\":255,\"bri\":255,\"transitiontime\":"),
      random(15,25),
      F("}")
    );

  delay( 10000 );

  setHue
    ( 2,
      F("{\"on\": true,\"hue\": 65280,\"sat\":255,\"bri\":255,\"transitiontime\":"),
      random(15,25),
      F("}")
    );

  delay( 10000 );

  setHue
    ( 1,
      F("{\"hue\": 65280,\"sat\":255,\"bri\":255,\"transitiontime\":"),
      random(15,25),
      F("}")
    );

  delay( 10000 );

  setHue
    ( 2,
      F("{\"hue\": 50100,\"sat\":255,\"bri\":255,\"transitiontime\":"),
      random(15,25),
      F("}")
    );

  delay( 10000 );

//  getHue( 1 );
//  getHue( 2 );
}

/* setHue() is our main command function, which needs to be passed a light number and a
 * properly formatted command string in JSON format (basically a Javascript style array of variables
 * and values. It then makes a simple HTTP PUT request to the Bridge at the IP specified at the start.
 */
boolean setHue
  ( int                        lightNum,
    const __FlashStringHelper *header,
    int                        parameter,
    const __FlashStringHelper *trailer )
{
#ifdef REAL_WIFI
  client.stop();

  if (client.connect(server, 80))
#endif
  {

    Serial.println(F("connected to server"));
#ifdef REAL_WIFI
    if (client.connected()&& status == WL_CONNECTED)
#endif
    {
      client.print(F("PUT /api/"));
      client.print(hueUsername);
      client.print(F("/lights/"));
      client.print(lightNum);  // hueLight zero based, add 1
      client.println(F("/state HTTP/1.1"));
      client.println(F("Connection: keep-alive"));
      client.print(F("Host: "));
      client.println(hueHubIP);

      // Calculate total command length.
      int cmdLength =
        strlen_P( (const prog_char *)header ) +
        1 +   //   Assume one digit for parameter...
        strlen_P( (const prog_char *)trailer );

      //  ... and add room for more digits if necessary.
      if (parameter > 9)
        cmdLength++;
      if (parameter > 99)
        cmdLength++;

      client.print(F("Content-Length: "));
      client.println( cmdLength );
      client.println(F("Content-Type: text/plain;charset=UTF-8"));
      client.println();  // blank line before body
      client.print( header );  // Hue command pieces
      client.print( parameter );
      client.println( trailer );
    }
    client.flush();
#ifdef REAL_WIFI
    client.stop();
#endif
    return true;  // command executed
  }
#ifdef REAL_WIFI
  else
    return false;  // command failed
#endif
}

//---------------------------------------------------------------------
// Utility function to extract one `bool` value from the client stream.
//   No buffers are used.  Each character is handled as it is received.
//   (you may want/need to add a timeout)

static bool clientParseBool( char delim )
{
  bool val = false;
  uint8_t count = 0; // number of chars we've read for the value

  while (status == WL_CONNECTED) {
    if (client.available()) {
      char c = client.read();
      if (c == delim)
        break; // done!
      if ((c == ' ') || (count++ > 0))
        continue; // skip spaces and anything after the first non-space char

      if (c == 't')
        val = true;
    }
  }

  // Debug prints
  Serial.print( F("bool ") );
  Serial.println( val );

  return val;
}

//-------------------------------------------
// Utility function to extract one 'unsigned 16-bit int' value from the client stream.
//   No buffers are used.  Each character is handled as it is received.
//   (you may want/need to add a timeout)

static uint16_t clientParseUint( char delim )
{
  uint16_t val = 0;

  while (status == WL_CONNECTED) {
    if (client.available()) {
      char c = client.read();
      if (c == delim)
        break; // done!
      if (c == ' ')
        continue; // skip spaces

      if (isdigit(c))
        val = val*10 + (c - '0'); // accumulate one digit of the bri value
    }
  }

  // Debug prints
  Serial.print( F("int ") );
  Serial.println( val );

  return val;
}

//-------------------------------------------

/* A helper function in case your logic depends on the current state of the light.
 * This sets a number of global variables which you can check to find out if a light is currently on or not
 * and the hue etc. Not needed just to send out commands
 */
boolean getHue(int lightNum)
{
  bool gotHue = false;

#ifdef REAL_WIFI
  client.stop();
  if (client.connect(server, 80))
#endif
  {

    client.print(F("GET /api/"));
    client.print(hueUsername);
    client.print(F("/lights/"));
    client.print(lightNum);
    client.println(F(" HTTP/1.1"));
    client.print(F("Host: "));
    client.println(hueHubIP);
    client.println(F("Content-type: application/json"));
    client.println(F("Connection: keep-alive"));
    client.println();

    if (status == WL_CONNECTED)
    {
        client.findUntil("\"on\":", "\0");
        hueOn = clientParseBool(',');

        if (status == WL_CONNECTED)
        {
            client.findUntil("\"bri\":", "\0");
            hueBri = clientParseUint(',');

            if (status == WL_CONNECTED)
            {
                client.findUntil("\"hue\":", "\0");
                hueHue = clientParseUint(',');

                gotHue = true;  // captured all three: on,bri,hue
            }
        }
    }

    client.flush();
#ifdef REAL_WIFI
    client.stop();
#endif
  }

  return gotHue;
}

void printWifiData() {

  //WiFi shield's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print(F("IP Address: "));
  Serial.println(ip);
}

void printCurrentNet() {
  //SSID of the network you're attached to:
  Serial.print(F("SSID: "));
  Serial.println(WiFi.SSID());
}

A few notes:

I did not have the extra blank line in my original setHue, so I put it back in to match your sketch.
I added a REAL_WIFI define that I could comment out for testing on Serial.  When I run it, I get this output:

WiFi shield not present
  You're connected to the networkSSID:
  IP Address: 0.0.0.0
  connected to server
  PUT /api/myhue/lights/1/state HTTP/1.1
  Connection: keep-alive
  Host: 192.168.0.50
  Content-Length: 65
  Content-Type: text/plain;charset=UTF-8

  {"on": true,"hue": 50100,"sat":255,"bri":255,"transitiontime":22}
  connected to server
  PUT /api/myhue/lights/2/state HTTP/1.1
  Connection: keep-alive
  Host: 192.168.0.50
  Content-Length: 65
  Content-Type: text/plain;charset=UTF-8

  {"on": true,"hue": 65280,"sat":255,"bri":255,"transitiontime":24}

You can copy and paste the above output if you want to add and test getHue with just the Serial Monitor (i.e., comment out #define REAL_WIFI).
I added a 10-second delay between each setHue, just to pace the output, and to give the "transition-time" um... some time to work.  The transition time is in seconds, so loop will call setHue again, before the requested transition has completed.  You won't see much change when you keep telling it to gradually change to the new color, but it only gets to transition a little bit.  Without any delay, I don't think you'll see anything.  This could be your current problem!  With 10 seconds, at least it will get about half-way there.  :-(

Thanks for the detailed answer. I'm not getting the No Socket Available error anymore but the code isn't doing what it is supposed to i.e. change the colors of the bulb.
Previously, I have sent JSON commands from my computer browser by going to the IP of the Philips Hue Bridge and it works smoothly. Have a look here once: http://www.developers.meethue.com/documentation/getting-started

@Hyperbola, I'm glad the No Socket Available error is gone, but I'll need to see "the code".  :)  You could edit your question and add an UPDATE section with the latest version.  My examples won't do anything with the network, of course.  They just use the Serial Monitor.

I have implemented suggestions #1 and #4 as #2 and #3 were throwing some errors. However, the sketch isn't doing anything irrespective of no errors. It's not able to change the color oft he bulb. Can you think of any possibilities of the same? Basically, we are just sending the same JSON commands from the arduino as we'd do from the browser: developers.meethue.com/documentation/getting-started

@Hyperbola, new UPDATE section above.  I suspect transition-time is doing what you told it to do...  :-)

I wonder if you are running out of RAM? Those sockets use RAM, and you have quite a few string constants, like this:
  client.println("Content-Type: text/plain;charset=UTF-8");

Change that (and all similar ones) to use the F() macro:
  client.println(F("Content-Type: text/plain;charset=UTF-8"));

I put the F() macro and cut some unnecessary data printing (MAC ID etc.) but it's still throwing the same error. I have updated the question with the new code having the macro.

Some of those Ethernet devices only support a limited number of sockets. I thought it might be 3 or 4, but can you find out how many for your WiFi shield? Or put it another way, what is the spec of the shield? (link)

I'm using the R3 Shield, exactly same as here. (https://www.arduino.cc/en/Main/ArduinoWiFiShield)

With reference to this example, perhaps you should call client.stop() right before you call client.connect() at the start of setHue() and getHue(). You should also call not only client.stop(), but also client.flush() at the end of both functions, just in case: Flush first, then stop.
On a different note, correct your HTTP headers from client.println(F("keep-alive")); to client.println(F("Connection: keep-alive"));.

For anyone else that comes across this. The reason it takes about 10 seconds to run this, is because of the Original: while (client.connected()) or in the OP's Post above the while (client.connected()&& status == WL_CONNECTED). Either are located in the setHue.
I commented that while loop out (and the opening { and closing } brackets for that while loop or you'll get an error of course), and the hue light changed instantaneously.
If you put a print to serial line in that loop, you'll see that it runs that loop continuously, which causes the long delay.
If you come upon this post from the original https://www.makeuseof.com/tag/control-philips-hue-lights-arduino-and-motion-sensor/ note that you should change the main loop's if statements to:
if((digitalRead(pir) == 1) && (activated == false) )

and
if((digitalRead(pir) == 0) && (activated == true) )

That way the setHue only is called on a change of state.


text:
Convert library from using bitbanging to hardware SPI
I'm using a MCP3008 8ch 10bit ADC to expand the Analog Inputs for the project I'm working on. The only library I can find for it is here the library is ported from Adafruit's Raspberry Pi library here. From what I can tell the library uses bitbanging as opposed to hardware SPI in order to communicate. I would like to use hardware SPI, but don't have the skills to write a library to communicate with it myself. Are there any resources for how to write a library like that, or anything I can read about on how to convert a library from bitbanging to hardware SPI?

What Arduino is this for?

It's for a PCB I designed based on the Atmega 1284 with hardware support added to the IDE with MightyCore found here: https://github.com/MCUdude/MightyCore

Typically, the library has a "sendByte" function in which it sends through "software spi" you would only have to re-write that.

The library uses some weird form of SPI. As it sends only 5 bits, and then reads 12 bits. SPI is normally a multiple of 8 bits.

Turns out my google-fu needs work. I found this that works great using hardware SPI! Thanks everyone!

The standard AVR library has SPI handling. See, for example: http://www.gammon.com.au/spi
You don't have to write a library if you don't want, just communicate directly using SPI.
The datasheet for the MCP3008 has some tips for using an 8-bit SPI system to communicate with the device. In particular this chart:

You can see from that, that you will need 3 x SPI.transfer. I don't have one here to test with, but the code would look like this:
digitalWrite (SS, LOW);  // select device
int result;
SPI.transfer (0x01);  // start bit
result = SPI.transfer (0b10000000);  // single, ch0
result = (result & 0b11) << 8;  // move to high-order byte
result |= SPI.transfer (0);   // lower order byte
digitalWrite (SS, HIGH);  // deselect

Untested, but this should be roughly it.

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/

sort: votes


text:
How to get a button state change within a for loop?
I have a for loop inside my void loop() that triggers a piezo.
What I want to happen is when I press a button, it breaks the loop of the piezo, but right now, it's as if it isn't detecting the button press inside my for loop.
Here's my code:
#include <Adafruit_NeoPixel.h>

#define PIN 6
#define TONE 8
const int buttonPin = 2;

long fadeTime = 5 * 1000L; // X minutes
int colorStops = 256;
int delaySpeed = fadeTime / colorStops;
int notes[] = {262,294,330,349};
int switchState = 0;         // variable for reading the pushbutton status

Adafruit_NeoPixel strip = Adafruit_NeoPixel(5, PIN, NEO_RGB);

void setup() {
  pinMode(buttonPin, INPUT); // initialize the pushbutton pin as an input

  strip.begin();
  strip.show();
}

void loop() {
  // read the state of the pushbutton value:
  switchState = digitalRead(buttonPin);

  // Fade in light
  for(int i = 1; i<colorStops; i++){
    for(int np = 0;np<strip.numPixels(); np++){
      strip.setPixelColor(np, strip.Color(i,i,0));
    }
    strip.show();
    delay(delaySpeed);
  }

  // Play tone after light fully bright
  for(int i = 1; i<100; i++){
    // Turn off tone on button press
    if (switchState == HIGH) {
      noTone(TONE);
      break;
    }
    tone(TONE, notes[random(0,3)]);
    delay(100);
  }
}

Does switchState = digitalRead(buttonPin); only get called at the start of the void loop and so it can't detect the button change until then? Something else?
Also, in case it's useful, here's my hardware set up...

That'll be because you're not reading the button inside the for loop?

@Majenko Does switchState not just call digitalRead(buttonPin)?

No. switchState is assigned the results of performing digitalRead(buttonPin) at the time it is called - i.e., at the top of loop().

You aren't reading the state of the button within your loop.
You only read it the once at the top of your loop():
void loop() {
  // read the state of the pushbutton value:
  switchState = digitalRead(buttonPin);

You need to replicate that every time you want a new reading from the button - so in your loop you need to add that digitalRead line:
// Play tone after light fully bright
for(int i = 1; i<100; i++){
  // Turn off tone on button press
  switchState = digitalRead(buttonPin);
  if (switchState == HIGH) {
    noTone(TONE);
    break;
  }
  tone(TONE, notes[random(0,3)]);
  delay(100);
}

Or you can do away with the variable altogether and just test the return value of the digitalRead:
// Play tone after light fully bright
for(int i = 1; i<100; i++){
  // Turn off tone on button press
  if (digitalRead(buttonPin) == HIGH) {
    noTone(TONE);
    break;
  }
  tone(TONE, notes[random(0,3)]);
  delay(100);
}

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/


text:
What's in an Arduino?
I've been using an Arduino Uno Rev. 3 for a few projects and would like to switch to using a bare Atmega328 chip so I can keep everything on the same board. I've seen the Arduino on breadboard tutorial which is fine, but the Arduino board itself has a lot of other components that aren't in the tutorial. I realize I can go look up the actual design itself, but I'm looking for a high level description of what most of the components are used for.
I'm not interested in programming through the Arduino IDE, so I don't need parts for serial programming and such. But I'm wondering if leaving out some other components would leave me at a disadvantage. For example, the datasheet recommends connecting AVCC to VCC with an LC circuit for ADC noise cancellation, but the arduino on breadboard tutorial doesn't mention this and I otherwise never would have known.

I realize I can go look up the actual design itself - So do it! It is a very simple board. If you have a specific question about some part of it, then ask.

What do you expect us to tell you that is not "go read the schematic?" If you want a block diagram, it's just a microcontroller, USB-to-serial, and some voltage regulation.

If you're not interested in the Arduino hardware, and you're not interested in the Arduino software, why mention Arduino at all? Just work directly from the Atmega328 datasheet.

This is one of the rare hardware questions that are probably better suited for the Arduino SE. You want a description of the Arduino hardware, it can't be more Arduino-specific than that.

Which Arduino? There are a lot of different board types.

Are you asking for a component-by-component description of (say) an Arduino Uno? Or are you asking for a sensible stand-alone board configuration?

Wel specifcally I'm trying to migrate from using an arduino to control an LCD, read 4 inputs where 3 of them are analog inputs, and output 2 signals, to having it on a standalone board without the unnecessary parts. So I tried to see if there were any general rules that apply.

This

You did not specify what Arduino board you are talking about. It would
have been useful to tag the question with the appropriate board name. In
the following, I assume you want something similar to an Arduino Uno,
i.e. an ATmega328P at 5 V and 16 MHz.

I realize I can go look up the actual design itself [...]

You should. There really isn't that much to it.
Let us take a look at the Uno rev. 3 schematic, and see what may be
useful to you:

ATmega16U2 and associated circuitry: This is for USB communication.
You have no use of it if you are not doing USB.
3.3 V regulator: This is for providing the Arduino 3.3V output.
Only a convenience feature, not used by the Arduino itself. You should
leave this out unless you need a 3.3 V supply.
5 V regulator. Only you know how you want to power your board.
This regulator is needed unless you have some reasonably stable
5 V supply like, e.g., a USB bus.
ISCP header: This is rarely used on an Arduino, but you are very
likely to use it in your custom board, as ICSP is the easiest way to
program an ATmega with no bootloader.
Reset button: Not always needed, as you can just power-cycle your
board.
10 kΩ pullup on RESET: Your board is very likely to work just
fine without this, but there is a little risk that you suffer from
random resets. You want this resistor on anything that is
“production”-like, for reliability concerns.
Decoupling capacitors: Just like the RESET pullup, the board may work
without them, but they provide reliability.
The MOSFET and OP-amp right before the 3.3 V regulator: This is
for automatically switching between the Vin and USB power supplies.
Unlikely to be useful on a custom board.
Ceramic resonator: For running the ATmega at 16 MHz, you need
either this or, for better timing characteristics, a quartz with
suitable capacitors.
LEDs: You know if you want them.
AREF capacitor: Only useful if you do analog readings, as it reduces
noise.

Yeah I was asking about the Uno Rev 3. I've edited my question to specify that. This is just what I was looking for! Ive looked at the schematic as well in the meantime but this goes over it in a very functional way.

It all depends on you want, and what you are talking or thinking about, when you ask What is an Arduino. There are two main things that I associate with Arduino: A family of Development Boards (maybe a hardware family of development boards) and a Software built to work with that development boards. This let me to answer you using that two focuses:

The hardware focus

I understand that the Arduino boards were intended to bring the electronics and programming, closer to artists. Also, as any development board, the Arduino boards allows the user to test the most quantity of features of the core microcontroller used in the board (for Arduino UNO, the Atmega328P). Thus implying that the most of components included are to allow you a "safe" development workaround.
Now, when you have worked in a project so many time that you are ready to replicate your design, maybe for a commercial implementation, an Arduino board can take up more space that if you design your own board, well by you are not going to use all the pins or well by that you noted that you are not going to mess up the microcontroller or other components (maybe you did it the necessary times to know it) and you want to choose a smaller package that don't needs an easy microcontroller replacement, or finally because you want to include in a single board all the components and circuitry you used for your project and remove the ones you are not going to use, that is the case you mention, and you can do more things... if you want to work from a CR2032 battery you won't need the regulator and so...

The software focus

When you decide to use your own circuitry, maybe you also want to program the IC by yourself, not through the 2K bootloader preprogrammed, but by your own ISP programmer. There are many workarounds using the Arduino IDE, but as apparently you don't want to use the Arduino IDE, the ISP programmer would be your programming interface.
A conclussion?: The minimal things you have to bear in mind to put in run the Atmega328P (and maybe most of microcontrollers) are 3: polarization, clock and Reset. The other things (the LC network you mentioned, the RC network I will mention, and so...) can improve the microcontroller stability and performance.

Polarization. Depending on the board, the DC supply used can be either 5V or 3.3V. Check the voltage used by your board.
Clock/Oscillator. See and reply the oscillator configuration used in the board. Then search where you can set up (in your IDE or code) the oscillator speed. Overall if you decide or want to use the internal oscillator, obtaining a minimal circuit or by playing with arduino config files. Note that, as example with the 328P, using the internal oscillator means that you are not going to reach the max number of MIPS the 328P can reach (with the internal you have 8MIPS, but you can use an external crystal up to 20 MHz to get 20 MIPS)... It really matters if you are going to do many processing tasks.
Reset. Please do not let it open, send it to VCC through a 10Kohm resistor, and (if available) additionally to GND with a 100nF ceramic capacitor.

There is very little on an Arduino aside from the chip itself, the regulator (sometimes) and the crystal / oscillator (sometimes).

But I'm wondering if leaving out some other components would leave me at a disadvantage.

Leaving out some parts will give you a disadvantage for some applications but give you an advantage for others; the same for adding some parts.
The right question is to figure out what you want to achieve with a given application and design towards that goal.
For minimum implementations, I have done plenty of nothing but the MCU - ghetto style.
On the flip side, there are plenty of applications where the MCU is literally buried in a sea of other parts: C8051F350 based LCR meter for example. so what to put in and what to take out is really application dependent.


text:
Can you help me trim my code?
First of all I want to be clear, I'm not very skilled in programming methods, all the C I learned was for various Arduino projects.
That being said, I just finished a project that reads some data from ELM327 via a HC-05 Bluetooth module and prints it to a 3.5 inch screen. All is working as intended, but apparently I have capped my Arduino UNO's memory because the sketch utilizes 99% of it. At the moment this is not very troublesome, but if sometime in the future I want to add more data to be read, I won't be able to do it.
With this in mind, I was looking for some advice on how I could rewrite my code in order to occupy less memory. I tried some stuff, but had little effect. As I said, I'm not familiar with advanced programming techniques.
LE: So I used all of your advice, I got rid of all the fonts, modified the MCUFRIEND library to only work with my display and got rid of some repeating code, and now the sketch got 35% smaller. Thanks to all.

Sketch uses 21216 bytes (65%) of program storage space. Maximum is 32256 bytes.
  Global variables use 642 bytes (31%) of dynamic memory, leaving 1406 bytes for local variables. Maximum is 2048 bytes.

Here's the (old) code:
#include <SoftwareSerial.h>
#include <Adafruit_GFX.h>
#include <MCUFRIEND_kbv.h>
#include <Fonts/FreeMonoBold9pt7b.h>
#include <Fonts/FreeMonoBold12pt7b.h>
#include <Fonts/FreeMonoBold18pt7b.h>
#include <Fonts/FreeMonoBold24pt7b.h>

SoftwareSerial BTSerial(10, 11);
MCUFRIEND_kbv tft;

#define BLACK   0x0000
#define WHITE   0xFFFF
#define GREY    0x8410

byte inData;
char inChar;
String constructor="";
String deconstructor="";
int A;
int B;
bool busy = false;

void setup()
{
    Retry:
    Serial.begin(9600);
    BTSerial.begin(38400);
    delay(1000);

    BTSerial.println("0100");
    while(BTSerial.available()>0)
    {
      inData=0;
      inChar=0;
      inData = BTSerial.read();
      inChar=char(inData);
      constructor = constructor + inChar;
      delay(20);
   }
    if (constructor.length()>0)
    {
      Serial.println("Conectat");
    }
    else {
      goto Retry;
      Serial.println("retry");
    }
    delay(5000);
    ReadData();
    basicConditions();

    tft.reset();
    uint16_t identifier = tft.readID();
    if (identifier == 0xEFEF) identifier = 0x9486;
    tft.begin(identifier);

    tft.fillScreen(BLACK);
    tft.setRotation(1);
    tft.setTextColor(WHITE);

    tft.fillRect(10, 40, 70, 40, GREY);
    tft.fillRect(10, 140, 70, 40, GREY);
    tft.fillRect(10, 240, 70, 40, GREY);
    tft.fillRect(140, 70, 200, 100, GREY);
    tft.fillRect(150, 220, 180, 60, GREY);
    tft.fillRect(370, 40, 70, 40, GREY);
    tft.fillRect(370, 140, 70, 40, GREY);
    tft.fillRect(370, 240, 70, 40, GREY);

    tft.setCursor(170,10);
    tft.setFont(&FreeMonoBold12pt7b);
    tft.print("Dacia 4X4");

    tft.setCursor(30,35);
    tft.setFont(&FreeMonoBold9pt7b);
    tft.print("Cuplu");
    tft.setCursor(80,70);
    tft.setFont(&FreeMonoBold18pt7b);
    tft.print("%");

    tft.setCursor(15,120);
    tft.setFont(&FreeMonoBold9pt7b);
    tft.print("Presiune");
    tft.setCursor(15,135);
    tft.print("motorina");
    tft.setCursor(82,170);
    tft.setFont(&FreeMonoBold12pt7b);
    tft.print("bar");

    tft.setCursor(15,220);
    tft.setFont(&FreeMonoBold9pt7b);
    tft.print("Presiune");
    tft.setCursor(20,235);
    tft.print("admisie");
    tft.setCursor(82,270);
    tft.setFont(&FreeMonoBold12pt7b);
    tft.print("bar");

    tft.setCursor(395,20);
    tft.setFont(&FreeMonoBold9pt7b);
    tft.print("Temp.");
    tft.setCursor(382,35);
    tft.print("Antigel");
    tft.setCursor(450,70);
    tft.setFont(&FreeMonoBold12pt7b);
    tft.print("C");

    tft.setCursor(395,120);
    tft.setFont(&FreeMonoBold9pt7b);
    tft.print("Temp.");
    tft.setCursor(382,135);
    tft.print("Admisie");
    tft.setCursor(450,170);
    tft.setFont(&FreeMonoBold12pt7b);
    tft.print("C");

    tft.setFont(&FreeMonoBold9pt7b);
    tft.setCursor(370,235);
    tft.print("Debit Aer");
    tft.setCursor(445,270);
    tft.setFont(&FreeMonoBold9pt7b);
    tft.print("g/s");

    tft.setFont(&FreeMonoBold12pt7b);
    tft.setCursor(150, 62);
    tft.print("Turatie (RPM)");

    tft.setFont(&FreeMonoBold12pt7b);
    tft.setCursor(152, 212);
    tft.print("Viteza (KM/H)");

}

void loop()
{
  cuplu();
  PresMot();
  PresAdm();
  TempAntig();
  TempAdm();
  MAF();
  RPM();
  viteza();
}
void basicConditions(){
    if(constructor.indexOf(">")>0)  {
    busy=false;
    constructor="";
  }
}
void ReadData()
{
  if (BTSerial.available()>0)
    busy = true;
  while(busy = true && constructor.indexOf(">")<0)
  {
    if (BTSerial.available()>0){
    inData=0;
    inChar=0;
    inData = BTSerial.read();
    inChar=char(inData);
    constructor = constructor + inChar;
    //Serial.println(constructor);
    //Serial.println(busy);
  }
  }
  //Serial.println("done");

  if (constructor.indexOf(">")>0){
    deconstructor=constructor.substring(11,13);
    A = strtol(deconstructor.c_str(),NULL,16);
    if (constructor.length()>15) {
        deconstructor = constructor.substring(14,16);
            B = strtol(deconstructor.c_str(),NULL,16);
    }
    else B = 0;
  }
}
void cuplu() {
  if (busy == false){
    BTSerial.println("01041");
      ReadData();
    tft.setTextSize(1);
    tft.setFont(&FreeMonoBold18pt7b);
    tft.setCursor(10, 70);
    tft.fillRect(10, 40, 70, 40, GREY);
    tft.print(A/2.55, 0);
  }
  basicConditions();
}
void PresMot() {
  if (busy == false){
      BTSerial.println("010A1");
      ReadData();
      tft.setTextSize(1);
      tft.setFont(&FreeMonoBold18pt7b);
      tft.setCursor(10, 170);
    tft.fillRect(10, 140, 70, 40, GREY);
    tft.print((3*A)/100.0, 1);
  }
  basicConditions();
}
void PresAdm() {
  if (busy == false){
      BTSerial.println("010B1");
      ReadData();
      tft.setTextSize(1);
      tft.setFont(&FreeMonoBold18pt7b);
      tft.setCursor(10, 270);
    tft.fillRect(10, 240, 70, 40, GREY);
    tft.print((A/100.0), 1);
  }
  basicConditions();
}
void TempAntig() {
    if (busy == false){
      BTSerial.println("01051");
      ReadData();
      tft.setTextSize(1);
      tft.setFont(&FreeMonoBold18pt7b);
      tft.fillRect(370, 40, 70, 40, GREY);
    tft.setCursor(370, 70);
    tft.print(A-40);
    }
  basicConditions();
}
void TempAdm() {
    if (busy == false){
      BTSerial.println("010F1");
      ReadData();
      tft.setTextSize(1);
      tft.setFont(&FreeMonoBold18pt7b);
      tft.fillRect(370, 140, 70, 40, GREY);
    tft.setCursor(370, 170);
    tft.print(A-40);
    }
  basicConditions();
}
void MAF() {
  if (busy == false){
      BTSerial.println("01101");
      ReadData();
      tft.setTextSize(1);
      tft.setFont(&FreeMonoBold18pt7b);
      tft.fillRect(370, 240, 70, 40, GREY);
    tft.setCursor(370, 270);
    tft.print(((256*A)+B)/4.0, 0);
  }
  basicConditions();
}
void RPM() {
  if (busy == false){
      BTSerial.println("010C1");
      ReadData();
      tft.setFont(&FreeMonoBold18pt7b);
    tft.setTextSize(2);
    tft.fillRect(140, 70, 200, 100, GREY);
    tft.setCursor(150, 140);
    tft.print(A/4.0, 0);
  }
  basicConditions();
}
void viteza() {
  if (busy == false){
      BTSerial.println("010D1");
      ReadData();
      tft.setFont(&FreeMonoBold18pt7b);
    tft.setTextSize(2);
      tft.fillRect(150, 220, 180, 60, GREY);
    tft.setCursor(180, 270);
    tft.print(A);
  }
  basicConditions();
}

99% of code is no problem, 80% dynamic ram can be a problem. What is the percentage of the used dynamic ram? The gfx library and the fonts use a lot of memory. You can upgrade to a arduino mega for more ram and extra hardware serial ports, or upgrage to arduino zero or one of the mkr boards for a faster processor, more ram and extra hardware serial port.

Are you trying to reduce Flash (code-space) or RAM (data-space) use? Which one is at 99%? The techniques for reducing either are different.

It says that the sketch size is at 99% and the dynamic memory is at 30%. So I’m guessing that the code size is problematic.

the code for drawing the gray rectangles is in your sketch twice

I assume you mean that are running short of flash memory, rather than
RAM. I base this assumption on the fact that you say that it's 99%
full, and that this “is not very troublesome”. Filling 99% of the RAM
with statically allocated data would certainly be troublesome. But
please note that it as always better to make your question clear and
explicit, rather than expect the respondents to make guesses.
Now, look at your font files. Each one of them ends with a comment
similar to this:
// Approx. 1672 bytes

Just adding those numbers we get:
FreeMonoBold9pt7b   1672 bytes
FreeMonoBold12pt7b  2402 bytes
FreeMonoBold18pt7b  4485 bytes
FreeMonoBold24pt7b  7469 bytes
------------------------------
TOTAL              16028 bytes

That's about 49% of your Arduino's flash. So that's the first place you
should be looking to if you want to save flash. Do you really need
these four different font sizes? And more specifically, do you really
need the (very flash hungry) largest sizes? Getting rid of some of them
is the easiest way to save flash.
If you really want to keep them all, your next option is to trim the
fonts in order to have only the characters you are actually using. This
can be a lot of work, but it should be a very effective way of
significantly reducing their flash footprint.
If you decide to take this path, the first step is to take note of what
characters you need at each font size. From a cursory look at your
source, it seems to me that the 18 pt font is only used for
printing “%”, “.”, the ten digits, and possibly “-”. That's a lot less
than the full ASCII repertoire the font supports. And I can't see where
you are using the 24 pt font. Look into an ASCII table and take
note of the smallest continuous range that contains all the characters
you use at one font size. Then trim the Glyphs array of the font to
keep only that range, and fix the first and last fields of the
GFXfont struct accordingly.
Next step is what will take most of the work. For each character you
actually need, take note of the bitmapOffset field of its glyph and
the next one. This way you know the range of offsets that are used by
that character. Then remove from the font's Bitmaps array all the
bytes that are at offsets you don't need. While doing this, you will be
changing the offsets of the bytes you keep, so you should update the
bitmapOffset fields on the Glyphs array accordingly.
Yes, that's quite some work, but you should end up with custom fonts
that are a lot lighter than the original ones, and yet capable of
displaying everything you are displaying now. Maybe you could write a
program to automate all this. Maybe someone already did that and you can
find it through a Web search...

Thanks for the advice and sorry I wasn’t very clear about the problem. First thing I’ll do is to get rid of the fonts permanently and go from there.

The documentation for the MCUFRIEND_kbv project has a file describing how to use.
This document has the statement:
Most of these controllers are #define SUPPORT_xxxx by default.
You can save Flash memory on a Uno by commenting out the macro(s) in MCUFRIEND_kbv.cpp

So you open MCUFRIEND_kbv.cpp and comment out support for the controllers you aren't using.
You can also reduce the number of different fonts you use to save Flash space.

Strings get allocated, reallocated, and deallocated as you use them, which can leave the heap - the bottom end of RAM memory - fragmented and the fragments essentially unusable. The memory report from the compiler can't show this; it happens at runtime.
If instead, you pre-allocate character arrays of a sufficient size for the eventual maximum text you want to put in them, they will stay in one place, neither growing nor shrinking, but also won't create those unused but unusable "holes" in the RAM.
Update:
Instead of:
String xyz;
xyz = "Hello";
xyz = xyz + ',';
xyz = xyz + "World!\n";

, you'd write:
#define XYZ_MAX  25    // or whatever size you need

char xyz[XYZ_MAX+1];
strcpy(xyz, "Hello";      // overwrites whatever is there
strcat(xyz, ", World!\n"; // appends whatever is there

You can further optimize RAM by directing the compiler to store the string literal ("Hello", etc.) in Flash. That's another topic, but here is a link to an article about it in the Arduino Playground, to get you started.

This is something I wasn't aware of. Maybe you could give me a short example on how to do it exactly.

you are repeating the same code in the 8 functions at the end of your sketch (note: the code is badly indented and the command sequence is inconsistent between functions)
similar thing is occurring at the middle of your sketch
here is the data that repeats
you could use one function and a lookup table (array)
this is the repeating data
+---------------+-------+-------------------------------+---------------+-----------------------+
|  println     setTextSize        fillRect                 setCursor          print             |
+---------------+-------+-------------------------------+---------------+-----------------------+
|   "01041"     |   1   |    10,  40,  70,  40, GREY    |    10,  70    |   A/2.55         , 0  |
|   "010A1"     |   1   |    10, 140,  70,  40, GREY    |    10, 170    |   (3*A)/100.0    , 1  |
|   "010B1"     |   1   |    10, 240,  70,  40, GREY    |    10, 270    |   (A/100.0)      , 1  |
|   "01051"     |   1   |   370,  40,  70,  40, GREY    |   370,  70    |   A-40                |
|   "010F1"     |   1   |   370, 140,  70,  40, GREY    |   370, 170    |   A-40                |
|   "01101"     |   1   |   370, 240,  70,  40, GREY    |   370, 270    |   ((256*A)+B)/4.0, 0  |
|   "010C1"     |   2   |   140,  70, 200, 100, GREY    |   150, 140    |   A/4.0          , 0  |
|   "010D1"     |   2   |   150, 220, 180,  60, GREY    |   180, 270    |   A                   |
+---------------+-------+-------------------------------+---------------+-----------------------+

you could also calculate some of the values in the first 6 functions

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/


text:
How to compare a string
How to compare a string coming from serial monitor with some predefined text stored  as a local variable?
If I say:
int led = 2;
String a = " abcds";

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

void loop() {
  String b = Serial.read();
  Serial.println(b);

  if (b != a) {
    digitalWrite(2,LOW);
  }
  else
  {
    digitalWrite(2,HIGH);
  }
}

just as an example, this code will not compile because on the serial I receive bytes and I want to compare with a string.
So my question is...
how should be done?

For which arduino board? Most of us try to avoid the String class for the arduino uno. As soon as a character is available, you add it to a buffer or to a String. Sometimes the data from the serial port is closed with a linefeed, then you can process the text in the buffer or in the String when a linefeed is read.

version using String (not recommended, but it makes simpler to understand the following C-string version)
#define LED 2
const char* a = "abcd";

void setup() {
  Serial.begin(115200);
  pinMode(LED, OUTPUT);
}

void loop() {
  if (Serial.available()) {
    String s = Serial.readStringUntil('\n');
    s.trim();
    if (s == a) {
      digitalWrite(LED, HIGH);
    } else {
      digitalWrite(LED, LOW);
    }
  }
}

the version with C-string:
#define LED 2
const char* a = "abcd";
char buffer[32];

void setup() {
  Serial.begin(115200);
  pinMode(LED, OUTPUT);
}

void loop() {
  if (Serial.available()) {
    size_t l = Serial.readBytesUntil('\n', buffer, sizeof(buffer - 1));
    if (buffer[l - 1] == '\r') {
      l--;
    }
    buffer[l] = 0; // the terminating zero
    Serial.println(buffer);
    if (strcmp(buffer, a) == 0) {
      digitalWrite(LED, HIGH);
    } else {
      digitalWrite(LED, LOW);
    }
  }
}

As I already commented on VE7JRO's post, Stream::readBytesUntil() will wait for the terminating character until it gets it or it times out, which can lead to long delays during which the sketch is unresponsive. A better solution is to read only whatever is available, and process the buffer when an LF is read. C.f. the blog post Reading Serial on the Arduino, by Majenko, for a better solution.

The String version works perfectly, but I can't get the C-string version to work. For me, the serial monitor shows "abcd" written out to 2 lines: line 1 prints "ab", line 2 prints "cd". Perhaps it's the old version of the IDE I'm using (1.0.6.2). I like that you provided 2 example sketches so the OP can see the difference in compile size: String 4364 bytes VS C-string 2746 bytes.

@EdgarBonet, it will wait only if terminating character is not present. the timeout can be set to for example to 10 milliseconds with setTimeout. in many cases it is better to wait for the stream as continue with other things in loop and then return to read an overflowed buffer

If your loop() takes so long that the serial buffer overflows, then you have probably done something very wrong. You can only afford to wait for the whole message to be received if you have no time-sensitive code outside of interrupt context. Stream::readBytesUntil() and delay() work in the same team: they can help you write simpler code if you can afford keeping the CPU busy doing nothing, but their use is not a good programming habit in general.

@EdgarBonet, if the gaps between the received bytes are microseconds small, but available() would sometimes return 0, what is a good way to read a command from Stream? the sketch has nothing to do, until this command is received. Other case:  with networking done in external modules and with Arduino libraries you can't have a 'real-time' loop. it could take some seconds until a web server sends a response, but then the bytes go in fast and always more than the serial buffer size.

C has strcmp() function that is used to compare two strings. It will return zero if two strings are equal non zero when not.

I started to suggest the same thing, and then noticed that the OP is using Arduino String objects, not C strings.

If you do a Google search on "Arduino String" you should find a class reference on the String class. https://www.arduino.cc/reference/en/language/variables/data-types/stringobject/
It has a function compareTo() that should do what you need.

Here is the loop() code from the SafeString_ReadCmdsTimed.ino example in the SafeString library available from the Arduino library manager.  It is non-blocking, i.e. no delays.
There is an extensive tutorial and examples available for SafeStrings.
SafeStrings has built-in error checking and debugging.  SafeStrings provides the functionality of Strings without the memory fragmentation problems of dynamic memory allocation.
If you are reading from telnet there is also a processbackspaces() method in SafeStrings to handle terminal typing corrections.
The delimiters are whatever you would like.  The example handles Windows, Unix and Mac end-of-lines.
char delimiters[] = " .,\r\n"; // space dot comma CR NL are cmd delimiters

void loop() {
  if (input.read(Serial)) {  // read from Serial, returns true if at least one character was added to SafeString input
    input.debug("after read => ");
    timeout.start(TIMEOUT_MS); // restart a 0.1sec timer every time something is read
  }

  if (input.nextToken(token, delimiters)) { // process at most one token per loop does not return tokens longer than input.capacity()
    token.debug("after nextToken => ");

    if (token == startCmdStr) {
      running = true;  Serial.print(F("start at ")); Serial.println(loopCounter);

    } else if (token == stopCmdStr) {
      running = false; Serial.print(F("stop at ")); Serial.println(loopCounter);

    } else if (token == resetCmdStr) {
      loopCounter = 0; Serial.print(F("reset Counter:")); Serial.println(loopCounter);

    }// else  // not a valid cmd ignore
  }
  if (timeout.justFinished()) { // nothing received for 0.1secs, terminated last chars so token will be processed.
    input += delimiters[0]; // any delimiter will do
    SafeString::Output.print(F("Input timed out"));
  }
  // rest of code here is executed while the user typing in commands
  if (running) {
    loopCounter++;
    if ((loopCounter % 100000) == 0) {
      Serial.print(F("Counter:")); Serial.println(loopCounter);
    }
  }
}

Please disclose your affiliation, you appear to be the author of the site you've linked multiple times.

Sure will add a 'my' to future posts.  There are a number of other free libraries/tutorials on my site, but that specific link is to the detailed tutorial for SafeString.which I am putting forward as a 'safe' replacement for Arduino Strings.  Check out the tutorial for all the reasons you should be using SafeString instead of Arduino Strings

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/


text:
Why is there a limitation in using Serial.println on ESP8266?
I'm trying to upload this code on ESP8266, and when I do, it just resets continuously.  This also happens when you have memory bugs, but obviously, this code has no memory bugs!  Here is the code:
#include "Arduino.h"

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

void loop()
{

}

void foo(){
    for(unsigned int i = 1; i <= 10000; i++){
        Serial.println("FOOBAR");
    }
}

Also, in the serial monitor, I get this (per reset):
Soft WDT reset

ctx: cont
sp: 3ffef130 end: 3ffef390 offset: 01b0

>>>stack>>>
3ffef2e0:  feefeffe feefeffe feefeffe 00002580
3ffef2f0:  0000001c 00000001 3ffe85b1 402023d4
3ffef300:  feefeffe 00000005 3ffe842d 3ffee364
3ffef310:  3fffdad0 00000006 3ffee340 40201fd1
3ffef320:  3ffe85b0 00000000 3ffee340 40201fd1
3ffef330:  3ffe8428 00000000 3ffee340 40201fec
3ffef340:  00000001 feefeffe 3ffee340 40202010
3ffef350:  feefeffe 00000000 00002580 40201c00
3ffef360:  3fffdad0 00000000 3ffee35c 40201c2e
3ffef370:  feefeffe feefeffe feefeffe 402021c8
3ffef380:  feefeffe feefeffe 3ffee370 40100718
<<<stack<<<
Õ®(ŽL‰Ì==   I5

So, why is this happening?

It's happening because you're not giving the ESP8266 a chance to do its housekeeping activities and the watchdog (which is enabled by default) is timing out - as evidenced by the very first line of your output:

Soft WDT reset

You need to allow the MCU to do other things at the same time as you are printing to serial:
void foo(){
    for(unsigned int i = 1; i <= 10000; i++){
        Serial.println("FOOBAR");
        yield();
    }
}

What does yield() does? Curious to know that.

the ESP8266 uses the same cpu for maintaining wifi as running sketch code. if your sketch code runs too long, the wifi routine freaks out about not being able to maintain a connection and resets. yield() pauses sketch code while the wifi does its thing.

Is there a way to modify time out?

@dandavis Very useful comment +1.


text:
How to change Arduino Nano MODEL_ID
I'm working on a project using a set of different Arduino Nano connected to a Raspberry Pi through USB.
Now my question is: "how can I, from the Pi's point of view, differentiate all of those Arduino and associate them with their respective tty?"
I found some part of my answer in this question. The answering guy proposes to manually change the Arduino MODEL_ID when compiling and to use it afterwork to identify the device. The problem is that I don't know how to achieve that.
I tried to edit the boards.txt file to add a new board configuration with custom vid.x and pid.x (why all those 4 different values?) but after selecting my board and uploading, the MODEL_ID still stays the same:
ID_MODEL_FROM_DATABASE=HL-340 USB-Serial adapter
ID_MODEL_ID=7523

Can't I just specify somehow the USB_PID macro to the compiler command line?

That question is about Arduino Micro, which has a ATmega32u4 with USB support. Yours has a ATmega328 with separate USB to serial chip.

How to change Arduino Nano MODEL_ID?

The Arduino Nano used a special USB-Serial adapter (FTDI FT232RL). You can change the ID but this requires some special hacking. Please see the provided links.
Cheers!

OK I see the problem then. Thanks! Unfortunately, the Arduino Nano that I have are chinese clones and so they use the ch341 USB serial driver, rather than the FTDI one. I keep investigating...

BW: Could your sketch on the Arduino Nano identify itself by sending an ID on startup? This would have to be unique for each connected board.

I think this is what I'm going to end with. Because even if I could change the vendor and product ID in the EEPROM, this would make a mess in the drivers that will not be able to recognize my devices anymore. I found an interesting link which propose a simple API to make this as easy as possible :)

Finally find the solution =)
You don't have to change the ID vendor or ID product: it is possible to attribute a permanent name with devpath (where the device is plugged)
The only downside of using the devpath is that the devices will always have to stay plugged into the same physical port.
Answer here:PersistentUSBDevices / Alternative filtering via Devpath


text:
LED pin 13 not flashing properly
This is my first program on Arduino Uno (the starter kit), although I do have prior experience with programming (JavaScript, coding class last year 7th grade). It blinks the internal led (pin 13) in a Morse Code message:

.... . .-.. .-.. ---   .-- --- .-. .-.. -..
. = dit();

- = dah();

(interval between parts of letter) = wip();

(interval between letters/words) = wah();

Here's my code:
/*
 * Roman's first program
 * Decipher the message!
*/

int ledPin = 13;
int index = 0;

void setup() {
  //initialize pins as outputs
  pinMode(ledPin, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  int sequence[] = {1,0,1,0,1,0,1,3,1,3,1,0,2,0,1,0,1,3,1,0,2,0,1,0,1,3,2,0,2,0,2,3,3,3,1,0,2,0,2,3,2,0,2,0,2,3,1,0,2,0,1,3,1,0,2,0,1,0,1,3,2,0,1,0,1};
  int arrLength = sizeof(sequence)/sizeof(int); //however THIS works?!
  if (index < arrLength-1) { //0-based array
    index++;
  } else {
     index = 0; //restart the sequence once finished
  }
  if (sequence[index] == 0) {
    wip();
  } else if (sequence[index] == 1) {
    dit();
  } else if (sequence[index] == 2) {
    dah();
  } else if (sequence[index] == 3) { //because sometimes I the values are screwed past arrLength...
    wah();
  }
  //Serial.println(String(sequence[index])+" , "+String(index));
}

void dit () {
  digitalWrite(pinMode, HIGH);
  delay(300);
  digitalWrite(pinMode, LOW);
}

void dah () {
  digitalWrite(pinMode, HIGH);
  delay(900);
  digitalWrite(pinMode, LOW);
}

void wip () {
  delay(900);
}

void wah () {
  delay(2100);
}

Yet nothing is happening, except for the four/five startup flashes on the led when I restart it (red button). And yes, I saved and compiled.

Well, mainly digitalWrite(pinMode, HIGH); looks suspicious. I though you called LED pin as ledPin
If you fix this, it should be working. As this one is working too, it's just simplified a little:
int ledPin = 13;
int index = 0;
const int8_t sequence[] = {1,0,1,0,1,0,1,3,1,3,1,0,2,0,1,0,1,3,1,0,2,0,1,0,1,3,2,0,2,0,2,3,3,3,1,0,2,0,2,3,2,0,2,0,2,3,1,0,2,0,1,3,1,0,2,0,1,0,1,3,2,0,1,0,1};
int arrLength     = sizeof(sequence);

void setup() {
  pinMode(ledPin, OUTPUT);
  Serial.begin(57600);
}

void loop() {
  Serial.println(String(sequence[index])+" , "+String(index));
  switch (sequence[index++]) {
    case 0: wip(); break;
    case 1: dit(); break;
    case 2: dah(); break;
    case 3: wah(); break;
  }
  if (index == arrLength) {
    index = 0;
  }
}

void dit () {
  digitalWrite(ledPin, HIGH);
  delay(300);
  digitalWrite(ledPin, LOW);
}

void dah () {
  digitalWrite(ledPin, HIGH);
  delay(900);
  digitalWrite(ledPin, LOW);
}

void wip () {
  delay(900);
}

void wah () {
  delay(2100);
}

Thank you! But, I'm pretty new to C code. Could you explain const int8_t or should I learn later? Also, you changed the baud...?

@Roman int is likely to be 16 or 32 bits (can't recall off the top of my head). IIRC the size of int may vary depending on the compiler you're using. Using int8_t guarantees an array of 8 bit ints, saving quite a bit of space. You're likely to have plenty of space at first, but eventually you'll write a large program and need to squeeze out every wasted byte you can just to fit it on the mcu.

Specifying 'const' informs the compiler that these variables are not meant to be changed (once initialized) and enables the compiler to check for and enforce that.


text:
Cheap ATtiny programmer on Debian
I've recently purchased a no-brand 1€ ATtiny programmer off eBay, and with the ridiculous price obviously came no documentation nor support from the seller.

At first I thought that using it with the Arduino IDE would have been as simple as plugging and programming, but no default lib worked. My hopes definitely crumbled when I realized the device wasn't even being picked up by Debian, showing instead this in the logs:
kernel.info: [ 2758.501968] usb 6-3: new low-speed USB device number 2 using ohci-pci
kernel.err: [ 2758.641798] usb 6-3: device descriptor read/64, error -62
kernel.err: [ 2758.885515] usb 6-3: device descriptor read/64, error -62
kernel.info: [ 2759.125231] usb 6-3: new low-speed USB device number 3 using ohci-pci
kernel.err: [ 2759.265065] usb 6-3: device descriptor read/64, error -62
kernel.err: [ 2759.508779] usb 6-3: device descriptor read/64, error -62
kernel.info: [ 2759.748500] usb 6-3: new low-speed USB device number 4 using ohci-pci
kernel.err: [ 2760.156027] usb 6-3: device not accepting address 4, error -62
kernel.info: [ 2760.291871] usb 6-3: new low-speed USB device number 5 using ohci-pci
kernel.err: [ 2760.699382] usb 6-3: device not accepting address 5, error -62
kernel.err: [ 2760.699421] usb usb6-port3: unable to enumerate USB device

and with lsusb outputting this:
Bus 007 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 002 Device 003: ID 07d1:3c0a WiFi Dongle
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 006 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 005 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 003 Device 002: ID 045e:0745 Mouse/Keyboard BT Dongle
Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub

Reading up on the subject seemed to confirm that it was something I shouldn't have bought, and the closest I've got to a better understanding was with this question (link) which I can't comment.
So building up on the answer there, can anyone please explain a bit more in detail what for and where micronucleus would be needed?
Alternatively, is it possible to go with something as easy as installing the drivers and plugging it into the Arduino IDE?

I'm in the same boat, or will be soon when the bits arrive from China.   The 1€ price tag is hard to resist!

I got a couple of Chinese USBASP programmers from eBay at 2.78 € each, with free shipping. They work great for programming ATtinies, and they are supported by avrdude (the programming tool used by the Arduino IDE). But you have to connect 6 wires...

It would be handy if you specified which specific item you bought. Most likely it's just the ATTiny breakout board that has the ISP-header brought out, and has a micro usb port, that is only used for power. I'd get a UsbASP programmer. They work perfectly for me.

If the board has a real ISP header, that would actually be a nice addition to the usbasp. No need to use the board's USB connector though, as the chip will be powered by the usbasp through the ISP.

This is unanswerable without a picture of the other side of the board.  Without that, and with no documentation, there's little reason to believe there is any IC on this capable of functioning as a USB device.  The provided failure message are merely a result of having a pullup resistor on a USB data line, without necessarily meaning any USB interface engine connected.  As this is in unanswerable form it should be closed

Looking at this item on ebay I am really confused as to how this product was meant to be used. As far as I can see there is no other MCU onboard. Couldn't find anyone actually using these on google either...

As this is in unanswerable form it should be closed - yes, Chris, but that's what comments are for. Teasing out more information about the question. You could have merely asked for a photo of the other side of the board.

It isn't clear to me what you need to do- both for specific chip and your programming needs.
You can easily program an ATTiny with just an arduino and a breadboard.  A breakout board and a socket are fun, you could also build or buy a permanent shield for this.
With that breakout board (you could just use a breadboard, too) and an Arduino, you can program your ATTiny from the ArduinoIDE or from avrdude (if for example you have just a .hex file from an Instructable.  You will find that the Arduino IDE doesn't support uploading .hex files directly, but since the IDE calls on avrdude for all the actual work- you can invoke avrdude from the command line to upload your .hex file to the chip).
If you mention which ATTiny you need to program, I've missed it.
Overall process is:
From the Arduino IDE, add these core libraries from: Tools/ Boards/ Boards manager
github.com/damellis/attiny
This will get you:
ATtiny 25 (8 pin)
ATtiny 45 (8 pin)
ATtiny 85 (8 pin)
ATtiny 24 (14 pin)
ATtiny 44 (14 pin)
ATtiny 84 (14 pin)

Add:
github.com/MCUdude/MicroCore  (this will need manual install, instructions are provided)
and
sourceforge.net/projects/ard-core13/files/latest/download  (I forget if this can be added from the IDE or needs manual install).
if you need ATtiny13 support.  Each has some advantages the other does not.
You will want to use IDE 1.6.x.
Wire up your breakout board (or breadboard) to your Arduino appropriately for the ATTiny you are using.  For example, according to the wiring diagram here for the ATTiny85:
highlowtech.org/?p=1695
And from there you should be able to program your ATTiny so that it can run independently from your Arduino.
If you need to upload a .hex file to your ATTiny check the examples here:
arduinodiy.wordpress.com/2012/09/11/programming-hex-code-on-an-attiny85-with-the-arduino/
You can do that by using the Arduino as an ISP and then uploading the .hex file to the ATTiny using AVRdude.  You'll have to tweak the avrdude command line params a little specific to your situation.
I've just done programming of ATTiny13 using an Arduino Uno, a breadboard, and 6 jumper wires just fine.  Both uploading sketches I made in the Arduino IDE as well as using compiled .hex files that were part of an Instructables.com project I was building worked fine.
If you need to upload a program to a board and then use that board to mass-produce many identically programmed ATTiny without using an Arduino, adafruit as a solution, as does shop.myavr.com.  I can't justify the expense but they look really neat.  Using the Arduino as ISP for this of course works as well.
htlinux has a shield for Arduino's that is really inexpensive and comes with sockets for many Atmel pinouts:
www.htlinux.com/product/attiny-isp-shield/
I ordered one and it isn't here yet, it took a month to get the shipping notice, but it looks like a convenient all-in-one solution.  It still needs an Arduino to act as programmer.  It would meet your requirement of "removing all wiring" if you are find with a shield.
You could easily build your own shield with a proto board, too.
http://www.instructables.com/id/ATtiny-Programming-Shield-for-Arduino-1/?ALLSTEPS
I hope this helps!  I spent a while figuring out all this stuff, hopefully having many items in one answers helps the next person looking to program ATTiny with Arduino.  I'm working from OS X, it should be even easier from Windows or Linux.

Thanks for all the detailed info, I'm sure they will come in handy to many, but I'm actually past that point. I can successfully program tinys (45/85) with the setup you described. With the board as from topic I was instead hoping to remove all the extras and have a single socket 'plug and program' solution for this.

Sounds good.  So you want a stand-alone programmer?
As Majenko indicates, you can build one or just buy one.  I think you are looking for something like: learn.adafruit.com/mass-avr-isp-programmer

Micronucleus is a bootloader - in the same way that Optiboot is a bootloader used on the Uno. It provides the USB connection to program the chip.
Without it you can't do anything at all with that, since the USB port just plugs direct into the ATTiny chip. With no software on the chip the USB port doesn't do anything.  It's kind of a catch-22 situation - you need software on the chip in order to put software on the chip.
In essence Micronucleus turns the ATTiny into a kind of Mini Leonardo.
You need to first put Micronucleus on the chip (which you can do with an Arduino as an ICSP programmer) and then once that is installed you should be able to start using that little board with the chip to program it.
Since you're on a decent operating system there's no need for "drivers".

Crystal clear, thank you! So basically the socket on the board is not meant for the "end-product" MCU, but rather for the programming MCU... If that's the case, that sucks. Would some other board (Sparkfun's i.e.) instead provide a direct usb2tiny interface? EDIT: I will of course make do with what I have now, but the whole point was to remove all the wiring from the process and in this very moment I simply shrunk the Mega I was formerly using to program the tinys...

You want a board that has a built-in hardware programmer. It will have a second MCU on the board to do the programming. If there is no second MCU on the board then all you have is a fancy socket like this one.

Judging by the picture it's just a board.
If it is anything like this link on eBay (the first hit for "attiny programmer board") then this is the description:

Development board supporting chip:ATtiny13A / ATtiny25 / ATtiny45 / ATtiny85 etc

It supports the named chips, it doesn't have them on it.
I presume you are supposed to do a few things with it:

Purchase an ATtiny85 (or similar) chip
Install it on the board
Solder in an ICSP header onto the 8 pins on the right
Program the Micronucleus bootloader using a suitable other piece of hardware (like a ICSP programmer)
Then use the board as a ATtiny development board.

It's not responding because there is no chip there (unless you can see one on the other side). That's why it's cheap. You are buying a board, not a microcontroller on a board.
This other link on eBay for a slightly different board (for the same price) shows that the other side does not have a processor on it.


text:
Ways to implement touch sensitive surface?
I'm building a tic tac toe board for my kids where tapping on a plexiglass surface in any one of the 9 squares would light it up.
What are some ways I can pull off making each of those 9 squares touch sensitive?
Doesn't need to be anything fancy, but the kicker is that it can't be something attached directly to the plexiglass surface (as that'd obscure the LED light underneath).
Current thinking is buy a sheet of this pressure-sensitive conductive material and cut it in to squares, then somehow transfer pressure form the plexiglass down to the square on the bottom of the box, but I may be overcomplicating it.

Can the nine squares of plexiglas be configured as floating items, perhaps secured along only one edge? If so, you could place a pressure sensor under each of the nine pieces. The illumination need not be directly under the plexiglas and can instead be mounted to provide an edge-lit panel. You would want adjacent tiles to be painted black on the edge to prevent cross-illumination. There are a number of such sensors on Adafruit, but the more practical unit is seven dollars. You may be able to use the sheet stuff and create something that works.

If you have to have under-tile lighting, you could have through-hole standoffs that pass the force under a substrate to the conductive material. I think your question is more engineering than arduino, but it should be easily resolved.

Transparent touch sensitive surfaces are usually based on parasitic capacitance like on an iPhone.  While you can buy loose glass touch surfaces, it is difficult to use such devices if not already attached to an LCD.  The same is true for the much cheaper resistive touch surfaces like on a Newton.
If you are already using LEDs, I would suggest investigating using the LED to detect the light from the reflection of a finger.  I found people talking about this here, here and here.
I believe this is a still from a video that someone else made using this technique:

For your tic tac toe box I could see touching a location for X's or for O's.  Then touching 1 of 9 boxes you would want to place the symbol in.
Added later...
As @Gerben pointed out there are other options.  I like solving hardware problems in software.  And reversing the potential on an LED then sampling the voltage over time is a snap to implement on many modern embedded processors.
If you are open to hardware solutions, microchip.com makes a chip which projects an electrical field in front of a PCB for 3 dimensional gesture recognition.  However, the PCB layout is touchy.

Also, there are gesture sensors that (probably) use IR radiation to track movement.  Here's one that supposedly does X Y & Z as well as sense colors.  And it sounds like there is already an Arduino library written for some simple gestures. Looks like there's a YouTube video as well.

I'd probably use some dedicated IR reflective sensors, instead of using the leds you are driving. That would make things a bit easier, and probably more accurate.


text:
Is a 9v battery appropriate for a piezo and 1 LED?
I'm making a basic "door open" detector that, when a door is opened, it turns on an LED and then sounds an alarm via a piezo.
This is controlled via a 5v Adafruit Trinket.
Is a 9v battery the correct thing to power this with, if the goal is to change batteries as infrequently as possible?

Here's the code, incase that's relevant.
#include <elapsedMillis.h>
elapsedMillis timeElapsed;

const int switchPin = 2;
const int ledPin = 1;
const int piezoPin = 0;
const uint32_t openLength = 5 * 1000L; // X seconds
int notes[] = {862,294,730};

void setup() {
  pinMode(switchPin, INPUT);
  pinMode(ledPin, OUTPUT);
  pinMode(piezoPin, OUTPUT);
  digitalWrite(switchPin, HIGH);
}

void loop() {
  if(digitalRead(switchPin) == LOW){
    digitalWrite(ledPin, LOW);
    timeElapsed = 0;
  } else {
    digitalWrite(ledPin, HIGH);

    if (timeElapsed > openLength){
      for (int n = 0; n < 200 ; n++){
        beep(notes[random(0,2)]);

        if(digitalRead(switchPin) == LOW){ break; }
      }
    }
  }
}

void beep(int delayAmount)
{
  for (uint16_t t = 0; t < 30*1000/2; t += delayAmount)
  {
    digitalWrite(piezoPin,HIGH);
    delayMicroseconds(delayAmount);
    digitalWrite(piezoPin,LOW);
    delayMicroseconds(delayAmount);
  }
}

UPDATE: I had a 9V plugged in to this for about 3 days before it used all the power in 9V. Is that an issue w/ voltage on the battery (i.e. I should be using AA's instead of a 9V)? Or does that point largely to some other inefficiency w/ the code or hardware?

Not the problem, but your notes[random(0,2)] will only be 0 or 1 (2 is never reached). But you have 3 values in your array.

Also, a quick/dirty fix could be to put the switch between the battery and the microcontroller (if it can handle the current/voltage). Then your microcontroller will only power up when the switch is connected ;). This way you won't drain anything when the switch is off!

@Paul Bah! Of course! It delays the reaction time a few seconds, since the micro has to boot, but not a big deal in this case. Genius!

If you use an Arduino withouth bootloader (or modify it) you can get an extremely fast startup time. Microcontrollers won't need to set up an OS (Or well, the bootloader waits for code to be uploaded).

@Paul Actually I just realized that what you mentioned won't work for my use case. It's a magnetic contact switch and I need it to boot when the magnets disconnect...which I believe can only be detected via software. I could be wrong, though: https://www.adafruit.com/products/375

hmm, yea that makes sense. Maybe pull the reset pin low through it? It's on the icsp header. I'm not sure on the power usage, but it's basically made for that (:

@Paul As far as I can tell, the Trinket doesn't have that pin (https://learn.adafruit.com/introducing-trinket/pinouts) in the same way the Uno does.

The pin labeled "rst" is suspicious (: check it's voltage when it's on. Should be "high" and the device will reset when pulled to GND.

@Paul Yeah, I was under the impression that that pin just basically triggered the same thing as pressing the reset button, which would just cause it to reboot over and over. That being said, I wired it up and while it did "reset", it didn't reduce voltage.

Reset would be caused by connecting it to ground/GND. And if you keep it like that, it won't start until the pin is released.

A couple things to note:

Get rid of the PWR LED on the Trinket so it's not always drawing current.
Sleep the MCU whenever possible, only waking on interrupts.
Converting 9V to 5V with an LDO (in this case, the MIC5225) implies a 55% efficiency, max, which isn't great. But at least the LDO has a low ground current.

Also, ask yourself if you really need a micro for this task.
If you want a ballpark for runtime, find the capacity of your battery, estimate your current draw, and see what your upper bound on runtime is.

Added an update w/ more info...wondering if I have a battery issue or a hardware/software issue.

@Shpigford With regards to your update, it's both. 9V is not an ideal battery (and a few AAs have a lot more capacity), and you could be sleeping almost all the time. Again, ask yourself if you really need a micro to accomplish this task.

You can power the Trinket (ATTiny85) from as little as 2.7 volt. So you could power it by connecting 2 (or 3) AA-batteries directly to the 5V pin.
Using a 9V battery means you would "throw away" 4 of the 9 Volts to get 5Volt. So you'd waste almost half of the capacity of the battery.
Also a 9V battery only has around 500mAh, where as an AA battery has 2500mAh.

Added an update w/ more info...wondering if I have a battery issue or a hardware/software issue.

Like i said, AA have 5 times the capacity. So if you now get 3 days with a 9v battery, AA would give you only 15 days.

authors: ธนากร อุ่นเรือน


text:
How do I run a loop for a specific amount of time?
I currently have a for loop that loops 300 times and then moves on.
Instead, I'd like that loop to run for a specific number of minutes, instead.
Here's the current loop, for reference.
for(int i = 1; i<300; i++){
  if (kill() == true){ break; }

  strip.setPixelColor(1, strip.Color(random(100,255),random(100,255),random(100,255)));
  strip.show();

  tone(TONE, notes[random(0,3)]);
  delay(100);
}

Also, I have an RTC that's used elsewhere in the app, so real actual time is available for use if it makes sense to do that...though I'd love to know of a way to do it without an RTC module for future projects.

Here is an example that will run for 5 minutes. Note that the loop will begin executing anytime before the time limit is up, including 1 msec before; it can't cut-off something happening at the 5-minute mark, meaning the timing precision will be limited to the duration of the code in the loop.
Update: My first suggestion had a bug related to the 50-some-odd days roll-over period of the millis() clock. This one is more robust:
uint32_t period = 5 * 60000L;       // 5 minutes

for( uint32_t tStart = millis();  (millis()-tStart) < period;  ){
   doStuff();
   moreStuff();
}

This is based on "5 minutes from the start of the Arduino" though, right?

No, it's based on the time of entry to the loop. The for-loop's first clause calculates the ending time, and the second clause compares the current time at the top of each loop to that time.

Just tested and works wonderfully. Thanks!

To your update, does tQuit need to be defined somewhere?

Acch! That what I get for coding on the fly! tQuit is no longer used (the bug was related to tQuit). That should say 'period'. (fixed). Thanks for the catch.

Using this example:
http://playground.arduino.cc/Code/ElapsedMillis
You could try something like:
#include <elapsedMillis.h>

elapsedMillis timeElapsed;
unsigned int interval = 60000; //one minute in ms

while(timeElapsed < interval){
    //do stuff
}

Depending on how accurate you want to be, you might want to opt for a similar method using the RTC.

Nice, "These special variable types automatically increase as time elapses."

You can use a variable that is incremented each time you perform the loop, then you need only to change the loop from using a for to a while.
For example:
   int incremented_variable = 0;
   int incremented_value = 100;
   int max_value = 1000;

   while(incremented_variable < max_value){
   if (kill() == true){ break; }

   strip.setPixelColor(1, strip.Color(random(100,255),random(100,255),random(100,255)));
   strip.show();

   tone(TONE, notes[random(0,3)]);

   delay(100);
   incremented_variable = incremented_variable + incremented_value;
   }

EDIT: I have just read your update on the question.
You can then use a while with a boolean flag that help you to end the loop or if you prefer, you can keep track of the time by calling the method: millis().

But how does that equate to actual time? i.e. "This loop has been running for 5 minutes."

@Shpigford you can manage to control the time changing the incremented_value that now is set to 100 and the max_value that is set to 1000. As an advice run the script only once to see the time it takes to perform only one time than you set those value accordingly.


text:
Possible to condense this if statement?
I have this if statement:
if (now.hour() == 5 && now.minute() == 10 && now.second() == 0 && now.dayOfTheWeek() != 1 && now.dayOfTheWeek() != 7){

Is there a way to condense that for the purposes of saving on some bytes?
Ultimately trying to say "At 5:10 every weekday do X"

If this is using too much space then it's not the condition responsible, it's now.

Well, I was fine (just barely under) until I added the && now.dayOfTheWeek() != 1 && now.dayOfTheWeek() != 7.

In most libraries now.dayOfTheWeek() will actually calculate the day of the week, where at the other functions just load their value straight from the RTC chip. Calculating the day of the week is quite a bit of work. That would explain the jump in code size. The weird thing is that the RTC chip will actually keep track of the day of the week.

The following saves a couple of program bytes (but no RAM) when now is a structure with a byte called DayofWeek:
 if ((byte)(now.DayofWeek+249)>250) ...
   -vs-
 if ((now.DayofWeek != 1 && now.DayofWeek != 7)) ...

It might save slightly more than that in your case, where now.dayOfTheWeek() appears to be a function reference.  This technique will work if function now.dayOfTheWeek() returns a byte, that is, an unsigned char.  The technique depends on value 7+249 overflowing to zero in byte arithmetic when truncated to a byte, because 7+249 is 0 modulo 256.
The cast to byte [or uint8_t] of now.DayofWeek+249 is needed because of int promotion as Edgar Bonet pointed out.

This does not work. You have to cast the sum to uint8_t. Otherwise, per the rules of integral promotion, everything in the expression is evaluated as 16-bit signed ints.

@EdgarBonet, it does work.  Specifically, it gives correct results for now.DayofWeek values from 1 to 7.  Note, now.DayofWeek is declared as a byte (which is equivalent to uint8_t except for being easier to pronounce) so byte, not int, arithmetic is used.

No, it doesn't, and you obviously did not try. If DayofWeek is 7, then DayofWeek+249 is 256, and since 256>250, the test succeeds, while it shouldn't. Note: there is no such thing as “byte arithmetic” in C: the operation is done on ints. C.f. for example this CERT article on integer conversion rules and, more specifically, the section titled “Integer Promotions”.

@EdgarBonet, unfortunately my test printed out the result of assigning now.DayofWeek+249 to a byte – hence the value I expected – rather than the result of the comparison :( , See edit

Yes. The method now() Returns the current time as seconds since Jan 1 1970. Simply keep tract of all your time this way and you only need to test this one value.
The Arduino is not a good source of time over long periods.  Consider using an RTC (Real Time Clock) chip.  This Arduino page links to this page which talks about an RTC.  (I will leave it up to you to research any compatibility issues.)
Many RTCs contain a register set specifically designed to handle tasks such as you outlined above. For example, setting alarms off on weekdays only or on specific days of the month.
If absolute time is not important in your application I would try the following code outline.  Each test only has 2 operands:
// Turn on Arduino on Monday at the time task is to be performed.  Task
// should be performed at that time on Monday, Tuesday, ... Friday.
// Nothing should happen on Saturday & Sunday.  Then cycle repeats.

// Set time to zero.

// Count through days (0, 1, 2, ...).

// Wait each day until number-of-seconds is greater then seconds-in-a-day
// times the day number.

// If day number is 4 or less do activity.  Else skip activity.

// If day number is more than 6 set the day counter to 0 and set the time
// to zero.

If you want to start the Arduino at arbitrary times, set the initial Arduino clock value to the number of seconds from the time the activity would have been performed on Monday and initialize the day counter to the appropriate value.  For example if you started the Arduino on Tuesday 23 hours after the time the activity should have happened on Monday set the Arduino clock to 23 * 60 * 60 seconds and initialize the day counter to 2.  Of course you can calculate the initial day counter value using  = initial_number_of_seconds / 60 * 60 * 24.

I'm trying to get it to be true at a specific time every weekday, so I'm not sure how what you've said applies here.

Answer has been changed.  Consider an RTC.  Most RTCs contain a hardware solution for your situation.  If Arduino time drift is tolerable, use the code outline which only uses seconds in a week to drive events.