text:
Safe to power LED strip via ESP32 GPIO
I want to rewire a battery powered LED strip (as shown in the picture below) to power via an ESP32's GPIO pin. I have a ESP32 NodeMCU Development Board, powered via USB.
The LED strip has specified 3,2V/20mA for the 100 LEDs. It originally uses three AA batteries. From what I've gathered the ESP32 should have a max current output of 40mA.
Other than the LED strip, the ESP32 uses WiFi and addresses a DHT22.
The goal would be to turn the LEDs on/off via a GPIO, for example:
pinMode(4, OUTPUT);
digitalWrite(4, HIGH);
digitalWrite(4, LOW);

Would it be safe to power the LED strip via a GPIO pin?

Quick answer is probably not.  Why?  The numbers don't add up:

...3,2V/20mA for the 100 LEDs...

From here we find this comment:

Most common LED’s require a forward operating voltage of between
approximately 1.2 to 3.6 volts with a forward current rating of about
10 to 30 mA, with 12 to 20 mA being the most common range.

(Actually there are low current LED on the market now that only need about 3mA to operate.  Let us assume this is what you have for our calculations.)
So, given the above is true, and if your string of LEDs were all in parallel and had average specifications, we calculate the current and voltage of the string of 100 LEDs:
Current: 100 x 3mA = 300mA or 0.3 Amps
Voltage: About 2 Volts.

(Note: When designing with LED you should always refer to that LED's specification.  The above 30mA and 2 Volts is only a guess.)
So, even if your LEDs are of the low current type, you can see a string of 100 such LED in parallel exceeds the initial expected current for the entire string of 100 LEDs.
This assumes the LEDs are in parallel and the power source is a constant voltage.  What if the LEDs are in series?  Then you would need a constant current power source.  Again let's assume the individual LED specifications are 2 Volts and 3 mA.  Now the calculations might look like this:
Current: About 3mA.
Voltage: 100 x 2 Volts = 200 Volts

Obviously the voltage far exceeds the capability of three 1.5 Volt batteries.
Ah!  Bigclivedotcom gives us some insight in his 2017 youtube video about repairing several variations of low voltage LED strings. The 3 different strings he uses in his video address how these LED strings can be made such that different voltage and current sources can be used to power them.
In conclusion it is likely your string of LED will require more current to power then a GPIO pin who's maximum current rating is only 40mA can provide safely.

If you still want to use this string of LED @emma.makes I can extend the answer to describe a possible approach.  But it would involve soldering and adding resistors and using a voltage / current meter.  It would be simpler to buy loose LEDs and resistors.  But that wouldn't be as fun.

so you say the LED string in Question will no light with 3 AA batteries? but that is a working product not a DIY

@st2000 Thank you for your elaborate answer! I have no problems with soldering and adding resistors! I could also measure the current drawn by the LEDs when powered by the three AA batteries. One alternative I see, is to use the 3.3V power pin from the ESP32 and control power with a transistor via GPIO.

@Juraj, I have no doubt that the LED string in the question lights up using 3 x 1.5 Volt batteries.  But I don't know how the string of LEDs are connected.  Guessing, I might assume they are connected in what BigClive called a Z arrangement.  Possibly 50 parallel groups of 2 in series LEDs.  That might give us about 4 Volts at about 150mA (given that (again, this is a guess) each LED is rated 2 Volts at 3 mA).  Such a load is reasonable for 3 in series AA 1.5 Volt batteries.

@emma.makes, that's a great idea to control the string of 100 LED using a transistor.  But the ESP32 usually runs on 3.3 Volts.  Before going down this road consider testing if the string of 100 LEDs will light up using a 3.3 Volt power supply.  And while you are doing that consider testing the current to find the necessary capacity of the transistor you will be using to control the string of 100 LEDs.  (Can you switch voltages higher then 3.3 Volts such as the 3 x AA 1.5 volt batteries?  Yes.  You just need to take care how you design the circuit.)

@st2000 I just measured the voltage and current drawn from the 3xAA batteries. 76.6mA and 2.72V. From the Espressif datasheet I gathered, the ESP32 has a cumulative IO output current of max. 1200mA. Would it be safe to use a GPIO pin to power the LEDs, is the 3.3V power out pin preferable or would it be best to use an external power source and switch the LEDs with a transistor via GPIO? Thank you very much for you help!

That is an unexpectedly low current and voltage.  Three fresh AA batteries in series should be able to produce 4.5 volts.  And 76.6mA / 100 LEDs means that each LED is only consuming 0.7mA if they were all connected in parallel.  That is remarkably small.  The lowest current LEDs I could find are rated to operate correctly at 2mA.  Look closely at the wiring and check if the LED are arranged 50P or 25P2S.  Also, are not each 32ESP GPIO pin rated at 40mA max?  So sounds unsafe to drive this LED string directly from a ESP32 GPIO pin.

@st2000 that makes sense. thank you for your helpful comments!


text:
How to cut down size of imported DigiKeyboard library
I'm working on a project with a Digispark ATTiny85, that performs keystrokes using the DigisparkKeyboard library (https://github.com/digistump/DigisparkArduinoIntegration/tree/master/libraries/DigisparkKeyboard). Besides the DigiKeyboard, I also import EEPROM.h.
My own code is only about 150 lines, I've cut down the size following a number of online guides, trying to avoid larger data types and so on. The Digispark is limited to ~6kB and the imported DigiKeyboard library takes up a little more that 5.4kB. In total the compiled project takes up about 7kB, which exceeds the boards capacity.
From the DigiKeyboard library I only use DigiKeyboard.sendKeyStroke() and DigiKeyboard.print() (with about only ten different characters). So I assume there is a lot of unused code I could remove, but I don't know how to approach this. I use Visual Studio Code and PlatformIO.
How could I reduce the size of the used DigisparkKeyboard library?

Are you printing numbers or only fixed messages? In the later case, does it help if you use write() instead of print()?

Also, I have no experience with PlatformIO, but I guess you should be able to enable a “verbose” mode that shows you the full command used to call the compiler. Could you please check whether this command contains the option -flto?

Thanks @EdgarBonet! The compiler flag -O3 -flto didn't change a byte for me and I couldn't find any documentation on write(). However, I switched to .sendKeyStroke for all write operations from .print(), which shaved off about 3kB! and the code fits the board! If you formulate an answer, I'll gladly accept it!

I just noticed that the big issue here wasn't the inclusion of print(), but rather one single instance of print, where I did: DigiKeyboard.print("Time: "+String(round(runtime/1000)));. So I believe the large code was due to the inclusion of String().

Re “If you formulate an answer, I'll gladly accept it!”: Well, actually you found your solution yourself! In such a case, the recommended practice it to post and accept your own answer.

With input from @EdgarBonet, I looked into the functions used and it turned out that the String() function, I used once in my code, takes up about 3kB of space in the compiled program.
I ended up removing the line with String() and kept the imported DigiKeyboard library as it is.

The compiler/linker will remove unused functions/methods automatically, so I doubt you can save memory by removing unused functions/methods yourself.
However, you could possibly gain by:

Removing the calls of check functions/methods when you know the result will be always false, true, or always the same number, string or data type in general.
Removing (parts of) functions/methods which are related to physical or logical functionality you never use. Like e.g. if, case statements that will never apply).
Prevent using an entire class (e.g. String) (see second comment of Emma Makes below).

Thank you for the feedback! I wasn't aware that unused functions and methods aren't included anyways! I was able to shave off about 3kB by switching from .print() to .sendKeyStroke! I'll keep the other suggestions in mind for future issues!

I would need to edit the comment, but it's too late to do so. The reduced size was not due to the change from print() to sendKeyStroke(), rather the fact that I didn't use String(), which I previously used in the print() function call.

That's also indeed a good way to reduce size, to preventing using a complete class (String in your case). I will add it to my answer

source: Stack Exchange

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

sort: votes


text:
Safe to solder a slide switch to unused GPIO pins?
I have a Digispark Rev.3 Kickstarter with ATTiny85 (see pinout below) and a three pin slide switch (see example below). I want to use the slide switch to control a task running on the Digispark, with the example code below.
The center pin of the slide switch will be connected to GND, one pin will be soldered to pin 2 on the Digispark (pinMode(2, INPUT_PULLUP);) and the remaining pin will be unused.
To install the switch, I want to have the center pin of the switch go through P3 on the pinout, one pin through P2 (which will be addressed in the code) and the remaining pin through P4. This means, P3 will be soldered to GND and depending on the switches position, P2 or P4 will connect to GND as well.
Could these connections between P2, P3 or P4 and GND interfere with the functionality or damage the Digispark?
int switchPos;
void setup() {
  pinMode(2, INPUT_PULLUP);
}

void loop() {
  switchPos = digitalRead(2);
  if (sensorVal == HIGH) {
    runCode();
  } else {
    delay(1000);
  }
}

Yes, you will lose the USB connection, since PB3 and PB4 are used for the USB communication. Normally you wouldn't solder a component directly onto a board if it doesn't fit with all pins. Instead you would use wires or a breakout PCB to do the job.
If you really want to to that and you don't need any of the other pins, then you can use PB0 and PB1. Set PB1 to OUTPUT LOW and PB0 as input. The OUTPUT LOW is basically the same as ground and configuring a pin as INPUT will make it high resistance, so it doesn't interfere with the circuit.

Thank you for the feedback! By USB connection loss you mean via the pins 3 and 4 or in general? Because I am using the USB male plug to emulate a keyboard on this project. As for your suggestion about the pins 0 and 1, you'd say I could solder the switch like so https://i.imgur.com/67Uhvu2.png and use the OUTPUT LOW on pin 1 as an alternative to ground, correct?

Pins PB3 and 4 are the data pins for the USB connection (emulated via software). When you want to send any data over USB you cannot use these. And yes, thats the wiring that I suggested (besides using wires)

Thank you for the feedback and your patience @chrisl! I've just checked the schematics of the Digispark and I understand how it makes sense, that the USB connection is impaired if I meddle with those pins.

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


text:
Rp2040 How to signal the second core from first core as an indicator to do something
Im new to dual core programming and i do not know the best practices yet. In my current project, i would like the second core to only do something after it is being told by the first core.
The approach i am using somewhat of a brute force is something like this:
bool indicator = false;
int a,b;

void loop () { // core1
  if(indicator == false){  //check if core2 is still processing
     a=random(100);
     b=random(100);
     indicator = true;
  }
}

void loop1(){ //core2
  if(indicator == true){
     int sum = a+b;
     Serial.println(sum);
     indicator == false;
  }
}

this is just a simplified idea of how my code is going to be. Are there better ways of going about this? In general i want to tell core2 from core1 that it needs to start/stop doing something.

What you have created there is called a semaphore.
In multi-threaded (or multi-core) programming there are two important signalling concepts:

Mutex - This is an object of some form that is used to allow access to a shared resource by only one core or thread at a time.  A thread tries to "lock" a mutex before using a resource.  A mutex can only be "locked" by one thread at a time, and if the mutex is already locked by another thread it can either block (aka a "spinlock") waiting for the mutex to be unlocked, or it can fail gracefully and try again later.
Semaphore - This is a simple flag that is used for one thread to tell another thread that something has happened or that it should do something. It is typically set by one thread then read and cleared by the other thread.

As I mentioned before, a semaphore is what you have created, and a simple boolean value is the most basic semaphore there is. Note, though, that you should really have the variable as volatile to prevent the compiler optimizing it away.
The RP2040 SDK has some functions built in for allowing the cores to communicate, including a "lockout" facility allowing one core to tell the other to stall until such time as it should start processing again, and a FIFO to allow the asynchronous passing of data from one core to the other.

Even after two days im still having troubles grasping the concepts. Which one should i use? both mutex and semaphore seems to be able to do the job, but which is much proper?

Also , in my example i just used basic datatypes. is it possible to lock a class data type.

@DrakeJest A mutex is used when you want to share a resource. For example if you have two threads that both want to print to serial. One thread "locks" the serial port mutex, prints what it wants, then releases it again. The other thread waits until it is able to lock the mutex itself before printing. That way you keep the serial data separate and don't end up with a garbled mess.

A semaphore is used to just inform another thread that something has happened. Maybe thread 1 has filled up a buffer with data and thread 2 should grab and process that data. Or maybe thread 1 has detected something happen on a sensor and wants to tell thread 2 that it happened.

And yes, you can use anything you like as a semaphore or mutex. You rarely want more than a simple bool or maybe an int. If you have a class you'll just be using a bool or int inside that class as the semaphore/mutex.


text:
Rp2040 dual core example sketches
So i have a rp2040 board, and i could not find a dual core example codes. The closest i could find is the scheduler library example given to me by the IDE
/*
 Multiple Blinks

 Demonstrates the use of the Scheduler library for the boards:

 - Arduino Nano 33 BLE, or
 - Arduino Portenta H7, or
 - Arduino Nano RP2040 Connect

 Hardware required :
 * None (LEDs are already conencted to RGB LED)

 ATTENTION: LEDs polarity is reversed (so loop3 will turn the LED off by writing 1)

 created 8 Oct 2012
 by Cristian Maglie
 Modified by
 Scott Fitzgerald 19 Oct 2012

 This example code is in the public domain

 http://www.arduino.cc/en/Tutorial/MultipleBlinks
*/

// Include Scheduler since we want to manage multiple tasks.
#include <Scheduler.h>

// On Nano RP2040 Connect, RGB leds are connected to the wifi module
// The user APIs are the same, but we can't convert to int, so use defines
#if defined(ARDUINO_NANO_RP2040_CONNECT)

#include "WiFiNINA.h"
#define led1  LEDR
#define led2  LEDG
#define led3  LEDB

// On Nicla Sense ME, RGB leds are connected via an I2C module
// The user APIs are the same, but we can't convert to int, so use defines
#elif defined(ARDUINO_NICLA)

#include "Nicla_System.h"
#define led1  LEDR
#define led2  LEDG
#define led3  LEDB

#else

int led1 = LEDR;
int led2 = LEDG;
int led3 = LEDB;

#endif

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

  // Setup the 3 pins as OUTPUT
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);

  // Add "loop2" and "loop3" to scheduling.
  // "loop" is always started by default.
  Scheduler.startLoop(loop2);
  Scheduler.startLoop(loop3);
}

// Task no.1: blink LED with 1 second delay.
void loop() {
  digitalWrite(led1, HIGH);

  // IMPORTANT:
  // When multiple tasks are running 'delay' passes control to
  // other tasks while waiting and guarantees they get executed.
  delay(1000);

  digitalWrite(led1, LOW);
  delay(1000);
}

// Task no.2: blink LED with 0.1 second delay.
void loop2() {
  digitalWrite(led2, HIGH);
  delay(100);
  digitalWrite(led2, LOW);
  delay(100);
}

// Task no.3: accept commands from Serial port
// '0' turns off LED
// '1' turns on LED
void loop3() {
  if (Serial.available()) {
    char c = Serial.read();
    if (c == '0') {
      digitalWrite(led3, LOW);
      Serial.println("Led turned off!");
    }
    if (c == '1') {
      digitalWrite(led3, HIGH);
      Serial.println("Led turned on!");
    }
  }

  // IMPORTANT:
  // We must call 'yield' at a regular basis to pass
  // control to other tasks.
  yield();
}

but i do not think its using the second core of the rp2040. Does anybody have an example codes? because im really lost how to do it

Just launch a new main() with multicore_launch_core1().

@Majenko So I have 3 functions now setup() , loop() , and main() , ? where do i put the multicore_launch_core1()

The RP2040 SDK is your friend: https://raspberrypi.github.io/pico-sdk-doxygen/

And: https://raspberrypi.github.io/pico-sdk-doxygen/group__pico__multicore.html#multicore_example

@Majenko ooooh... You can use all sdk function in arduino IDE?? I did not know you can do that.

Yep. The Arduino core is merely a wrapper around the SDK.

Note: This information is about the pure "Arduino" core, not the "MBED" core. The MBED core gets in the way of using the RP2040 SDK, so install the pure bare metal core from here.
By default the second core isn't doing anything.
But you can run anything you want on it directly. No need for any libraries.  You use the function multicore_launch_core1(func) to start a function on that core. You could make it Arduino-like by writing a wrapper function, such as this code:

void setup2() {
    pinMode(1, OUTPUT);
}

void loop2() {
    digitalWrite(1, HIGH);
    delay(750);
    digitalWrite(1, LOW);
    delay(750);
}

void main2() {
    setup2();
    while (1) {
        loop2();
    }
}

void setup() {
    multicore_launch_core1(main2);
    pinMode(0, OUTPUT);
}

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

The code throws an error in arduino IDE. sketch_nov05a:21:5: error: 'multicore_launch_core1' was not declared in this scope

@DrakeJest Sure you have the right board selected, and the right core installed? I use that function all the time without needing to do anything.

I double checked, and yes .  I am using Arduino Mbed OS RP2040 Boards - Raspberry pi pico

@DrakeJest Ah, sounds like you're not using the Raspberry Pi core but the MBED core. I've never used that. Stick to the proper Pi one.

@DrakeJest This is the one I use: https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json

What is the name of the pi core? The only one showing up inside the board manager is  that one, it even says its made by arduino, so i think this is the official one

Got it to compile now ! And wow there so many boards included in this one, can even change core clock and stuff. Whats up with that Arduino Mbed Os then?

@DrakeJest The problem with the MBED one is it runs MBED. That's an operating system (like FreeRTOS) which sits between your code and the hardware.

Oh thats a bummer, so i loose access to the scheduler library then. are there similar alternatives? I guess i will have to code my project the hard way then

The scheduler library is a crutch. You don't need crutches.

You are right, if i want an OS might as well go for a full-blown raspberry pi 4/zero. Thank you for your help Majenko, Ill get right to starting my project. Have a nice day


text:
How to smooth transition to another color NEOPIXELS
I am working on a led strip project and was looking for ways to smooth transition from color to another. Problem is my current method is not so good.
#include <Adafruit_NeoPixel.h>

#define LED_PIN     25
#define LED_COUNT  60
#define BRIGHTNESS 50

Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRBW + NEO_KHZ800);

bool isFading = false;
unsigned long startTime;
uint32_t fadeDuration = 1000;          //fade for 3seconds
uint32_t startingColor = 0x00ffff00;      // W = 0x00 R=0xFF G=0xFF B=0x00  yellow
uint32_t targetColor = 0x008f00ff;        // W = 0x00 R=0x8F G=0x00 B=0xff  violet

void setup() {

  pinMode(25, OUTPUT);
  digitalWrite(25, LOW);

    Serial.begin(9600);
  while (!Serial);
  Serial.println("Starting");

  strip.begin();
  strip.show();
  strip.setBrightness(BRIGHTNESS);

  for (int i = 0; i < strip.numPixels(); i++)
    strip.setPixelColor(i, startingColor);
  strip.show();

  delay(5000); // wait 5 seconds before fading

  isFading = true;
  startTime = millis();
}

void loop() {

  if (isFading) { //Fade from yellow to violet in 3 seconds
    for (int i = 0; i < strip.numPixels(); i++)
      strip.setPixelColor(i, getFadeColor(startingColor, targetColor, startTime, startTime + fadeDuration));
    strip.show();
  }

  if ( millis() >= startTime + fadeDuration){; // i intentionally did not include an overflow check to keep it simple
  Serial.println("Fade ended");
  isFading = false;
  }
}

uint32_t getFadeColor(uint32_t startColor, uint32_t endColor, unsigned long timeStart, unsigned long timeEnd) {

  uint8_t startWhite  = (startColor >> 24) & 0xff;
  uint8_t startRed    = (startColor >> 16) & 0xff;
  uint8_t startGreen  = (startColor >> 8 ) & 0xff;
  uint8_t startBlue    =  startColor & 0xff;

  uint8_t endWhite    = (endColor >> 24) & 0xff;
  uint8_t endRed      = (endColor >> 16) & 0xff;
  uint8_t endGreen    = (endColor >> 8) & 0xff;
  uint8_t endBlue      = endColor & 0xff;

  unsigned long timeNow = millis();

  uint8_t mapTime = map(timeNow, timeStart, timeEnd, 0, 255);
  uint8_t white   = map(mapTime, 0, 255, startWhite, endWhite);
  uint8_t red     = map(mapTime, 0, 255, startRed, endRed);
  uint8_t green   = map(mapTime, 0, 255, startGreen, endGreen);
  uint8_t blue    = map(mapTime, 0, 255, startBlue, endBlue);

  Serial.print("Time: \t");
  Serial.print(mapTime);
  Serial.print('\t');
  Serial.print("Color now: \t");
  Serial.println(strip.Color(  red,   green,   blue, white),HEX);

  return strip.Color(  red,   green,   blue, white);

}

The problem im having with this code is visually it would seem that it goes from
Yellow -> White -> violet
and it does not look like a proper transition. I have tried with other colors, and it always seems to pass throught the white color
Are there color theories i can apply for the transition? if you can show me an example sketches on how to do the transition that would also be great.

That happens if you directly fade between complementary colors. After half of the duration the components will be somewhere half brightness. So that looks white. How do you want it to fade between them?

Im not really sure how i want it, i guess  something that will go through the color wheel until the destination color. Are there other options?

@DrakeJest: If you want to go around (rather than across) the color wheel, you should interpolate in the HSV, rather than the RGB color space.

something that will go through the color wheel until the destination color

For that the FastLED library has the function ColorHSV(), which can be used to define colors using the HSV color space. It stands for Hue, Saturation and Value (or brightness). Hue is the value representing the position in the color wheel, so that is what you want to change.
Instead of
strip.Color(  red,   green,   blue, white);

use
strip.ColorHSV( hue, saturation, brightness );

and change hue over time with the algorithm, that you already programmed. When saturation and brightness stay the same the LEDs will cycle through the color wheel.
Note: The library provides the way from HSV to RGB color (with the above function), but it does not provide a way back. For getting back HSV from an RGB color you would need to write your own conversion function and I don't know how to do that. Though at the current state you don't need it.

I have looked into the colorHSV() function, so it returns the 32bit WRGB to be used in setPixelColor(). What i have is the starting RGB and the endpoint RGB, and i need to convert them to starting hue and enpoint hue. You mentioned that i do not need a function to convert RGB to HSV, so how do i get my start and end hue values?

My point was that the library doesn't have a function for going that way. I would suggest that you use an online color picker too to determine the HSV values and then just using them in the code (so that you don't use RGB values of your colors in your code). A short google search gave me this one. Input your RGB values, press Enter and then copy the HSV values.

By the way: When you look at the image of the HSV representation cylinder in the HSL and HSV wikipedia article you can see why you got white with your code. You moved at a straight line from one side of the cylinder to the other, passing the white in the middle in the process. Thats a good visual representation to help you understand the color space

Unfortunately my color source are generated by the code and will always output a RGB value. So i have two options rewrite a portion of my code and convert everything to HSV or use formulas like the one discussed here. i will have to think about it which is more compatible of what other things i might add to this project :)

there's a lot of rgb to hsl stand-alone snippets floating around.


text:
Reverse engineering an i2c signal
I have an i2c device that i would like to rreverse engineer. Using the oringal master of the device here is a snapshot from the logical analyzer

I would like to replace the orginal master of the device with an arduino, the device has an interrupt pin that when detected it will do the trasaction above.
So far what i have figuerd out is the address is 0x53 (the first byte). I have also figured out by interactive with the device that the second,third, and last byte are data from the slave device.
How do i write an arduino code to simulate this transaction? Here is the code i have written and the response i got is not quite the same
#include <Wire.h>

void setup() {
  Wire.begin();        // join i2c bus (address optional for master)
  Wire. setClock(100000)
  Serial.begin(9600);  // start serial for output
}

void loop() {
  Wire.requestFrom(0x53, 6);    // request 6 bytes from slave device #8

  while (Wire.available()) { // slave may send less than requested
    char c = Wire.read(); // receive a byte as character
    Serial.print(c);         // print the character
  }

  delay(500);
}

Are you sure that you should get the same answer everytime you request data from the device? And what happens with the real master before that read transaction? Often I2C devices work like "master write to tell the device what data you want to have --> master read to actually get that data". So if there is a master write cycle before the read transaction that can be important. Before trying to recreate the master with an Arduino I would try to understand the protocol. There is no easy way around that. Depending on what you expect from the device search for patterns in the data stream.

@chrisl i can assure that there is no write cycle, before each transaction or even the very first transaction during power-up. That is not difficult to check in a logic analyzer. And yes i have recorded all the possible oputs of the device( there are 11). Its just keeps reapting with the only different thing is the second,third, and last byte depending how you interact with the device. How do i add a bit of delay between each byte?

For introducing a delay you would need to change the Wire library. Though I doubt that this would help. The delay is introduced by the master (since if the slave would do the clock stretching here the Arduino couldn't overcome this). Why would the slave need it? It perfectly works in the communication. In I2C when the slave is too slow for the master the communication normally totally breaks apart, mostly resulting in a blocked I2C bus. Also you can see in the first picture, that the slave is releasing SDA line right after the acknowledgement pulse. That suggest, that it isn't too slow.

Customised Protocol
As has been mentioned in the comments, it may be that the controller and target are communicating using a customised protocol for which you will need to modify the Wire library and/or the TWI library.
Modifying the TWI library is not easy because it uses a very convoluted mixture of ISR code and non-ISR polling code.
I've re-written the TWI library so that you can use standard burst-read and burst-write protocols in either ISR mode or polling mode, or build your own protocol using building-block functions. It uses the watchdog timer to detect timeouts when the bus freezes due to an error.
Terminology
The terminology of my TWI library conforms to NXP Semiconductors recently released v7 of the I2C-bus specification which has:

Updated the terms "master/slave" to "controller/target" throughout to align with MIPI I3C specification and NXP's Inclusive Language Project


text:
Reply from the SIM800l module is being cut short
I have a sim800l module connected to the Rpi pico hardware UART
/*
SIM800       RPi Pico
5v           *External 2A 5v supply*
GND          GND
VDD          3v3
TXD          GP1
RXD          GP0
*/

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

  while (!Serial)
    ;

  Serial1.begin(9600);

  Serial.print("Initializing");
  delay(1000);
  Serial.print(".");
  delay(1000);
  Serial.print(".");
  delay(1000);
  Serial.println(".");

  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, HIGH);

  Serial1.println("AT"); //Once the handshake test is successful, it will back to OK
  updateSerial();
  delay(3000);

  Serial1.println("ATI"); //Returns the module name and revision.
  updateSerial();
  delay(3000);

  Serial1.println("AT+CCID"); //Read SIM information to confirm whether the SIM is plugged
  updateSerial();
  delay(3000);

  Serial1.println("AT+COPS?"); //Checks which network you are connected to
  updateSerial();
  delay(3000);

  Serial1.println("AT+COPS=?"); //Returns the list of operators present in the network.
  updateSerial();
  delay(3000);

}

void loop()
{
  updateSerial();
}

void updateSerial()
{
  delay(200);
  while (Serial.available())
  {
    Serial1.write(Serial.read());//Forward what Serial received to Software Serial Port
  }
  while (Serial1.available())
  {
    Serial.write(Serial1.read());//Forward what Software Serial received to Serial Port
  }

}

terminal response
AT
OK
ATI
SIM800 R14.18

OK
AT+CCID
XXXXXXXXXXXXXXXXXXXX
AT+COPS?
+COPS: 0,0,"Vodaa TelAT+COPS=?
+COPS: (2,"Vodaa Telecom","Ver

From what i know so far the SIM800L always ends its response with an "OK" but there are some commands that are cut short and not end with OK.  such as AT+CDID and AT+COPS. I do not know if the problem is with the pico or with sim800l. The sim800l seems to be working fine so i suspect its with the pico but if so, it might be a problem with the internal libraries which is beyond me.  To supoort that theory the number of characters that is being cut is about 20 characters, so it might be a setting i have to adjust

hint:   always ends its response with an "OK" ... there is more than OK in the response ... count the number of characters that are actually received

the 115200 baud is slow. there are gaps between bytes so while (Serial1.available()) can end before the complete response is read

@jsotola im sorry i dont get it.. I counted how many serial1.read() pe command.  AT=9 character, ATI = 27 , AT+CCID=31, AT+COPS? = 31,  AT+COPS=? is 9 followed by a long pause then responded with another 31.  looks like 31 is the limit,

@Juraj i dont think i can go any higher than that, i tried to explore that end thinking it was a baud rate issue, according to this thread 115200 is the highest it can go

I didn't suggest higher baud rate but proper reading of the input

Took me quite a while, but upon reading the pico's documentation

The size of the receive FIFO may also be adjusted from the default 32
bytes by using the setFIFOSize call prior to calling begin()
Serial1.setFIFOSize(128);
Serial1.begin(baud);

settinng it to a much higher value like 256 solves the problem


text:
How to set SIM800L to save messages to memory and reading them
I have so many commands that i need help to setup my SIM800L module. Tutorials i have seen so far involves the messages going directly to the mCu this is problematic for me because if the mCU is currently bussy doing something as of the moment and multiple messages arrive. The buffer would fill up without getting read.
I would like my program logic to be like this:
Wait for new messages/ do some other stuff -> check inbox -> if new message -> read message -> delete read messages-> repeat...
Would this be possible? Im having a hard time finding the commands for these actions.
I know that setting how messages are handled are set by AT+CNMI= i could not understand the datasheet. I have also came across this command : AT+CMGL="ALL" and AT+CMGD=X which deletes
the read message.
AT+CMGL= ALL seems dangerous because if too much pending message is present it would overflow the buffer i set in my arduino (256 bytes). Is there a command thats just 1 at a time?
so the sequence of commands would be:
//setup:
AT
AT+CMGF=1
AT+????? //tells the module to save incoming to memory

//reading:
AT+CMGL="XXX" //read one unread if present
AT+CMGD=??    //CMGL should return a number identifier which i can then use for delete
//do something else or loop though all unread messages.

Can anyone help me sort this out?


text:
How to save the current SPI settings with out have a global variable keeping track?
I am making a function for one of my devices, my device needs a particular SPI setting. I was hoping to save the current setting of the SPI class into some variable, load in the required setting, do a transfer, and after that load back the old setting.
I know there is an object for the SPISettings, but i dont know how to pull the current settings without me having to create a global variable that keeps track of it.
void sendSPI(){
 SPISettings oldSettings = ??? ;   //save old SPI Settings
 SPISettings mySettings(14000000, MSBFIRST, SPI_MODE0);

 digitalWrite(CSPIN,LOW);
 SPI.beginTransaction(mySettings); //load in new SPI Settings
 SPI.transfer(0x0);
 digitalWrite(CSPIN,HIGH);

 SPI.beginTransaction(mySettings); //Revert to old SPI Settings
}

What about trying static?

@st2000 the problem is i do not know the function for access the current settings

every library which uses SPI should start the transaction with the setting for the specific device. so you don't have to restore the settings. what are your other devices?

I'm going to assume you know what you want (but this may be a case where there are better ways to do what you want in C++ when considering the problem from a higher level perspective). In your class, write a method that will return ("expose") the desired variables.  Then, each time you instantiate your class, call those functions to return the desired values.

"every library which uses SPI should start the transaction with the setting for the specific device. ... "  I've had cases @Juraj where the I2C device was "unconventional" and had to use unusual settings.  But have to admit, I've never tried mixing these w/more conventional I2C devices on the same bus.

@st2000 "Once you have your SPI parameters, use SPI.beginTransaction() to begin using the SPI port." from https://docs.arduino.cc/learn/communication/spi?#serial-peripheral-interface-spi

https://github.com/arduino/ArduinoCore-avr/blob/master/libraries/SPI/src/SPI.h#L203 you can make a backup for SPSR and SPCR (but it kinda expects you are using clasic AVR Arduino)

@Juraj im using adafruit libraries, and they have their own spi/i2c classes kind of a rats nest, im just making sure i wont inadvertently bug out their libraries. It also assures that my function is compatible with libraries not following conventions

How to save the current SPI settings with out have a global variable keeping track? is a somewhat misleading question because you said  i do not know the function for access the current settings ... when you figure out how to read the current settings, then save them in EEPROM

the adafruit libraries have software (bit-banging) SPI as an option, but you don't use software SPI pins for multiple devices. If you use hardware SPI they relay on the SPI library and use beginTransaction


text:
VL6180X returning to its default i2c address after shutdown
According to this thread the VL6180X after changing the i2c address the new address should persist after a power down. but when i changed mine it came back to its default address at 0x29. Here is the code i used to change the address
#include <Wire.h>
#include "Adafruit_VL6180X.h"

Adafruit_VL6180X vl = Adafruit_VL6180X();

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

  // wait for serial port to open on native usb devices
  while (!Serial) {
    delay(1);
  }

  Wire.setSDA(0);
  Wire.setSCL(1);
  Wire.begin();

  Serial.println("Adafruit VL6180x test!");
  if (! vl.begin()) {
    Serial.println("Failed to find sensor");
    while (1);
  }
  Serial.println("Sensor found!");
  vl.setAddress(0x35);
}

After running this code i then ran a i2c scanner code which indeed showed the new 0x35 address but when i re-plugged the power it went back to 0x29. Am i doing something wrong here? Or the thread is just wrong ?

The data sheet and the thread agree with what you are seeing...the device will always power up at the default address, but you can change the address while it is powered up.  The Pololu link is explicit about this: "It can be changed to any other value by writing one of the device configuration registers, but the new address only applies until the sensor is reset or powered off." I don't see anything in the thread that says that you can change the default value when first powered up.


text:
How do I control a servo with python through an Arduino
I'm trying to make it so I can control 2 servos with data that I get from a python script that tracks my face.
I have found 2 libraries that do this:pySerial and pyfirmata.
Is one superior to the other one, are there more libraries, or should approach things differently.

They're different things: one is a specific interface to Arduino Firmata, one is a generic serial port library. "Superior" depends on context, usage, etc. Either would work perfectly fine, each would require a different approach.

Thank you so much

I'd say pyFirmata can work but controling servos ... NOPE!
use pyserial and add the code

Did you see Dave Newton's comment below the question?

no but thanks i needed it


text:
Can you use multiple arduinos to run two programs simultaneously?
If I want to run 2 different programs simultaneously, can I do this with 2 arduinos wired together?
Context: I’m building a robot that will balance with reaction wheels while doing other tasks. I would like to have the balancing program running continuously in the background while the servos that control the robot are moving. Can I accomplish this by having a 2nd arduino running the balancing while the 1st arduino controls the rest of the robot?

yes, yes, and yes ..... good luck with your project

You can go with Teensy 4.0 - it's so powerfull, it should be able to handle everything (if it's written correctly). Or maybe Raspberry pi pico with two cores - but I'm not sure if the Arduino core supports it (mbed might be: https://forum.arduino.cc/t/multicore-on-raspberry-pi-pico/858908/15 )

Why do you think a single arduino is not enough to run a sketch with a combined program? You just need non-blocking code.

The answer is yes, you can run two programs one in each Arduino. There are no restrictions on doing this. There are probably millions of Arduinos currently operating without any interaction with each other. In your robot they would need some sort of communications between them. This is if there is to be any type of interaction between them. I do not know your skill set but it may be  possibly do it with one with some tight code.


text:
MC33926 Brushed Motor Driver (Shield/Carrier)
How can I use a MC33926 Motor Driver like it is offered for Arduino to drive forwards, backwards with a PWM and a direction control.
The problem is that the MC33926 has Inputs IN1 and IN2 and not PWM and DIR as usual. How can IN1 and IN2 be directly used with a Arduino. Such as it is done in the ArduMower project.
I'm also wondering under which conditions this is controller is energy efficient? If the load has a flywheel effect (e.g. high RPM mower disk) reducing RPM would waste energy?
I know there are different shields that have logic to drive the inputs with PWM and DIR, but the ArduMower PCB 1.4 decided to hook it up directly. Here is a hardware solution by pololu (I wish i would understand these two NAND gates and the Q2, but that's another problem):

https://www.pololu.com/product/1213/pictures

I have figured this so far:

If the PWM frequency is too low, the load-free power consumption (100% PWM 200mA) of the
motors increases(!) rapidly when driving slowly, e.g. 33% to 1A.
From a certain PWM frequency (>2kHz), the power consumption normalizes and driving more slowly requires less power.
MC33936 has IN1 and IN2, which are normally connected with IN1 = LOW and
IN2 = PWM or IN1 = PWM and IN2 = LOW (not good for most MCs)
Alternatively you can use IN1 = PWM and IN2 = LOW / HIGH BUT you must INVERT the PWM SIGNAL when running reverse, i.e. IN1 = PWM and IN2 = LOW or reverse IN1 = ~PWM (inverted PWM) and IN2 = HIGH. Otherwise you start driving at 0 PWM with 100% motor power. This is quite tricky, too.
MC33936 has no freewheel (except if ENABLE = LOW) and brakes the
motor to 0 when IN1 = IN2
MC33936 is a braking motor controller that actively sets the output RPM.
of the motor according to PWM.


text:
Using index of to search for multiple characters
In my Arduino project, a string will be received. I understand using .indexof to find the placement of a certain character in the string. My problem is that I need to find the first occurrence of any letter A-Z and haven't found any resources regarding using or  statements in an .indexof aka string.indexof("a" || "b" ....).
Is this something that is not possible using indexof functions and if so is there any function that I can use to solve this! Thanks!

index is only for one comparison at a time. there's a built-in isupper(char): http://www.cplusplus.com/reference/cctype/isupper/. you can find many chars at once using https://www.cplusplus.com/reference/cstring/strcspn/

You can also use a for loop that checks the value of i (or whatever variable) and then depending on what i is it runs indexof with different letters.

Here are two functions that I hope help in your endeavours. You can supply either a String or a char array and you should get the first position of an alpha character. Returns -1 if not present.
See https://www.arduino.cc/reference/en/language/functions/characters/isalpha/
Update:
Thanks to great comments from Edgar & Mat I have updated the functions with best practise and cost improvements.
int alphaPos(const char* str)
{
  for (int i = 0; str[i] !=0 ; ++i) {
    if (isAlpha(str[i]))
    {
      return i;
    }
  }

  return -1;
}

int alphaPos(const String& str)
{
  return alphaPos(str.c_str());
}

/*
    Usage:

    String bobble = "&&&88434a";
    int x = alphaPos(bobble);

    if (x != -1)
    {
      ...x has the position in the string
    }
    else
    {
     ...There is no alpha char present.
    }
*/

I suggest passing a const reference to the second overload.

@EdgarBonet, I admit I have much to learn so ask honestly what the benefit is?

@voidPointer: it indicates to the caller that the function will not modify the passed String. It is good practice. Also you can avoid the strlen call (which doubles the cost of the function) - use str[i] != 0 in the loop condition instead.

@Mat. Thanks. That strlen tip is pretty cool and will help others too.

To elaborate on Mat's comment: if you wan to get an idea of why it is considered good practice, see Const Correctness on the isocpp.org wiki.

@EdgarBonet That is a good read. Thanks.


text:
Why do I get this error when uploading a sketch on my arduino uno?
I have two Arduino Unos. On the first I can upload my sketch wittout any error, but with my second Arduino I always get this error, altough Im using the same settings:
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0xbf

What I tried:

different Usb Port
different Usb Cable
swapped the MCU on the board
restarted VSCODE

I also have this error sometimes, especially when I'm switching boards or usb port and forget to reselect  the device at Tools > Port.


text:
Using Arduino Click shield with NDIR Click CO2
I am trying to use  (NDIR CO2 sensor Mikroelectronika) with Arduino Mega 2560 utilizing the Click shield.
Mikroelectronika provides libraries for their platform (likely proprietary), hence i have no idea how to manage to do this with arduino.
Here is the code I tried from the library page.
void application_init ( void )
{
log_cfg_t log_cfg;
ndirco2_cfg_t cfg;

//  Logger initialization.

log_cfg.level = LOG_LEVEL_DEBUG;
LOG_MAP_USB_UART( log_cfg );
log_init( &logger, &log_cfg );
log_info( &logger, "---- Application Init ----" );

//  Click initialization.

ndirco2_cfg_setup( &cfg );
NDIRCO2_MAP_MIKROBUS( cfg, MIKROBUS_1 );
ndirco2_init( &ndirco2, &cfg );

Delay_ms( 300 );

ndirco2_reset( &ndirco2 );
ndirco2_write_register( &ndirco2, NDIRCO2_AVERAGING_COUNT_REG, 0x03 );
ndirco2_set_mode( &ndirco2, NDIRCO2_CONTINUOUS_OP_MODE );
log_printf( &logger, "NDIR CO2 is initialized \r\n" );
Delay_ms( 200 );
}

void application_task ( )
{
uint16_t co2_data;

ndirco2_read_co2( &ndirco2, NDIRCO2_CHECK_EACH_MEASURE, &co2_data );
log_printf( &logger, "CO2 concentration is: %d ppm \r\n", co2_data );
}

The example for arduino is available here.


text:
What will happen if I give my Arduino Uno more or less than 5 volts?
Will it still run on less than 5 volts? Will it break?

Can you be more specific? Are you talking about the power supply voltage, a digital input pin, an analog input pin?

Will it break at < 5V? Not likely.

Check the datasheet for the IC's on the board and find the minimum power supply voltage the device works at.
At typical ATmega328 Safe Operating Area (under "Speed grades" in the datasheet) specifies approximately 4.1V for 16MHz.
If you require to use the USB interface, you'll have to check the datasheet for that chip too.

Will it run at < 5V? Maybe.

If the supply voltage gets below the minimum operational voltage, the controller may behave erratically. That means it can do anything (un)expected. This value is in the datasheet and probably somewhere around 2.7V.
If the Brown Out circuit is configured (in fuses), then the controller will switch itself off when supply voltage gets too low to prevent undefined situations. Once the supply voltage returns, it restarts.

Will it break at > 5V? Depends on where you apply it.

V(IN) should work fine for 7-20VDC as it is fed through an on board regulator. Notice though that the regulator has to dissipate the excess voltage and can get pretty hot when you draw a fair bit of current. The regulator will fail if the voltage goes over 20V or gets too hot too often;
+5V should work fine up to 5V, and I personally wouldn't worry if an external supply delivers up to 5.5V unloaded. Above that 5.5V you will probably release the magic blue smoke.

Whilst outside of technical specs, I have not encountered a single ATmega328 that fails to run at 16MHz at 3.3V.

You also have to take care of the Brown Out Detection fuses that will put the ATmega328 into sleep mode whenever it gets below a given level (cf the datasheet).

@zmo, the question was if it breaks. Answer is no, not likely. If the question is "will it stop working as intended?" then the brown out detection comes into play.

@jippie the question was Will it still run on less than 5 volts? as well as Will it break?, so everything you say is true, but the BOD fuse definitely comes into play for this answer ;-)

@zmo You are right. Edited my answer

One point you might want to note is that if you supply a voltage <5V, you should feed it to the +5V pin, not VIN, to bypass the voltage regulators (Conversely, as you note, voltages >5V must be fed to VIN).

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


text:
Webserver on Arduino
How can I run a webserver in a Arduino Uno? I want to use my Arduino to monitor things in my home such as temperature. I want to be able to access this data through the internet.

You'll need something like the Ethernet Shield to connect your Arduino Uno to a LAN.
As for webserver functionality, the Webserver Example sketch does the bulk of what you need.

For the "access this data through the internet" part, assuming you want access beyond your LAN; you'll need to perform Port Forwarding on your local router (i.e. allow the "Internet" to see your Arduino).
If you need wifi, then personally I prefer the CC3300 to the Arduino Wifi shield.

it's easier to let the arduino just emit periodic UDP packets with the relevant data and have another computer do the heavy lifting of hosting the webserver (and it can do logging)

It's important to note that many new users to Arduino don't realise quite how small it is, and how limited a web server you can build. Don't even expect anything near to a home router's config pages in complexity.

UDP is great, but don't forget that UDP is open to packet loss. If you need each and every sample you'd need to make sure you send it multiple times. Then you'd also need to timestamp or identify it. So UDP can become cumbersome. The Original Poster requested info on implementing a Server. The data sent can be as little as just the temperature value. We shouldn't assume a fancy Webpage is required.

@akellyirl with a direct connection and one-way traffic (or connected to a switch with store-and-forward) there will be no packet loss unless the cable is bad

The Arduino Yún has been made with this use case in mind. The Bridge library allows your sketch to publish data such as sensor readings: this data is available through a REST api.
Say you want to publish the temperature of your living room: you'll write something like
Bridge.put("living_room", String(19)); //celsius
You can then access the data via web with a URL like
http://arduino.local/data/get/living_room
You can get all sensor readings without specifying the key name, with
http://arduino.local/data/get

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


text:
How can I use the SerialIP library on my Arduino through a Mac?
I am looking into using the SerialIP library to connect my Arduino to the internet through it's USB connection to my computer.
However, I cannot figure out how to establish the SLIP connection to the Arduino from my Mac.
The library's documentation says:

Perhaps the most difficult part of using this library is figuring out
  how to establish the SLIP connection to the Arduino.

It suggests the use of:
sudo slattach -L -s 115200 -p slip /dev/ttyUSB0

On linux systems. However, on my Mac running OS X 10.10, there is no such command.
I ran into this thread on the Apple forums regarding the missing slattach command, which sounds like it was removed in OS X 10.6.
How can I use the SerialIP Arduino library on my Mac?

You might see if there is a homebrew or macports version of that?


text:
Using an Ethernet Shield and a tlc5940 together
I have am using an Arduino Uno R2 and TLC5940 to control a bunch of RGB LEDs. I want to add an Ethernet Shield R3 so that I can control the LEDs over a web-interface. However, the ethernet shield and TLC5940 use many of the same pins. Can I use them together? How?

You can do this with out any additional hardware by putting the TLC5940 to BITBANG mode instead of SPI mode and making the Ethernet Shield use D8 pin instead of D10 pin.
Software Changes

On line 61 of sketchbook/libraries/Tlc5940/tlc_config.h replace
#define DATA_TRANSFER_MODE    TLC_SPI

with
#define DATA_TRANSFER_MODE    TLC_BITBANG

On lines 339 - 341 of arduino/libraries/Ethernet/utility/w5100.h replace
 inline static void initSS()    { DDRB  |=  _BV(2); };
 inline static void setSS()     { PORTB &= ~_BV(2); };
 inline static void resetSS()   { PORTB |=  _BV(2); };

with
 inline static void initSS()    { DDRB  |=  _BV(0); };
 inline static void setSS()     { PORTB &= ~_BV(0); };
 inline static void resetSS()   { PORTB |=  _BV(0); };

Hardware Changes

Bend leg of the D10 pin on the Ethernet Shield so it doesn’t connect to the D10 pin on the Arduino.
Connect D10 pin of Ethernet Shield to D8 pin on the Ethernet Shield

Connect the TLC5940 using the following pins:
-------------                                  ---u----
Ethernet   13|                           OUT1 |1     28| OUT channel 0
Shield     12|                           OUT2 |2     27|-> GND (VPRG)
           11|                           OUT3 |3     26|-> SIN (pin 7)
10,underneath|-> BLANK (pin 23)          OUT4 |4     25|-> SCLK (pin 4)
            9|-> XLAT (pin 24)             .  |5     24|-> XLAT (pin 9)
            8|-> to pin 10 on shield       .  |6     23|-> BLANK (pin 10 underneath shield)
            7|-> SIN (pin 26)              .  |7     22|-> GND
            6|                             .  |8     21|-> VCC (+5V)
            5|                             .  |9     20|-> 2K Resistor -> GND
            4|-> SCLK (pin 25)             .  |10    19|-> +5V (DCPRG)
            3|-> GSCLK (pin 18)            .  |11    18|-> GSCLK (pin 3)
            2|                             .  |12    17|-> SOUT
            1|                             .  |13    16|-> XERR
            0|                           OUT14|14    15| OUT channel 15
-------------                                  --------

Tested with Arduino 1.0.5 on Linux Mint 17 with r14 of the tlc5940arduino library.
References:
http://blog.andrewwei.mu/?p=19
http://forum.arduino.cc/index.php/topic,22111.0.html
http://forum.arduino.cc/index.php/topic,142977.0.html
http://forum.arduino.cc/index.php/topic,118265.0.html

When using multiple SPI devices the normal way to have them share a bus is to assign them distinct slave select lines. The problem here is that although the '5940 libraries use SPI to send data to it, the '5940 is not actually a proper SPI device and so lacks any sort of slave select line.
All is not lost, however. Since the '5940 responds only to SCLK (and GSCLK of course, but you should be running that one separately) all you need to do is inhibit it while nSS for the Ethernet module is active. This can be done with just a little bit of external circuitry. Since nSS must be high in order for the Ethernet module to be inactive, we can AND SCK with nSS to derive SCLK from it.
Using a 74HC08 for this would work, although it leaves 3 of the gates unused. A 74HC02 will let you do it with no wasted gates, but with a slightly higher propagation delay.
And of course, the requirement to clock in the grayscale data before the grayscale cycle completes is still there; properly interleaving this with the Ethernet communications is left as an exercise for the reader.


text:
Can the Arduino Uno become an AVR programmer and use the ICSP header to program the target board
The Arduino Uno has an ICSP header that I imagine is for programming the board using a separate ICSP programmer. That is, its ICSP header turn the board into a target.
Can one use that same ICSP to program other boards, turning the Arduino Uno effectively into a ICSP AVR programmer? How?
I'm assuming that the target boards would also be Arduinos and wanted the Uno to program them using the Arduino IDE. Is that possible?
Reading the AVR In-System Programming Application Note it looks to me that the only issue would be to make the programmer (the Arduino Uno) control the target board reset line. I've seen something like that in ArduinoISP sketch, but in that sketch, the target reset is controlled by port D10. But one could program the reset line to be an output, right? So could we change the ArduinoISP sketch to use its own reset line as output to control the target board reset line? If not, why not?

First of all, as configured, the RESET pin can not be used as an output pin. In order to use it as an I/O pin, you would have to program the RSTDISBL fuse. But once you do that, as jippie said, it becomes near-impossible to reprogram your Arduino (if you have the socketed through hole variety of the MCU, you could pull it out and put it into a high voltage programmer; in all other cases, it's effectively impossible).
So in theory, you can use the ICSP header the way you suggest. In practice, it's under almost any conceivable circumstance a terrible idea.

I recommend going out and buying an AVR Dragon - costs aroud $US50. That gives you ISCP programming plus debugwire debugging (using the Atmel Studio IDE).

Atmel Studio only runs on Windows. That's fine if you have Windows, not so great if you are using Linux or Mac.

To answer my own question, just to report that I found something close to what I was looking for, which I link and describe briefly below.
Gammon Software Solutions forum - Atmega Bootloader Programmer - Programming Cable
On that page, the author suggest that we cut pin 5 from the 6-pin ICSP programming cable, solder a pin to it, and wire it to pin D10. Like so:

Then, you can load the Arduino Uno with the ArduinoISP sketch and program the target board as usual.

Yes you can program the Arduino's reset input pin as an output and use that to program another AVR, but you can no longer program your Arduino as that relies on the controller being reset through its own reset pin.
Coming to think about it, I am not sure how the other devices (like the USB controller) responds to being reset by Arduino's controller itself. It resets the USB controller which may or may not reset the connection to the computer, possibly loosing data. With the USB controller being reset, GPIO-pins D0 and D1 (the serial interface between PC and Arduino's AVR) may corrupt the datastream.

In the R3, the nRESET line of the USB controller is not connected to the nRESET line of the main MCU, but only to its own ISP connector. Cutting a trace will disconnect the nRESET line of the main MCU, and jumpering a pair of pads ("RESET EN") will reenable it.


text:
Generating PWM signal 1-2 ms @ 333 Hz
I'm currently working with the Talon SR Speed Controller and it requires a specific Input PWM Signal of 1-2 ms @ 333 Hz and an input resolution of 10-bit (1024 steps). Currently I use the Servo library to handle these requirements, but was having some issues of the motors jumping their dead-band from forwards to backwards really fast causing the motors to rock back and forwards a few millimeters. If the servo1.write(pwmValue); isn't my issues please let me know?
If there is a way to specifically achieve the 333Hz PWM signal for 4 motors of the same Uno or Due (most likely will transfer to a Due in a few days) I would like to implement that.
From my understand I can modify the timers registers for the arduino specifically, but don't know exactly how to do that or to achieve 333Hz. If someone could please help me understand this I would greatly appreciate it.
Speed SR  Speed Controller Information:
Input voltage 6-28 VDC
Continuous current 60 A
Peak current 100 A
Input PWM signal 1-2 ms @ 333 Hz
Input resolution 10-bit (1024 steps)
Output resolution 10-bit (1024 steps)
Output switching frequency 15 kHz
4% neutral dead band

Does this have to do with FRC? I thought the build season was already over

"modify the timers registers for the arduino specifically, but don't know exactly how to do that or to achieve 333Hz" Download the "Complete" version of the datasheet of ATmega328 from the atmel.com website and read the chapters about timers. The datasheet is surprisingly easy to read. Use the knowledge from that to ask a more specific question rather than asking for a complete solution. One hint: 333Hz equals 3ms period, find a timer that can time an accurate 3ms with sufficient resolution.

@thedoctor,  No. This is collegic level robotics.

@jippie, reading it right now. Hopefully it's better than the Arduino website.

@Steven10172 - i applaud your choice in motor drivers

@TheDoctor, we almost built our own in our other custom PCBs, but decided it was safer/easier/cheaper and it had a nice case to protect against metal shavings.

FYI servo/ESC control signals are not the same thing as standard "PWM". Servo position does not depend on duty cycle at all, only the width of the HIGH component. details here: http://www.pololu.com/blog/17/servo-control-interface-in-detail

Hopefully it's better than the Arduino website. - I'm pretty sure tea-leaf divination is better then the arduino site.

I am playing on a Arduino UNO, you would have to compare the datasheets to determine differences.
For my research on this answer I am looking at:

Code/PwmFrequency (for a quick rundown)
Tutorial/PWM
TimerPWMCheatsheet (explains the prescaller and resulting frequencies)
varying the pwm frequency of timer0 and timer2
feature request: adjustable pwm frequencies
pwm frequency library (this is the one you REALLY want)
and the datasheet for the ATMega328

Also:

we know PWM pins are D3, D5, D6, D9, D10, D11
I am using D11 for this since I can attach my oscilloscope to the MOSI pin of the ISCP
D11 maps to PB3 (MOSI/OC2A/PCINT3) (see datasheet or this cool gfx)

Normal usage
First, let's see what happens when we set an arbitrary PWM on pin 11
int DUTY = 25;
analogWrite(11, DUTY * 256 / 100);

results in:

Freq: ~487Hz
Duty: ~25%
Time: ~2.05ms

This first point I will make is that with the given 490Hz the PWM duration is actually 2ms which seems to be close to what you want (you said between 1-2ms), maybe my misunderstanding there.

Playing with pre-scalers
From several of the links posted above, you will see that you have different pre-scalers available depending on which timer you are using: eg.
Pins 5 and 6: controlled by Timer 0 in fast PWM mode (cycle length = 256)
Setting     Divisor     Frequency
0x01        1           62500
0x02        8           7812.5
0x03        64          976.5625
0x04        256         244.140625
0x05        1024        61.03515625

TCCR0B = TCCR0B & 0b11111000 | <setting>;

Pins 9 and 10: controlled by timer 1 in phase-correct PWM mode (cycle length = 510)
Setting     Divisor     Frequency
0x01        1           31372.55
0x02        8           3921.16
0x03        64          490.20
0x04        256         122.55
0x05        1024        30.64

TCCR1B = TCCR1B & 0b11111000 | <setting>;

Pins 11 and 3: controlled by timer 2 in phase-correct PWM mode (cycle length = 510)
Setting     Divisor     Frequency
0x01        1           31372.55
0x02        8           3921.16
0x03        32          980.39
0x04        64          490.20
0x05        128         245.10
0x06        256         122.55
0x07        1024        30.64

TCCR2B = TCCR2B & 0b11111000 | <setting>;

(All frequencies are in Hz and assume a 16000000 Hz system clock.)

These are relatively simple to setup and use (the setting is at the bottom of each of the above code blocks), but you have to be mindful of playing with the pre-scaler of timer0 (which controls millis() and delay()). So if you have a choice, steer clear of timer0, or pwm pins 5 and 6.
Example of using just the inbuilt pre-scalers without any additional libraries:
#define PIN 11
void setup(){
    pinMode(PIN,OUTPUT);  // not absolutely required
    int DUTY = 20;
    TCCR2B = TCCR2B & 0b11111000 | 6;
}

void loop() {
  static long counter = 0;
  if(millis()%10==0){
      counter++;
      analogWrite(PIN, counter%255);
  }
}

I know you can manipulate the frequency better than that, and I have been playing with this for hours and then I finally stumbled upon the final link (which believe it or not, I found via YouTube!).

Using an External Library
To use the PWM library you will need to download it from Google Code, save/import/get it into your library folder, and restart the IDE. Once you do that, you can explicitly set the frequency (within limits, 333Hz is within those limits), and you should be set.
Code example:
#include <PWM.h>
int32_t frequency = 333;

#define PIN 10

void setup(){
    pinMode(PIN,OUTPUT);
    int DUTY = 20;
    InitTimersSafe();                    // won't touch timer0
    SetPinFrequencySafe(PIN,frequency);  // again, not timer0
    pwmWrite(PIN, DUTY * 256 / 100);
}

There is even a pwmWriteHR which allows for higher resolution, but that does not work with timer2 (which is only an 8-bit timer).
The matching, non-safe (ie initialises and uses timer0 as well) functions are:
InitTimer();  // and
SetPinFrequency(PIN,frequency);

The only limitation I have found so far is that it doesn't work with PWM pin D11. I have tested D3, D9 and D10 (they all worked fine), but I did not get around to testing D5 or D6.
Good luck, I hope this helps.

This will command a Talon SR from an Arduino.  I used an Uno and had the Talon hooked up to a CIM motor & gearbox and it ran fine.  I don't understand the code well enough to know if it's generating the 1-2ms PWM signal you asked about and your control resolution will definitely be limited to roughly 1% of range - all I know is that it works.
First, make sure your wiring is set up:
Black PWM wire goes to GND
Red PWM wire goes to 5V (right next to GND on the Arduino)
White PWM wire goes to pin 3 (or some other Arduino PWM pin)
Then try this code:
#include <Servo.h>  //This comes with the Arduino

int talon_pin = 3;

Servo talon;

/* The 'Servo.h' library allows you to control motors and servos by passing any value between
0 and 180 into the "write" method (talon.write() in this program).
For a motor:   0 is full power in one direction,
             180 is full direction in the opposite direction,
              90 is stop.
For a servo:   0 is all the way one direction,
             180 is all the way in the opposite direction,
              90 is the middle.
*/

int talon_max_forward = 180;  //this might not actually be forward
int talon_max_reverse = 00;    //this might not actually be reverse
int talon_stop = 90;          //this is definitely stop (if the Talon is calibrated right)

void setup() {
  talon.attach(talon_pin);  //This tells the arduino to control this pin like it's a servo/motor
}

void loop() {
  talon.write(talon_max_forward);   //full power one way
  delay(2000);                      //wait 2 seconds
  talon.write(talon_stop);          //full power the other way
  delay(2000);                      //wait 2 seconds
  talon.write(talon_max_reverse);   //full power one way
  delay(2000);                      //wait 2 seconds
  talon.write(talon_stop);          //full power the other way
  delay(2000);                      //wait 2 seconds
}

The Talon I used was fresh out of the box and had never been calibrated before, so the "stop" didn't actually stop - it just moved slowly.
To calibrate it, use a paper clip or pen / pencil to press and release the CAL button on the Talon (next to the LED).  You have to press AND release when commanded to stop (after going full + and full - in between), but the motor doesn't turn when the button is pressed.  I calibrated by running the program above with the motor attached, waiting for the motor to "stop", then pressing and holding for 8 seconds.  If you have trouble hitting it, increase one of the delays after a talon_stop command.

You'll need to edit the library file, Servo.h.
Find the line...
#define REFRESH_INTERVAL    20000     // minumim time to refresh servos in microseconds
And change the refresh interval - 20000us (20ms) is the standard 50Hz rate.
Change it to 3003 to get 333Hz rate.
This will permanently change the Servo library to 333Hz.  If you need 50Hz servos, it would be best to duplicate the Servo library to Servo333 or something.
You will not be able to run both at the same time as they use the same timers.
(This is based on the standard Servo library in arduino 1.06)


text:
Washable, Wearable Tech with Arduino
Question: How does one prepare clothing with embedded electronics for washing?
Background: There are several Arduino boards/clones that are designed for "wearable tech."  (For example, the Lilypad.)  Wearable tech with LED light patterns, microphones, GPS, or other circuitry is an interesting concept, but water and electricity tend not to mix.
To prepare wearable tech for washing, I would assume people make large circuitry removable.  Yet, inevitably, some electronics will be more-or-less permanently affixed to the cloth.  What, if anything, can be done to these electronics (e.g. sewn-in Arduino Lilypad) to make them washing-machine (preferred--hand wash could be done, but it's so much easier to machine wash) safe?

I would use some sort of epoxy and cover up the exposed circuitry. The major concern would be where the wires connect to the board as flex over time can weaken it.
Some options include:

3M™ Scotchcast™ Wet-Niche Potting Kit
Hysol

US1150™—For electronics, telecommunications, and automotive
  components. Provides environmental hazard protection.
US1152™—For electronic assemblies. Provides environmental hazard protection.

  Heat might play a factor if you cover up the boards in epoxy but you shouldn't be producing that much heat in a wearable device anyway, right?

How does one prepare clothing with embedded electronics for washing?

Remove the battery(ies) and other power supplies, and set them far away from the water. Buzzers and speakers also.
Gently wash clothing (including the Lilypad, LEDs, resistors, capacitors, integrated circuits, accelerometers, magnetometers, Bluetooth modules, GPS modules, etc.) by hand with a mild detergent.
Drip dry, or manually dry with a hair-dryer.

See:

"LilyPad ... They're even washable!"
"accelerometer shirt ... is washable."
"Are LEDs and Resistors Washable?" (Yes!)
"Remove After Washing" on Piezo Buzzer

I would make it so the Board has velcro on it so that it can be un attached from the clothing, and then have all the wires have snap terminals that wires from the Arduino connect to. This way you un snap all the wires and remove the arduino. As far as components, I would cover them in an epoxy to protect them.

I've purchased the "correct" snaps for wearable electronic connections, and I've also bought cheap shiny silver colored snaps from the fabric store. Both work just fine with conductive thread. It's a lot less particular than it seems like it should be.


text:
Code for one-time execution in Arduino
Question: Where do I put code if I want it to execute only once per Arduino startup?
Background: I tend to use my Arduino to perform tasks that should be executed once per power cycle.  (For example, my robot should only drive forward once every time I turn it on--more than that, and it might fall off the table.)
The standard Arduino IDE "template" consists of a loop() and a setup() function.  The setup code is run once per power cycle, and the loop is re-started every time it finishes.
I see two approaches to code "1 time tasks:"
Method 1: "Loop once"
void setup() {
  //do setup stuff
}

void loop() {
  //do task

  while(1) ; //Repeat forever, preventing function from re-starting
}

Method 2: "Setup only"
void setup() {
  //do setup stuff

  //do task
}

void loop() {
  //do nothing
}

More detailed form of question:  Is one of these methods "better" from a hardware/software sense?  (e.g. is there anything "special" about the setup function, like it can only run for so much time?)
And, if they are the same from a hardware/software perspective, is there a "best practice" or standard way of writing code for these situations in the Arduino community?

Some use of the exit command is discussed in http://arduino.stackexchange.com/questions/188/what-happens-when-i-call-exit-from-my-program

I'm kind of confused by your question. You ask where you want to put once-per-startup setup functions, and then discuss the setup function. That's what the setup function is for.
As such, one-time setup functionality goes in the setup function.
FWIW, if you look in the file that calls the setup and loop functions:
#include <Arduino.h>

int main(void)
{
    init();

#if defined(USBCON)
    USBDevice.attach();
#endif

    setup();
    for (;;) {
        loop();
        if (serialEventRun) serialEventRun();
    }
    return 0;
}

For all intents and purposes, the two options are completely identical. Either way, you get a empty busy-wait loop. Frankly, I'd expect the two different options to probably emit the same machine code anyways, so the whole thing is a non-issue.
Note:
if (serialEventRun) serialEventRun(); appears to be a facility to allow you to attach a function that is called upon reception of serial data, but if you do not define a function void serialEvent(){} in your code, it will compile out completely and not be present in the produced machine code.

It feels weird to accept an answer that isn't (yet) the highest-voted.  But, seeing the main() function definition was really helpful to my question.  (And, you do indicate a consensus with the group with using setup instead of loop).  Thank you for your help.

@anorton - When in doubt, look under the covers. I find the arduino platform convenient for prototyping, but it's largely just boilerplate code. Understanding what it's doing can be tremendously helpful in deciding how to architect something.

I usually go with Method 2, but end up doing this:
void setup() {
  //do setup stuff

  //do task
  init(); //Do start-up initialization steps
}

void init() {
  // do tasks on startup
}

void loop() {
  //do looping code
}

With the above setup it allows my code to be even more organized.

the best answer so far +1, thanks dude you saved me!

I would strongly prefer Method 2. If you ever plan to add code to handle input, output, etc,  it's easy with Method 2 -- just fill in loop(), but requires reworking/refactoring in Method 1.

There is no time limit on the setup function. I prefer method 2 because the loop can be filled with whatever you need to later.

Definitely go with method two. That's what the setup function is there for. It's much easier to read as well. Anything in the loop() implies it will be run in a loop.

As most other answers, I would go for method 2.
But I would try to avoid the call, by Arduino library, to an an empty loop() that makes the Atmel consume "a lot" of current for nothing.
Edit:
As some comments pointed out though, using delay() in loop() will change nothing to power consumption.
Hence, if you would like to reduce power consumption once your setup() has run, you will have to play with Atmel sleep modes.
You can take a look at this article that shows how to deal with sleep modes from your Arduino sketches; it does more than just putting the Atmel to sleep but it is a good (and simple) read if you want to play with sleep modes.


text:
How do I get an accurate time?
I've made a clock using an Arduino, but the time seems to drift.  I am aware of the rollover issue; the clock seems to drift by about 15 minutes over the course of a week.
I'm using a custom PCB with this resonator from Digi-key.  The code reads the millis() function at the beginning of each loop, and works from that value.
My question is:  How can I measure time with an Arduino, accurately enough to make a passable desk clock?

The millisecond function is supplied with data from an interrupt, which takes a couple clock cycles to run. This adds a miniscule amount of time to each tick.

@TheDoctor: This is incorrect. The interrupt does not slow down the hardware timer that drives millis().

Note: although my answer was accepted and has a higher vote score, make sure you read Edgar Bonet's great answer on how to make your Arduino keep time without an RTC.
I've been quite successful in using the DS1307 Real Time Clock. Here's a link to its datasheet.
Below are some of its features:

It uses IC interface for communication with Arduino, making it easy to program using the right libraries (available on the Net).
It is connected to Arduino through the SCL and SDA pins (analog A4 and A5 respectively), thus only using 2 pins.
It requires very little external components to run.
IT can be connected to a coin cell battery so it will keep time even while the Arduino is turned off. In its low power mode, the coin cell battery lasts for years.
It drifts very little (in my case it only drifts a few seconds per week).
It's not very expensive.

If you don't intend to use an RTC, you can replace the crystal that is commonly used to provide clock to arduino for a crystal oscillator module like this one from Farnel or this other one. They come in 4 pin packages like in the images below. They will generate a much more precise clock for your arduino.

Both modules mentioned have tolerances of 50 ppm and operate at 5V.
Again, just to be clear, these crystal oscillator modules are not to be confused with regular 2 pin crystal like this below. Those are part of the circuitry of external clocks for MCUs, for example.

Is the DS1302 good enough or should I move to the DS1307?

You do not need an RTC to build a clock: the ATmega chip has all the
hardware needed to perform the duties of the RTC itself. Here is how:

Get a 32768 Hz watch crystal: either buy it or disassemble an
old clock. These crystals, specifically designed for time keeping,
have an extremely small temperature drift. You would also need one
of those if you wanted to use an RTC chip.
Configure the fuses of your ATmega to run off the 8 MHz RC
oscillator. This will make your millis() function horribly
inaccurate, and also free the XTAL1 and XTAL2 pins.
Connect the watch crystal to the TOSC1 and TOSC2 pins. These are the
same pins as XTAL1 and XTAL2 (9 and 10 on the 328P). The different
names are used to mean different functions.
Configure the Timer/Counter 2 for asynchronous operation, normal
counting mode, prescaler set to 128, and enable the timer overflow
interrupt.

Now you will get a TIMER2_OVF interrupt at a very steady rate of once
per second. You only need to advance the clock display by one second in
the ISR. In between the interrupts, you can put the MCU in very deep
sleep (power-save sleep mode: nothing runs but Timer/Counter 2) and run
for years on a couple of AA cells. Unless the display is power-hungry,
obviously.
I did exactly this to build my 24-hour one handed wall
clock.
This link points now to the English translation of the original
documentation in French.
Quartz calibration
If you do not calibrate your quartz, you can expect a significant drift,
typically a few seconds per week. The drift rate depends on the
stray capacitance of the traces that connect the crystal to the MCU. In
principle, it could be removed by adding some extra, finely tuned
capacitance. It is worth noting that you would have the same drift
problem with an RTC.
If you are satisfied with this kind of accuracy, then live with it and
be happy. However, if you care to measure the drift, you will notice
that it is very stable. You can then easily compensate for it in
software, and achieve an accuracy of a few seconds per year.
The algorithm for correcting the drift is very simple. From the measured
drift, you figure out the precise delay between the interrupts, which
should be very close to 109 nanoseconds, then:
#define ONE_SECOND    1000000000  // in nanoseconds
#define ONE_INTERRUPT  999993482  // for example

ISR(TIMER2_OVF_vect)
{
    static uint32_t unaccounted_time;

    unaccounted_time += ONE_INTERRUPT;
    while (unaccounted_time >= ONE_SECOND) {
        advance_display_by_one_second();
        unaccounted_time -= ONE_SECOND;
    }
}

In the above example, the quartz is slightly too fast, and the software
compensates by “missing” a tick every few days. If the quartz was too
slow, the same code would instead double-tick once every few days.
This kind of calibration could also be done for an RTC, but it would be
significantly more complex because the RTC reports the time in a
broken-down form that does not naturally lend itself to arithmetic
operations.

Wow that's a really slick design!  I really like how you've put up enough photos to make the design clear, even for us silly monoglot americans :)  I really love seeing explicit project documentation like this!

@JohnWalthour: Thanks! Now you are encouraging me to write a translation. :-)

@JohnWalthour: Done! The link now points to the English translation.

Just to be clear, when you say, "ATmega chip has all the hardware needed", that isn't entirely true when you have to obtain a new crystal.  I think  your solution is slick and am not above replacing the crystal but I was a bit confused when you say I don't need hardware and then turn around and say I need to replace a piece of hardware.

@KellyS.French: My sentence was “the ATmega chip has all the hardware needed to perform the duties of the RTC itself” (emphasis added). But then it is important to notice that most RTCs, including the ubiquitous DS1307, need an external crystal to operate. The ATmega is no different: it has all that's needed to replace the RTC itself, but not to replace the crystal that you would have to connect to the RTC anyway. Please note that an RTC module is more than just an RTC, as it does include the crystal.

@EdgarBonet fair enough sir! I hope I did not come across as rude, I was expressing my puzzlement.

The resonator you specified has a 0.3% stability, where the crystal or crystal oscillator (as mentioned by Ricardo) is 50ppm. Many times more stable. Not to even mention the temperature drift of resonator is horrible. Heating by sunlight will change it. Hence a resonator should not be used for keeping time over long periods.
Hence using either a crystal or crystal oscillator will get what you want. Either using it on the ATmega and set the fuses respectively or us one connected to an RTC.

Where 50ppm is 0.005% stability?

I generalize on that spec, to keep answer brief. Note stability aside Res. have a much larger tolerance and can be quite off. As John W is experiencing. "the right part for the right job"

Oh, I was just curious about terminology @mpflaga ... new to me.

If you don't want to use extra hardware like an Real Time Clock (eg. DSDS1307), you can significantly improve timing accuracy by disabling all unused interrupts. By default Arduino sketches come with various interrupt routines enabled and often they are not used for actually your sketch. Quickest way to find out if you can do without it to try and disable them by issuing noInterrupts();

−1 (although this deserves −4) because: 1. Unless you actually need them, all interrupts are disabled by default, with the sole exception of TIMER0_OVF, which is needed for time keeping. 2. The timing accuracy of the Arduinos is limited mainly by the quality of the resonator. 3. Interrupts do no affect the accuracy of millis() unless you manage to spend more than one millisecond at a time servicing them, in which case you have other problems... 4. Disabling interrupts with noInterrupts() will prevent millis() from keeping time at all!

I understand a lot of the spirit with Arduino is being frugal and occasionally trudging through a problem. I use Arduino (and now chipKIT, since it's got 10x the RAM and 10x the clock speed) for my workplace and I need "peripheral functions" to be up to speed and working as quickly as possible.
I use the sparkfun real time clock in one of my projects and am very happy with it. They also have a "Dead on" variant.


text:
How to connect two Arduino without shields?
I'm planning an Arduino system that consists of several Arduino boards. The maximum distance between the boards is about 50 meters. I want to send basic data between these, like short strings or integers. I know I could send data through ethernet cables but that requires an ethernet shield or the Arduino Ethernet board that doubles the costs. Is there a low budget way I could connect the boards using only the most basic boards (like Uno) and some other components but not a full shield?

If budget wasn't an issue you can use bluetooth or xbee chips. They're not too bad, but will run a total of ~$60 as you'll need 2.

@Steven10172 Bluetooth devices are handy, but it seems like the OP wants a cheap solution without shields (low profile maybe?)

Make sure to connect the grounds if your medium of transfer is electricity!!!

Related: Sending minimal data between two Arduinos far away from each other

For long distance wired communication, look at RS-485.

Since it uses a differential balanced line over twisted pair (like
  RS-422), it can span relatively large distances (up to 4,000 feet
  (1,200 m)). A rule of thumb is that the speed in bit/s multiplied by
  the length in meters should not exceed 108. Thus a 50 meter cable
  should not signal faster than 2 Mbit/s

You can use the MAX485 chip. It's pretty easy to work with but there's a good library as well:
https://github.com/Protoneer/RS485-Arduino-Library

Couldn't he just strip the wires in RS-485 or similar and just use that for serial to save money? 9600 baud doesn't run nearly as fast as 2 MBPS. Is there something special about the protocol/voltages/etc. that makes it suitable for long distances? It might save some money...

It's a differential signal sent over a twisted pair. Reduces noise. http://en.wikipedia.org/wiki/Differential_signaling

This page is an excellent resource on RS485 with Arduino http://www.gammon.com.au/forum/?id=11428

There are two categories i can think of to classify comminucation features of the Arduino boards:
Between 2 devices:

Serial: Easy to use and only requires 2 data lines.
OneWire: Harder to use and slow, but uses only one data line

Between more than 2 devices

I2C: You can have up to 128 devices on a network, individually addressable, but requires a master device, uses 2 data lines. this is know also as Wire.
SPI: difficult to use, but very fast and easy device selection. uses a lot of data lines (3 + num of devices)
OneWire: using addressed oneWire is even slower than regular oneWire, still only one data line
SoftwareSerial: You can have several devices connected by different Serial lines, but it is slower.
CAN: only available on the Due, and addressable

There are other methods available, but these listed only require a minimum of external hardware.
For distance ratings, see http://forum.arduino.cc/index.php?topic=82937.0 and http://www.tldp.org/HOWTO/Remote-Serial-Console-HOWTO/serial-distance.html
These data rates are directly controlled in Serial and can be tweaked in many others.

Freakduino makes some Arduino boards with built in wireless. Their long range wireless is 900 MHz and their shorter range is 2.4GHz. I think they are actually XBee radios and for programming you would use a library called chibiArduino, which is available (and documented) on the Freakduino website. When communicating wirelessly with another radio you can use Broadcast or specify a radio by it's ID which is a value you need to set in the EEPROM of the Freakduino.
Taken directly from the Freakduino site:

The addition of an integrated wireless radio based on the IEEE 802.15.4 protocol (same radio protocol as the XBee) allows for wireless control of devices or wireless sensor data collection. Optional battery circuitry was added so that it could function as a true wireless node without any external power cables. The board is also designed to fit a ruggedized enclosure so that the design can be transported safely or deployed in an actual usage scenario without worrying about damaging the circuitry.
This 900 MHz radio is a personal favorite of mine. I use it all the time because 900 MHz offers much better range compared to 2.4 GHz. The radio can output up to 10 mW of transmit power which can get a surprising amount of range. With direct line of sight, a few hundred meters would not be surprising. If additional range is needed, the modulation mode can also be changed from OQPSK to BPSK. This results in additional range at the expense of data rate, with the max going from 250 kbps to 40 kbps in standard mode.

You could use a Ethernet breakout board ($2 at Sparkfun).  This lets you use the Ethernet cables but you don't have to use a full TCP/IP protocol, instead you can just hook up data pins to the breakout board, use the Ethernet to connect them, and then have them talk using serial.  I use this quite a bit to place one wire sensors further from the Arduino for a strong yet cheap connection.

Like you said, Ethernet shields are expensive, but you don't have to use the shield.  Check out the enc28j60 for wired networking, or the ESP8266 if you would prefer wireless.  Both are about $4USD.  I am using the ESP8266 now and have about 8 devices talking to each other and a Raspberry Pi.  It is a really great little chip!  I cannot speak personally to the ENC28j60, as they are still sitting in the package on my desk.