text:
Arduino Mega vs servo shield
I am currently designing a hexapod with a total of 18 servos. I come from a computer science background and know little about electronics, so there is one thing which puzzles me.
Adafruit is selling this servo shield. It can power up to 16 servos while only using two pins. But it's quite expensive as it would cost me ~30€. Add the cost of an Arduino Uno and you are at >50€. At the same time I could just buy an Arduino Mega and power all Servos for a lower price.
I like to think that Adafruit wouldn't sell a uselessly overpriced product, so would there be any advantage to using this shield?
Bonus question: If I'd end up buying the shield, could I just power 16 Servos with the shield and 2 via the Arduino? Would there be any problems with that? Like a delay in the 16 motors or similar issues which could through my kinematics over bord? Would I have to buy two shields (which is not really an option at that price)? Any other suggestions I have not heard of are also very welcome!
If it is of any relevance, I am planning to buy these servos as they are pretty strong and come super cheap in bulk.

The idea of that particular servo shield is that it provides 16 PWM (pulse width modulation) channels. These are all operated simultaneously with no additional processing overhead on the Arduino.
The Arduino Uno itself does not offer 16 (or 18) hardware PWM channels but only 6 (see here). So driving 18 servos without an additional shield would require software PWM which requires some of the Arduino's ressources to be devoted doing the calculations. This may or may not interfere with the rest of your program.
Furthermore the Uno does only provide 14 dedicated digital GPIO pins in total (+6 multiplexed digital/analog pins, as ZS6JMB's answer points out), so additional hardware would* be required either way - or using an Arduino with more pins (such as the suggested Mega). The Mega however offers only 15 hardware PWM channels, leaving you with soft PWM again. (* assuming some pins will be needed for sensors or user interfacing).
An alternative is this board or, uhm, well, cheaper clones if you like. It features the same chip as the shield but with a PCB half the size and thus skipping the "free use area". I expect it to behave the same way like the shield and operate with the same libraries as the both the shield and this board communicate only via I2C. Both can be chained (or stacked for the shield if you will) for up to 992 PWM outputs (62 boards).

you absolutely nailed my question! thanks a lot! just one little thing: what is the difference between the board you linked and the shield? is it just more expansive because it is a shield?

@Neuron from the docs I would say that there is little difference. Both have the same chip and communicate via I2C. I dare say it will work the same way as the shield.

Most of those pen controllers or shields are o.o expanded or own generators. In this case, the resolution maxes out to be just shy of 8 bits.
There are better ways to do it. I can post the link later but I explored quite a few ways to drive multiple servos off of a timer on a pic or avr. The number of servos it can drive is determined by the length of off-duration a servo can tolerate, and number of gpio pins on a mcu.
here is the link: https://dannyelectronics.wordpress.com/2017/02/18/driving-multiple-servos-off-a-pic-timer2-ranged-extended/
it provides a few examples for its implementation on PIC and AVR. But the basic concept is the same.
No shield used and it runs in the background so it is full transparent to the user code.

The linked adafruit board claims 12 bit PWM. Do you have details to substantiate the claim it really does not?


text:
Trying to get my MPU chip to work
I'm new to Arduino and I'm trying to get my MPU 6050  chip to work. The simple code runs fine but when I use the downloaded example I get the following:
Arduino: 1.6.5 (Windows 7), Board: "Arduino/Genuino Uno"
Build options changed, rebuilding all
....

g.cpp.o

C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avr-gcc -w -Os -Wl,--gc-sections -mmcu=atmega328p -o C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp/MPU6050_DMP6.cpp.elf C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050_DMP6.cpp.o C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\Wire\Wire.cpp.o C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\Wire\utility\twi.c.o C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp/core.a -LC:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp -lm

C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::setRate(unsigned char)':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:133: undefined reference to `I2Cdev::writeByte(unsigned char, unsigned char, unsigned char)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::setExternalFrameSync(unsigned char)':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:175: undefined reference to `I2Cdev::writeBits(unsigned char, unsigned char, unsigned char, unsigned char, unsigned char)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::setDLPFMode(unsigned char)':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:218: undefined reference to `I2Cdev::writeBits(unsigned char, unsigned char, unsigned char, unsigned char, unsigned char)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::setFullScaleGyroRange(unsigned char)':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:253: undefined reference to `I2Cdev::writeBits(unsigned char, unsigned char, unsigned char, unsigned char, unsigned char)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::setFullScaleAccelRange(unsigned char)':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:387: undefined reference to `I2Cdev::writeBits(unsigned char, unsigned char, unsigned char, unsigned char, unsigned char)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::setMotionDetectionThreshold(unsigned char)':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:531: undefined reference to `I2Cdev::writeByte(unsigned char, unsigned char, unsigned char)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::setMotionDetectionDuration(unsigned char)':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:561: undefined reference to `I2Cdev::writeByte(unsigned char, unsigned char, unsigned char)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::setZeroMotionDetectionThreshold(unsigned char)':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:601: undefined reference to `I2Cdev::writeByte(unsigned char, unsigned char, unsigned char)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::setZeroMotionDetectionDuration(unsigned char)':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:632: undefined reference to `I2Cdev::writeByte(unsigned char, unsigned char, unsigned char)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::setSlaveAddress(unsigned char, unsigned char)':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:972: undefined reference to `I2Cdev::writeByte(unsigned char, unsigned char, unsigned char)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o:C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:1558: more undefined references to `I2Cdev::writeByte(unsigned char, unsigned char, unsigned char)' follow
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::getIntStatus()':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:1687: undefined reference to `I2Cdev::readTimeout'
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:1687: undefined reference to `I2Cdev::readTimeout'
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:1687: undefined reference to `I2Cdev::readByte(unsigned char, unsigned char, unsigned char*, unsigned int)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::setFIFOEnabled(bool)':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2351: undefined reference to `I2Cdev::writeBit(unsigned char, unsigned char, unsigned char, unsigned char)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::setI2CMasterModeEnabled(bool)':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2375: undefined reference to `I2Cdev::writeBit(unsigned char, unsigned char, unsigned char, unsigned char)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::resetFIFO()':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2391: undefined reference to `I2Cdev::writeBit(unsigned char, unsigned char, unsigned char, unsigned char)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::resetI2CMaster()':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2400: undefined reference to `I2Cdev::writeBit(unsigned char, unsigned char, unsigned char, unsigned char)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::reset()':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2426: undefined reference to `I2Cdev::writeBit(unsigned char, unsigned char, unsigned char, unsigned char)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o:C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2450: more undefined references to `I2Cdev::writeBit(unsigned char, unsigned char, unsigned char, unsigned char)' follow
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::setClockSource(unsigned char)':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2543: undefined reference to `I2Cdev::writeBits(unsigned char, unsigned char, unsigned char, unsigned char, unsigned char)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::getFIFOCount()':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2708: undefined reference to `I2Cdev::readTimeout'
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2708: undefined reference to `I2Cdev::readTimeout'
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2708: undefined reference to `I2Cdev::readBytes(unsigned char, unsigned char, unsigned char, unsigned char*, unsigned int)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::getFIFOBytes(unsigned char*, unsigned char)':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2744: undefined reference to `I2Cdev::readTimeout'
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2744: undefined reference to `I2Cdev::readTimeout'
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2744: undefined reference to `I2Cdev::readBytes(unsigned char, unsigned char, unsigned char, unsigned char*, unsigned int)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::getDeviceID()':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2764: undefined reference to `I2Cdev::readTimeout'
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2764: undefined reference to `I2Cdev::readTimeout'
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2764: undefined reference to `I2Cdev::readBits(unsigned char, unsigned char, unsigned char, unsigned char, unsigned char*, unsigned int)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::getOTPBankValid()':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2785: undefined reference to `I2Cdev::readTimeout'
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2785: undefined reference to `I2Cdev::readTimeout'
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2785: undefined reference to `I2Cdev::readBit(unsigned char, unsigned char, unsigned char, unsigned char*, unsigned int)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::setOTPBankValid(bool)':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2789: undefined reference to `I2Cdev::writeBit(unsigned char, unsigned char, unsigned char, unsigned char)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::getXGyroOffsetTC()':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2792: undefined reference to `I2Cdev::readTimeout'
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2792: undefined reference to `I2Cdev::readTimeout'
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2792: undefined reference to `I2Cdev::readBits(unsigned char, unsigned char, unsigned char, unsigned char, unsigned char*, unsigned int)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::setXGyroOffsetTC(signed char)':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2796: undefined reference to `I2Cdev::writeBits(unsigned char, unsigned char, unsigned char, unsigned char, unsigned char)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::getYGyroOffsetTC()':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2802: undefined reference to `I2Cdev::readTimeout'
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2802: undefined reference to `I2Cdev::readTimeout'
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2802: undefined reference to `I2Cdev::readBits(unsigned char, unsigned char, unsigned char, unsigned char, unsigned char*, unsigned int)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::setYGyroOffsetTC(signed char)':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2806: undefined reference to `I2Cdev::writeBits(unsigned char, unsigned char, unsigned char, unsigned char, unsigned char)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::getZGyroOffsetTC()':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2812: undefined reference to `I2Cdev::readTimeout'
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2812: undefined reference to `I2Cdev::readTimeout'
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2812: undefined reference to `I2Cdev::readBits(unsigned char, unsigned char, unsigned char, unsigned char, unsigned char*, unsigned int)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::setZGyroOffsetTC(signed char)':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2816: undefined reference to `I2Cdev::writeBits(unsigned char, unsigned char, unsigned char, unsigned char, unsigned char)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::setZAccelOffset(int)':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2876: undefined reference to `I2Cdev::writeWord(unsigned char, unsigned char, unsigned int)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::setXGyroOffset(int)':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2886: undefined reference to `I2Cdev::writeWord(unsigned char, unsigned char, unsigned int)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::setYGyroOffset(int)':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2896: undefined reference to `I2Cdev::writeWord(unsigned char, unsigned char, unsigned int)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::setZGyroOffset(int)':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2906: undefined reference to `I2Cdev::writeWord(unsigned char, unsigned char, unsigned int)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::setDMPEnabled(bool)':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2971: undefined reference to `I2Cdev::writeBit(unsigned char, unsigned char, unsigned char, unsigned char)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::resetDMP()':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2974: undefined reference to `I2Cdev::writeBit(unsigned char, unsigned char, unsigned char, unsigned char)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::setMemoryBank(unsigned char, bool, bool)':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2983: undefined reference to `I2Cdev::writeByte(unsigned char, unsigned char, unsigned char)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::setMemoryStartAddress(unsigned char)':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2989: undefined reference to `I2Cdev::writeByte(unsigned char, unsigned char, unsigned char)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::readMemoryByte()':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2995: undefined reference to `I2Cdev::readTimeout'
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2995: undefined reference to `I2Cdev::readTimeout'
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:2995: undefined reference to `I2Cdev::readByte(unsigned char, unsigned char, unsigned char*, unsigned int)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::readMemoryBlock(unsigned char*, unsigned int, unsigned char, unsigned char)':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:3016: undefined reference to `I2Cdev::readTimeout'
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:3016: undefined reference to `I2Cdev::readTimeout'
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:3016: undefined reference to `I2Cdev::readBytes(unsigned char, unsigned char, unsigned char, unsigned char*, unsigned int)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::writeMemoryBlock(unsigned char const*, unsigned int, unsigned char, unsigned char, bool, bool)':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:3060: undefined reference to `I2Cdev::writeBytes(unsigned char, unsigned char, unsigned char, unsigned char*)'
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:3066: undefined reference to `I2Cdev::readTimeout'
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:3066: undefined reference to `I2Cdev::readTimeout'
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:3066: undefined reference to `I2Cdev::readBytes(unsigned char, unsigned char, unsigned char, unsigned char*, unsigned int)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::writeDMPConfigurationSet(unsigned char const*, unsigned int, bool)':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:3170: undefined reference to `I2Cdev::writeByte(unsigned char, unsigned char, unsigned char)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::setDMPConfig1(unsigned char)':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:3198: undefined reference to `I2Cdev::writeByte(unsigned char, unsigned char, unsigned char)'
C:\Users\Emma\AppData\Local\Temp\build2536911660206936106.tmp\MPU6050\MPU6050.cpp.o: In function `MPU6050::setDMPConfig2(unsigned char)':
C:\Users\Emma\Documents\Arduino\libraries\MPU6050/MPU6050.cpp:3208: undefined reference to `I2Cdev::writeByte(unsigned char, unsigned char, unsigned char)'
collect2.exe: error: ld returned 1 exit status
Error compiling.

Help would be most appreciated
Thanks!

Do you have the i2cdev library installed?

when I use the downloaded example - I don't see any code in your post, nor any reference to what you are talking about.

What URL did you download the example from?

You seem to be missing the I2C header.
If you are using the Arduino IDE, beware that it has its own whacky idea of where headers should be. Try adding the #include to the .ino file.

Get i2cdevlib from this linkhttp://github.com/jrowberg/i2cdevlib or just  git clone if your linux user.
then go to i2cdevlib--> arduino folder.There have a folder name with I2Cdev ,just copy that folder in to your library folder in your workspace and then restart the IDE .It will compile now

source: Stack Exchange

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

sort: votes


text:
Arduino and 127/220 Volts: Relay and Isolation
I am new to Arduino, also, I am not fluent in english.
I wish to create a controller for several circuits. All of those circuits are "in parallel" with additional circuits.
My question is:

Do a Relay Shield protects the Arduino board from the current and voltage from the power supply?

Suppose the following:

The retangular boxes are "parallel switches" connected to the devices.
R = Power Supply Phase

S = Another Power Supply Phase

N = power Supply Neutral

Arduino, C2 and C3 are 127 Volts, (S+N)

C0 and C1 are 220 Volts (R+S)

Are the Shields safe from oscilations from the eletrical supply?
What / Where / How should I look on what to ground? Local regulations state that I cannot let R and/or S be grounded.

Which relay shield? Construction is very important for safety reasons.

Arduino: Mega 2560 R3. Relay (all of them are Sanyou SRD-S-105D) Circuits are UP to 2 Ampere each

Okay, but which relay shield? Safety is more than just the parts, as I already said.

So far, there is no "shield" for the relays, they are going to be "screwed" in a wood connector, and the Arduino will have welded wires to the Relay controller pins.

Those relays don't have any ability to be screwed into anything.

Out of curiosity, where has 127VAC?

@IgnacioVazquez-Abrams I am still searching for an actual relay shield, but have not found any shopts that sell them here so far. When I sayd screwed, I am at the moment, planning to either use the plastic cover to glue/weld/screw or use some non-conductant way to keep them in place.

@CharlieHanson Circuits C2 and C3 are 127Volts, Alternating current, provided by the S phase

Make sure you follow creepage recommendations regardless.

Do a Relay Shield protects the Arduino board from the current and voltage from the power supply?

A relay provides galvanic isolation in the circuit.  The mains power is electrically isolated from the rest of the circuit since the device that performs the actual switching (the contacts in the relay) have no physical connection to the rest of the circuit - they are merely acted upon by magnetism.
That doesn't mean that it's safe, however.  There are a number of things you still need to deal with:

The Arduino cannot directly drive a relay - it can't provide enough current. You must use a drive circuit.
Back-EMF from the relay coil as the magnetic field collapses can damage sensitive semiconductors - good snubber circuit design is important here.
Mains electricity is dangerous and must be treated with respect.  Proper circuit design is paramount to ensure that the mains is kept away from the rest of the circuit. Proper connectors must be used and exposed high voltage points must be rendered inaccessible, either by the project housing or by the addition of plastic insulating shielding.
Relays as they turn on and off cause sparks. Sparks cause EMI. EMI causes induced currents. Induced currents cause damage to electronics.  Minimizing the spark generation not only prolongs the life of your relay but the life of everything else around. Ensure your relays can switch fast enough for the currents you are dealing with, or consider using solid state relays (SSRs) that don't suffer from this issue.

When you wrotte: Arduino cannot directly drive a relay. I am having difficulty understanding this. Do you mean that Arduino cant provide the main power? (I expected that, the Relay has 5 pins, 2 for control, a common, and a Normal Open/Normal Closed), they are all understood, OR is this something else?

@Bonatti The Arduino IO pins have an absolute maximum current rating of 40mA and a normal operation maximum recommended limit of 25mA. This is not enough to energise a relay's coil properly.  Google "Arduino Relay" and you will see some simple drive circuits.

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


text:
Is it possible to specify a pin upon which the data sent over i2c can act?
A master will send fan speed values to the slave. The slave will then read the fan speed values and change the speed value for the relevant pwm pin. However I am not sure how I can tell the slave which pin the data is for.  Should I send two packets of data in quick sucsession and then have a loop system wherby the first peice of data out of two is always for specifying the pin? Any help in tackling this would be greatly appreciated.

You can use a struct to send multiple things, like this:
#include <Wire.h>

const byte SLAVE_ADDRESS = 42;

struct t_message
{
  byte pin;
  byte speed;
} message;

void setup ()
{
  Wire.begin ();   // initialize master
}  // end of setup

void loop ()
{
  // set desired parameters
  message.pin = 10;
  message.speed = 50;

  // send the message
  Wire.beginTransmission (SLAVE_ADDRESS);
  Wire.write ((byte *) &message, sizeof message);
  Wire.endTransmission ();
}  // end of loop

More information about I2C - Two-Wire Peripheral Interface - for Arduino

On that page is mentioned how to Send and receive any data type. This includes structs. Using the code there you could send a struct, and receive a struct.

Perhaps you should also add the code for the receiver, especially how to extract the struct members

I've expanded my answer.

In a way, yes.  You are making the assumption that many beginners do, that I2C is only able to send one byte.  That's not the case. You can send many bytes as one single packet with I2C.
Send a single packet consisting of two bytes - the first is the pin number and the second the speed.

so how could i tell the two bytes apart when sent in a single packet? could you give a short code example?

You don't need to. They are separate. You just receive one then receive the other.  The first byte you receive is the first one you sent.

how would the counter system work?

@TCarr What counter system?

well the first byte will indicate the pin and the second the fan speed. So how can i differentiate the first byte from the second in a data package?

You don't! It is already done! The first byte in the packet is the first byte in the packet.  I suggest you ask Wikipedia how I2C works so you can understand what I am saying. Do you have a big L on your left hand and an R on your right hand? No? That's because your left hand is your left hand and you don't get it confused with your right hand because it isn't your right hand.

Let us continue this discussion in chat.

@TCarr What is there to discuss? You have all the information you need. Now go read.

The Arduino Tutorial MasterWriter shows you exactly how to do it. https://www.arduino.cc/en/Tutorial/MasterWriter You send 2 bytes from the master and the receiver event is called with howmany set to 2. You read twice, the first is the pin number the second is the fan speed. It's not rocket surgery.


text:
Arduino Wire.onReceive(handler)
It says in the description of the function:

Registers a function to be called when a slave device receives a transmission from a master.

So when does it exactly called? I guess it's not been called for each byte, but its the meaning of receiving transmission from the master. Does it called for each byte? When the master use transmissionBegin? transmissionEnd?

The functions are beginTransmission and endTransmission, not what you had.

It is called at the end of the reception of the entire packet - i.e., when the slave receives the final STOP bit.  It is passed the number of bytes received (which is the number of bytes you requested since I2C has no way of being able to work out if it is actually receiving real data - see here) as the only parameter so you know how many bytes you can then read from the internal buffer without overflowing it.

Yes, so after endTransmission it would be called - once all of the bytes in the buffer have been transferred, or the transfer failed.

It is passed the number of bytes received - on the AVR versions of the library at least, you get the number of bytes you asked for or zero. I have a discussion about this here.

It looks like they fixed it on SAM... I guess the AVR's I2C module isn't as capable as the SAM one and can't work out if it failed to receive or not.

I don't know how they did that, because the slave doesn't control the clock and can't therefore raise a stop condition. The master is clocking out clock pulses, and reading the results. If the slave stops sending the master just receives 1-bits because of the pull-up resistor.

I guess it may never receive an ACK from the slave though after the last byte has been sent by it - so it would time out.

No, it can't be that - when reading the master ACKs the slave, not the slave the master.

I'm not so hot on I2C, preferring the higher speed of SPI. I have, however, found this very very nice PDF that explains it all in detail: http://www.nxp.com/documents/user_manual/UM10204.pdf

From that document: START and STOP conditions are always generated by the master. (P9). - I might set up a test and see if the SAM boards actually handle that, or if they simply didn't test it.

Figure 12 (P15) is pretty much the clincher... there's no way for the master to know if the slave has stopped sending. It just receives "stuff" and blindly fires an ACK back at the slave until it has read its entire quota - when it then sends the stop. I don't see, from that, how they can have actually "fixed" it in the SAM chips.


text:
Create a device to detect object state
Here is what I want to do or get it done (since I am not a embedded guy)...

create a prototype with Arduino to detect open window/door of my room using camera(image processing/object state detection)?
that prototype will take pictures of room door/window at certain interval and than using some algorithm to decide whether they are open or not and will sound an alarm if it is open.
prototype should work in dark as well
No false alarms
Form factor should be small (the final product should not be bigger than smoke detectors that we have it in our room)

My questions are..

Is it possible? :)
What all things I need to create a prototype?
Which camera should I use? Camera should be really small.
Are algorithms available to detect it?

Not possible, the Arduino is far from powerful enough. What you need is a computer, not a microcontroller.  Think Raspberry Pi or BeagleBone Black.

Also, one has to ask the question: Why?! What's wrong with technology that's been around for a good century or more: the reed switch and magnet?

@Majenko tecnically both Galileo and Edison+Arduino shield qualify as Arduino, so you cannot just equate Arduino and microcontroller.

@IgorStoppa Technically some F1 vehicles qualify as Ford. I wouldn't want to drive one round town though. Also, good luck getting hold of one.

@Majenko certainly the availability of non-microcontroller Arduinos is several orders of magnitude higher than F1-Fords. But I'd rather go for the F1-Fiat, anyways :-P

@IgorStoppa I have been wanting an Edison to play with for ages. You just can't get them. It's like they don't exist. F1 cars are 10-a-penny by comparison....

@IgorStoppa Anyway, the Edison is Intel not Arduino - they just label it as Arduino under license. The only thing Arduino has to do with it is to build a selection of carrier boards for it.

@Majenko: strange, I have a few Edison and Galileo I use for work and they have been sourced from sparkfun or similar, afaik. Not from internal sources. Also on both Galieleo and and Edison you can run projects built with variants of the Arduino ide. I prefer plain Debian on them, but it is possible to use them as Arduino, afaik.

@IgorStoppa You probably got them from the first run - they sold out in the first 1273ms I think and they haven't been available since.  Anyway, I much prefer the 4D Armadillo, since I build the OS for it for them :P

This isn't really on-topic for the question anymore? Arduino is a brand, microcontroller is an 'architecture'. Arduino sells microcontroller development boards. But, they also sell Yún and Due which aren't (purely) microcontrollers. And yes, I would consider an atmega based board ineffective (somewhat incapable) for image processing. For Galileo and Edison+Arduino shield == Arduino they may be pin-compatible but their architecture isn't the same by a long shot? (Not mentioning that you're comparing a board with a brand) :)

I wonder if you haven't overspecified the device? Is there a reason that it must be photo-interpretive? Because if you only need to know whether a door or window is open, a couple of switches and some simple wired logic, or the very most basic of micro-controllers, if you choose to go that way, will be more than adequate, less expensive, more reliable in the long term (Ok, I know you won't be in a dorm room for long), less prone to false or missed alarms, totally unaffected by the ambient lighting or the lack of it, unobtrusive (no cameras - plural - in the middle of the room).
But I get that it might not be as much fun to make, if that is one of your top criteria!

Your answers :-)

yes, it's possible and should not be too complex
for a simple prototype, you do not need an embedded device, just a PC with a webcam
a webcam with few megapixels should be enough
try OpenCV

After your prototype is ready, you can use a small PC-like platform.
Examples: Minnowboard, Edison, BeagleBone, RaspBerry PI 2, Arduino Yun, Galileo 2
A word of warning: depending on the expectations you have, you will have to pick more powerful models. Computer Vision is computationally intensive.
The examples I gave are roughly sorted by performance and, unsurprisingly, cost. OpenCV is available for many architectures, but afaik, it is particularly optimized for x86, since it's mostly sponsored by Intel.
Disclosure: I work for Intel, so I am more informed on Intel products, but by no means I'm trying to do advertisement, this answer is simply given to the best of my knowledge.

I doubt you could make such a thing, especially with no embedded experience.

You want to use a camera, but it should "work in the dark" - problem there. You would need to somehow "light" the room with (say) infra-red, but then technically it wouldn't be dark any more.
It should be really small, but has to have the power of image capture and image processing. Maybe a dedicated board designed by people with a lot of experience, and using surface-mounted devices, could do that. I strongly doubt you could do it on an Arduino of any type.
No false alarms? Without knowing your windows that might be hard to say, but considering windows are usually made of glass, detecting the difference between a closed window, and a wide-open one, might be marginal as you would still see the scene outside through the glass.
As the sun rises and falls the image captured would change considerably, quite probably leading to false alarms. Imagine a sudden thunderstorm, where the next image is much darker than the previous one. The image comparison would register a "difference".
Imagine a picture taken during a storm with lightning flashes corrupting the image.
What is someone enters the room and walks in front of the window? That would register as a difference, but doesn't mean the window is open.

What seems much more practical to me would be variants of existing technologies, eg.

Magnets and reed switches
Shine a laser on the window and detect if it moves (the angle would probably change).
Use distance-detection, such as pinging devices. An open window would change the distance (a bit).
Use passive infra-red to detect the movement when the window opens.
Vibration detection mounted on the window glass, or possibly the window frame.
Temperature measurement to detect a difference in temperature as the window opens.

The camera sounds to me the least practical.

Here is what I want to do or get it done (since I am not a embedded
  guy)...

Welcome to the world of embedded... things. I highly appreciate your interest in the embedded world, after all it's more interesting as just PC things :)

create a prototype with Arduino to detect open window/door of my room

You've come to the right place, Arduino (embedded stuff) is very good at input/output. And that seems like a fun project!

using camera(image processing/object state detection)?

Wait, where did this come from? Humans are good at observing, their main sense would be vision (I guess?) to do so. Microcontrollers are somewhat better at logic signals. They are good at taking sensor signals and turning them into whatever you like.
There is a possibility you'd just like to do something with image processing/detection. If so, please mention that :)

that prototype will take pictures of room door/window at certain interval and than using some algorithm to decide whether they are open
  or not and will sound an alarm if it is open.

Arduino can read out a simple "Door sensor" and check if the door is, or is not closed. This will both shrink your project and make it easier.
Arduino can sound an alarm. You can even add a keypad (for a disable code).

prototype should work in dark as well

The drawback of human vision. Is that it does not work so well in the dark. Sensor's based on the touch of the door or a magnetic contact on the door are not affected by darkness.

No false alarms

If your sensor won't fail, the alarm won't go off by accident :)

Form factor should be small (the final product should not be bigger than smoke detectors that we have it in our room)

Use an arduino nano or micro.

My questions are..
  - Is it possible? :)

Yup! You can check for existing projects on the web. You can put in your own implementation though.

What all things I need to create a prototype?

Whatever you need is what you will need.
An sensor as input, an arduino to process it and an "alarm".
There are a trillion configurations for this, you can choose to just go by one or check what fits your needs best.

Which camera should I use? Camera should be really small.

Unless you really want to get going with camera detection/object tracking, you shouldn't use one. (Especially with arduino it can be quite frustrating.) You should use a PC or raspberry Pi or Android phone.
Or use arduino with said sensor.

Are algorithms available to detect it?

Yes. For this, it's again application specific. You should check out some resources, check what others use and determine what would work best for you. Try it out and if it won't work you can ask it :) (probably on normal stack-overflow since it's not really arduino related, maybe robotics stackexchange).


text:
Webserver on Arduino: How to 307 temporary redirect
I originally asked this question. Regarding a webserver Refresh issue on arduino.
I am totally new to web development and ethernet. The answer from @Majenko is correct, but I do not understand how to implement it. Should I change the homepage() function's first line to HTTP/1.1 307 temporary redirect and use META REFRESH?
Or do the homepage() first using HTTP/1.1 200 OK and then for all the following requests, use HTTP/1.1 307 temporary redirect?

@Majenko I would like you to answer this please.

This might be of use to you: http://stackoverflow.com/help/merging-accounts

You need to make a decision on what to respond with depending on what the request is you have received.
If you receive a "command" URL (which you already check for by looking for certain sub-strings) then you need to respond with the 307 response. If you don't receive a "command" URL (so anything except the things you are specifically looking for) then you respond with the homepage.
A slight re-formatting of your decision code to use else if instead of just if would make it easier:
if (c == '\n') {
  Serial.println(readString); //print to serial monitor for debuging
  // homepage(); << This is now moved elsewhere.
  //controls the Arduino if you press the buttons
  if (readString.indexOf("?resetcount1") > 0) {
    count1 = 0;
    redirect();
  } else if (readString.indexOf("?resetcount2") > 0) {
    count2 = 0;
    redirect();
  } else if (readString.indexOf("?resetcount3") > 0) {
    count3 = 0;
    redirect();
  } else if (readString.indexOf("?resetcount4") > 0) {
    count4 = 0;
    redirect();
  } else if (readString.indexOf("?togglerelay1") > 0) {
    toggleRelay1();
    redirect();
  } else if (readString.indexOf("?togglerelay2") > 0) {
    toggleRelay2();
    redirect();
  } else if (readString.indexOf("?togglerelay3") > 0) {
    toggleRelay3();
    redirect();
  } else if (readString.indexOf("?togglerelay4") > 0) {
    toggleRelay4();
    redirect();
  } else { // If none of them match then send the homepage.
    homepage();
  }
}

redirect() is as simple as:
void redirect() {
  client.println("HTTP/1.1 307 Temporary Redirect");
  client.println("Location: /");
  client.println("Connection: Close");
  client.println();
  client.stop();
}


text:
Arduino MCP23S17 I/O Expander (SPI)
I found this post and I am having almost the exact same issue. Nick Gammon (the god of arduino) has an excellent answer but I can't for the life of me implement it myself. I am not an advanced user like the initial question asker.
So What I want to do is use 2 MCP23S17's (picture here).
I have been messing with one of them all week and have it reading like a charm. I am using the githib library by n0mjs710 to do this. But writing to one will not work.
Along with the zipped library is a few examples. I am trying to read some BCD switches off of one "input MCP" and then display the digits on the "output MCP"
I have used external pullups so I did make one change to the code by commenting out the call for pullups. Here is what Doesn't work:
#include <SPI.h>              // We use this library, so it must be called here.
#include <MCP23S17.h>         // Here is the new class to make using the MCP23S17 easy.

MCP inputchip(1, 10);             // Instantiate an object called "inputchip" on an MCP23S17 device at address 1
                                  // and slave-select on Arduino pin 10
MCP outputchip(2, 10);            // Instantiate an object called "outputchip" on an MCP23S17 device at address 2
                                  // and slave-select on Arduino pin 10

void setup() {
  inputchip.begin();
  outputchip.begin();
  inputchip.pinMode(0xFFFF);     // Use word-write mode to set all of the pins on inputchip to be inputs
  //inputchip.pullupMode(0xFFFF);  // Use word-write mode to Turn on the internal pull-up resistors.
  inputchip.inputInvert(0xFFFF); // Use word-write mode to invert the inputs so that logic 0 is read as HIGH
  outputchip.pinMode(0x0000);    // Use word-write mode to Set all of the pins on outputchip to be outputs
}

void loop() {
  int value;                        // declare an integer to hold the value temporarily.
  value = inputchip.digitalRead();  // read the input chip in word-mode, storing the result in "value"
  outputchip.digitalWrite(value);   // write the output chip in word-mode, using our variable "value" as the argument
  // outputchip.digitalWrite(inputchip.digitalRead()); // this one line replaces the three above, and is more efficient
}

I have tried:

slowing the SPI bus by changing the library to SPI_Divide the clock by 2
changing the ss line and even splitting the lines so one chip uses pin 10 and the other uses pin 9

So after reading Mr. Gammon's post I have made some changes to the code attempting to rid myself of the old slave select pin low trick he mentioned. Here is my attempt:
MCP inputchip(1, 10);             // Instantiate an object called "inputchip" on an MCP23S17 device at address 1
                                  // and slave-select on Arduino pin 10
MCP outputchip(2, 9);            // Instantiate an object called "outputchip" on an MCP23S17 device at address 2
                                  // and slave-select on Arduino pin 10
int ssPin = 9;

void setup() {
  pinMode(ssPin,OUTPUT);

  inputchip.begin();
  digitalWrite(ssPin, HIGH);
  digitalWrite(ssPin, LOW);
  outputchip.begin();
  inputchip.pinMode(0xFFFF);     // Use word-write mode to set all of the pins on inputchip to be inputs
  //inputchip.pullupMode(0xFFFF);  // Use word-write mode to Turn on the internal pull-up resistors.
  inputchip.inputInvert(0xFFFF); // Use word-write mode to invert the inputs so that logic 0 is read as HIGH
  digitalWrite(ssPin, HIGH);
  digitalWrite(ssPin, LOW);
  outputchip.pinMode(0x0000);    // Use word-write mode to Set all of the pins on outputchip to be outputs
}

void loop() {
  int value;
  // declare an integer to hold the value temporarily.
  value = inputchip.digitalRead();  // read the input chip in word-mode, storing the result in "value"
  digitalWrite(ssPin, HIGH);
  digitalWrite(ssPin, LOW);
  outputchip.digitalWrite(value);   // write the output chip in word-mode, using our variable "value" as the argument
}

So any advice would be great to get this working. Help me Obi wan Gammon your me only hope.

Try my library instead. That one looks horrible. https://github.com/MajenkoLibraries/MCP23S17

I agree with Majenco...that one looks hard...I am no expert but i used the Adafruit library and found it very friendly... https://github.com/adafruit/Adafruit-MCP23017-Arduino-Library

I will try yours now Mr. Majenko. Doug the library you posted is for the I2C version of the chip. I have worked with it  before and found it excellent but must use the SPI for some applications.

I have one question. Once you set the PinMode of an expander then can you change the mode without giving a reset? I mean, I have to use 3 expanders for controlling an SRAM: on one MCP I have the data lines, on the second one I have the control signals and on the last one I have the address lines. Firstly, I do a SRAM_WRITE, so I need the pins of the first expander to be OUTPUTs,then I do a READ_SRAM so a need the pins of the first expander to be INPUTs. Can I change the mode from output to input? Then I am trying to check the signals with an oscilloscope. When a do a pinMode OUTPUT of the expa

This sketch uses the Majenko Library with two MCP23S17 chips to demonstrate the library functions.
It was tested on an Arduino Uno with IDE 1.6.5.
/*
 * MultiTest_Majenko_02.ino
 * Library Ref: github.com/MajenkoLibraries/MCP23S17
 *
 * Lowell Bahner
 * 2016-12-11
 *
 * Hardware: Arduino UNO
 * IDE: Arduino 1.6.5
 *
 * Useful SPI Ref: gammon.com.au/spi
 *
 * Wire the SPI Interface common lines (Mega2560 SPI pins shown in [ ]):
 * Arduino SPI_MOSI pin 11 [51] <->   SI  MCP23S17 pin 13
 * Arduino SPI_MISO pin 12 [50] <->   SO  MCP23S17 pin 14
 * Arduino SPI_CLOCK pin 13 [52]<->   SCK MCP23S17 pin 12
 * Arduino SPI_CS pin 10 [53]   <->   SS  MCP23S17 pin 11
 * MCP23S17 VDD pin 9 to +5V
 * MCP23S17 VSS pin 10 to Gnd
 * MCP23S17 Reset pin 18 to +5V
 * MCP23S17 Interrupt pins 19-20
 * MCP23S17 A0,A1,A2 pins connect to Gnd or +5V (000 = Address 0, 100 = Address 1, 010 = Address 2, etc)
 * MCP23S17 Port A pins are chip pins 21-28
 * MCP23S17 Port B pins are chip pins 1-8
 *
 * This sketch runs a series of functions to demonstrate library capabilities.
 * This sketch does not demonstrate interrupt functionality.
 *
 * This sketch instantiates 2 MCP23S17 chips.
 * Bank2 (MCP23S17 address 1) pins are set as INPUT or INPUT_PULLUP.
 *    Normally HIGH, use switch to set a pin LOW.
 * Bank1 (MCP23S17 address 0) pins are set as OUTPUT.
 *    MCP23S17 outputs will power LEDs up to 25ma through 1000ohm resistor to ground.
 *
 * Majenko MCP23S17 library functions (see .h,.cpp files for details):
 *
 *  bank.pinMode(uint8_t pin, uint8_t mode)
 *    where modes are:
 *      OUTPUT - sets pin HIGH
 *      INPUT  - sets pin LOW for sensing change to HIGH +V
 *      INPUT_PULLUP - sets pin HIGH for sensing change to LOW 0V
 *
 *  bank.digitalWrite(uint8_t pin, uint8_t value)
 *    if mode=OUTPUT, pin value = LOW (0) or HIGH (1)
 *    if mode=INPUT, value LOW disables pullup on pin, value HIGH enables pullup on pin
 *
 *  uint8_t value = bank.digitalRead(uint8_t pin)
 *    read the state of the pin
 *
 *  uint8_t value = bank.readPort(uint8_t port)
 *    read entire 8-bit port of all INPUT pins on Port A (port=0) or Port B (port>=1)
 *
 *  uint16_t longValue = bank.readPort()
 *    read both ports as 16-bit combined
 *
 *  bank.writePort(uint8_t port, uint8_t val)
 *    write val (0 or 1, hex example 0x55) to all OUTPUT pins on Port A (port=0) or Port B (port>=1)
 *
 *  bank.writePort(uint16_t val)
 *    write val (hex example 0x55AA) to all OUTPUT pins on Port A and Port B
 *
 *  Also, interrupt functions are defined:
 *      enableInterrupt(uint8_t pin, uint8_t type);
 *      void disableInterrupt(uint8_t pin);
 *      void setMirror(boolean m);
 *      uint16_t getInterruptPins();
 *      uint16_t getInterruptValue();
 *      void setInterruptLevel(uint8_t level);
 *      void setInterruptOD(boolean openDrain);
 *
 *
 *
 *
Run Sketch: Serial Monitor Output

 -- RWpins() --

Bank2: Switch i15: 1 (Push button switch not pushed, Bank2 INPUT pin 15 is HIGH +5V)
Bank1: Output j4:  1 (Bank1 OUTPUT pin 4 is HIGH.
                      Arduino pin 7 is set HIGH.
                      LED on pin 4 is ON. LED on pin 7 is ON.)

Bank2: Switch i15: 0 (Push button switch pushed, grounds Bank2 INPUT pin 15)
Bank1: Output j4:  0 (Bank1 OUTPUT pin 4 switches to LOW.
                      Arduino pin 7 is set LOW.
                      LED on pin 4 is OFF. LED on pin 7 is OFF.)

 -- RWport() --

Bank1: Port A BIN: 00000000
Bank1: Port B BIN: 00000000

Bank1: Port A BIN: 11110100  DEC: 244
Bank1: Port B BIN: 00001011  DEC: 11

 -- RWlongPortValue() --

Bank1: Port A & B BIN: 0000101111110100  HEX: 0x0BF4    DEC: 3060

 -- RWlongPort() --

Bank1: Port A & B BIN: 1011100101000010  HEX: 0xB942    DEC: 47426

 -- CyclePins() --

Bank1: Port A & B BIN: 0000000000000000  HEX: 0x0000    DEC: 0
Bank1: Port A & B BIN: 0000000000000001  HEX: 0x0001    DEC: 1
Bank1: Port A & B BIN: 0000000000000011  HEX: 0x0003    DEC: 3
Bank1: Port A & B BIN: 0000000000000111  HEX: 0x0007    DEC: 7
Bank1: Port A & B BIN: 0000000000001111  HEX: 0x000F    DEC: 15
Bank1: Port A & B BIN: 0000000000011111  HEX: 0x001F    DEC: 31
Bank1: Port A & B BIN: 0000000000111111  HEX: 0x003F    DEC: 63
Bank1: Port A & B BIN: 0000000001111111  HEX: 0x007F    DEC: 127
Bank1: Port A & B BIN: 0000000011111111  HEX: 0x00FF    DEC: 255
Bank1: Port A & B BIN: 0000000111111111  HEX: 0x01FF    DEC: 511
Bank1: Port A & B BIN: 0000001111111111  HEX: 0x03FF    DEC: 1023
Bank1: Port A & B BIN: 0000011111111111  HEX: 0x07FF    DEC: 2047
Bank1: Port A & B BIN: 0000111111111111  HEX: 0x0FFF    DEC: 4095
Bank1: Port A & B BIN: 0001111111111111  HEX: 0x1FFF    DEC: 8191
Bank1: Port A & B BIN: 0011111111111111  HEX: 0x3FFF    DEC: 16383
Bank1: Port A & B BIN: 0111111111111111  HEX: 0x7FFF    DEC: 32767
Bank1: Port A & B BIN: 1111111111111111  HEX: 0xFFFF    DEC: 65535

Bank1: Port A & B BIN: 1111111111111111  HEX: 0xFFFF    DEC: 65535
Bank1: Port A & B BIN: 0111111111111111  HEX: 0x7FFF    DEC: 32767
Bank1: Port A & B BIN: 0011111111111111  HEX: 0x3FFF    DEC: 16383
Bank1: Port A & B BIN: 0001111111111111  HEX: 0x1FFF    DEC: 8191
Bank1: Port A & B BIN: 0000111111111111  HEX: 0x0FFF    DEC: 4095
Bank1: Port A & B BIN: 0000011111111111  HEX: 0x07FF    DEC: 2047
Bank1: Port A & B BIN: 0000001111111111  HEX: 0x03FF    DEC: 1023
Bank1: Port A & B BIN: 0000000111111111  HEX: 0x01FF    DEC: 511
Bank1: Port A & B BIN: 0000000011111111  HEX: 0x00FF    DEC: 255
Bank1: Port A & B BIN: 0000000001111111  HEX: 0x007F    DEC: 127
Bank1: Port A & B BIN: 0000000000111111  HEX: 0x003F    DEC: 63
Bank1: Port A & B BIN: 0000000000011111  HEX: 0x001F    DEC: 31
Bank1: Port A & B BIN: 0000000000001111  HEX: 0x000F    DEC: 15
Bank1: Port A & B BIN: 0000000000000111  HEX: 0x0007    DEC: 7
Bank1: Port A & B BIN: 0000000000000011  HEX: 0x0003    DEC: 3
Bank1: Port A & B BIN: 0000000000000001  HEX: 0x0001    DEC: 1
Bank1: Port A & B BIN: 0000000000000000  HEX: 0x0000    DEC: 0
 *
 *
 *
 */

// Majenko MCP23S17 Library
#include <MCP23S17.h>

// Arduino Library SPI.h
#include <SPI.h>

// SPI CS/SS chipselect pin can be changed by user as desired
const uint8_t chipSelect = 10;

// example Arduino board pin
uint8_t pin7 = 7;

// Create an object for each chip
// Bank1 is address 0. Pins A0,A1,A2 grounded.
// Bank2 is address 1. Pin A0=+5V, A1,A2 grounded.

MCP23S17 Bank1(&SPI, chipSelect, 0);
MCP23S17 Bank2(&SPI, chipSelect, 1);

void setup() {

  // Slow down the master a bit if desired
  SPI.setClockDivider(SPI_CLOCK_DIV8);

  Serial.begin(9600);

  Bank1.begin();
  Bank2.begin();

  // LED connected to Arduino pin 7 to test inter-device communication
  pinMode(pin7, OUTPUT);

  //
  // Set MCP23S17 pin modes:
  // example set one pin: chip.pinMode(0, OUTPUT); // sets chip pin 0 (Port A 0) to OUTPUT mode
  //
  // setChipPins(); // use loop to set individual pins
  // or, since this library does not have a setPortPinMode, do 8 pin loops
  setPortPins(); // example: set pins on each Port on each chip to different modes.
  //

}

// Set all Chip pins to desired mode
void setChipPins() {
  // Example usage

  // Set all Bank1 pins to be OUTPUT
  for (uint8_t i = 0; i <= 15; i++)
    Bank1.pinMode(i, OUTPUT);

  // Set all Bank2 pins to be INPUT_PULLUP
  for (uint8_t i = 0; i <= 15; i++)
    //Bank2.pinMode(i, INPUT);  // unswitched pin voltages about +0.1V, switch must pull pin to +5V
    Bank2.pinMode(i, INPUT_PULLUP);  // unswitched pin voltages about +4.9V, switch must ground pin
}

// Set Port pins to desired mode
void setPortPins() {
  // Example usage

  // Set all Bank1 Port A pins to OUTPUT
  for (uint8_t i = 0; i <= 7; i++)
    Bank1.pinMode(i, OUTPUT);

  // Set all Bank1 Port B pins to OUTPUT
  for (uint8_t i = 8; i <= 15; i++)
    Bank1.pinMode(i, OUTPUT);

  // Set all Bank2 Port A pins to be INPUT
  for (uint8_t i = 0; i <= 7; i++)
    Bank2.pinMode(i, INPUT);

  // Set all Bank2 Port B pins to be INPUT_PULLUP
  for (uint8_t i = 8; i <= 15; i++)
    Bank2.pinMode(i, INPUT_PULLUP);
}

//
// Change LED On/Off with button push
// 1) Switch an INPUT_PULLUP pin to ground
// 2) Read the pin value
// 3) Write the value to an OUTPUT pin
// 4) Turn LED On/Off
// Use functions digitalRead(pin) and digitalWrite(pin,value)
//
void RWpins() {

  Serial.print("\n -- RWpins() --"); Serial.println("");

  uint8_t b15 = 0;  // Bank2 input pin value (0 push LOW, 1 normally open HIGH) with push button switch to gnd
  uint8_t i = 15;   // Bank2 pin number
  uint8_t a4 = 0;   // Bank1 output pin value
  uint8_t j = 4;    // Bank1 pin number

  // read the switch value into b15
  b15 = Bank2.digitalRead(i);
  Serial.print("\nBank2: Switch i"); Serial.print(i); Serial.print(": ");  Serial.println(b15);

  // write the switch pin i, value b15, to the output pin j
  Bank1.digitalWrite(j, b15);

  a4 = Bank1.digitalRead(j);
  Serial.print("Bank1: Output j"); Serial.print(j); Serial.print(": ");  Serial.println(a4);

  // Turn on/off LED connected to Arduino pin 7 through resistor to ground
  digitalWrite(pin7, a4);
}

//
// Read and Write Port values
//
void RWport() {

  Serial.print("\n -- RWport() --"); Serial.println("");

  // set the port pin modes
  setPortPins(); // all Bank1 pins are OUTPUT but set as Ports

  // clear the port pin values to 0
  uint8_t port = 0; // Port A
  uint8_t val = 0x00; // set to 0000 0000
  Bank1.writePort(port, val);
  port = 1; // Port B
  Bank1.writePort(port, val); // set to 0000 0000

  // read the port pin values
  uint8_t valueA = Bank1.readPort(0);
  Serial.print("\nBank1: Port A BIN: "); print8Bits(valueA); Serial.println("");
  uint8_t valueB = Bank1.readPort(1);
  Serial.print("Bank1: Port B BIN: "); print8Bits(valueB); Serial.println("");

  // set the port pin values
  port = 0; // Port A
  val = 0xF4; // set to 1111 0100
  Bank1.writePort(port, val);
  port = 1; // Port B
  val = 0x0B; // set to 0000 1011
  //val = 0xB0; // set to 1011 0000
  Bank1.writePort(port, val);

  // read the port pin values
  valueA = Bank1.readPort(0);
  Serial.print("\nBank1: Port A BIN: "); print8Bits(valueA);
  Serial.print("  DEC: "); Serial.println(valueA, DEC);

  valueB = Bank1.readPort(1);
  Serial.print("Bank1: Port B BIN: "); print8Bits(valueB);
  Serial.print("  DEC: "); Serial.println(valueB, DEC);
}

void RWlongPortValue() {

  Serial.print("\n -- RWlongPortValue() --"); Serial.println("");

  // Read the Bank1 Port pin values as a combined long value
  uint16_t valueLong = Bank1.readPort();
  Serial.print("\nBank1: Port A & B BIN: "); print16Bits(valueLong);
  Serial.print("  HEX: "); crPrintHEX(valueLong, 4);
  Serial.print("  DEC: "); Serial.println(valueLong, DEC);
}

void RWlongPort() {

  Serial.print("\n -- RWlongPort() --"); Serial.println("");

  // Write the Bank1 Port pin values as a combined long value
  uint16_t valueLong = 0xB942;
  Bank1.writePort(valueLong);

  // Read the Bank1 Port pin values as a combined long value
  uint16_t valueLongIn = Bank1.readPort();
  Serial.print("\nBank1: Port A & B BIN: "); print16Bits(valueLongIn);
  Serial.print("  HEX: "); crPrintHEX(valueLongIn, 4);
  Serial.print("  DEC: "); Serial.println(valueLongIn, DEC);
}

//
// Cycle through OUTPUT pins with count-up count-down
//
void CyclePins() {

  Serial.print("\n -- CyclePins() --"); Serial.println("\n");

  // Set all Bank1 pins to be OUTPUT
  for (uint8_t i = 0; i <= 15; i++)
    Bank1.pinMode(i, OUTPUT);

  // clear Bank1 using writePort
  uint16_t valueLong = 0x0000;
  Bank1.writePort(valueLong);

  // Read the Bank1 Port pin values as a combined long value
  for (int8_t i = -1; i <= 15; i++) {
    if (i >= 0) Bank1.digitalWrite(i, 1); // i=-1 allows print of 0 data
    valueLong = Bank1.readPort(); // read 16 bits
    Serial.print("Bank1: Port A & B BIN: "); print16Bits(valueLong);
    Serial.print("  HEX: "); crPrintHEX(valueLong, 4);
    Serial.print("  DEC: "); Serial.println(valueLong, DEC);
  }

  Serial.println("");

  for (int8_t i = 15; i >= -1; i--) { // i=-1 allows print of 0 data
    // decrement after the read while reading down the values
    valueLong = Bank1.readPort(); //  read 16 bits
    Serial.print("Bank1: Port A & B BIN: "); print16Bits(valueLong);
    Serial.print("  HEX: "); crPrintHEX(valueLong, 4);
    Serial.print("  DEC: "); Serial.println(valueLong, DEC);
    Bank1.digitalWrite(i, 0);
  }
}

void loop() {

  // Change LED On/Off with button push
  RWpins();

  // Read and Write Port pins as a group
  RWport();

  // Read the Bank1 Port pin values as a combined long value
  RWlongPortValue();

  // Read and Write Chip 16 pins as a group
  RWlongPort();

  // Cycle through OUTPUT pins with count-up count-down
  CyclePins();

  delay(1000);

}

// print 8-bit byte as 8 bit binary string
void print8Bits(uint8_t myByte) {
  for (byte mask = 0x80; mask; mask >>= 1) {
    if (mask  & myByte)
      Serial.print('1');
    else
      Serial.print('0');
  }
}

// print 16-bit word as 16 bit binary string
void print16Bits(uint16_t myWord) {
  for (uint16_t mask = 0x8000; mask; mask >>= 1) {
    if (mask  & myWord)
      Serial.print('1');
    else
      Serial.print('0');
  }
}

//---------------------------------------------------------------------------------
// crPrintHEX print value as hex with specified number of digits
//---------------------------------------------------------------------------------

void crPrintHEX(unsigned long DATA, unsigned char numChars) {
  unsigned long mask  = 0x0000000F;
  mask = mask << 4 * (numChars - 1);
  Serial.print("0x");
  for (unsigned int i = numChars; i > 0; --i) {
    Serial.print(((DATA & mask) >> (i - 1) * 4), HEX);
    mask = mask >> 4;
  }

  Serial.print("  ");
}

Majenko's library works. All praise to Majenko https://github.com/MajenkoLibraries/MCP23S17

Nick is only a Demi-god :P I am Zeus and Odin rolled into one. Maybe I should change my name to Zein ... or Odus...? ;)


text:
Two arduinos one power source
I was surprised that this question had no answer on Stack Exchange and I can't find much about it elsewhere so, in the hopes that it will be useful to people other than myself, I'd like to ask:
How can one power two arduinos using the same power source? Such that the first is connected by barrel jack to a 12v transformer.
I saw this youtube video which very briefly mentions doing this by make the connections:

Ardu1 --> Ardu2
5V --> 5V
GND --> GND

This surprised me as I was not aware the 5V could operate as a power input. I was expecting the use of the VIN pin somewhere along the line.
Am I correct in thinking that the second arduino would take power on it's VIN pin from 5V on arduino one?
If so, where should the second arduino ground to?

Where did you read that putting 5V on VIN is acceptable?

Nowhere, my only knowledge of VIN is that it can be used as a power source. Please explain your enthusiastic objection.

"The board can operate on an external supply from 6 to 20 volts. If supplied with less than 7V, however, the 5V pin may supply less than five volts and the board may become unstable."

Thank you for that link Ignacio Vazquez-Abrams. It has helped me, discover the solution:
"Vin. The input voltage to the Uno board when it's using an external power source (as opposed to 5 volts from the USB connection or other regulated power source). You can supply voltage through this pin, or, if supplying voltage via the power jack, access it through this pin."
So I have connected arduino 1 VIN --> VIN arduino 2, and arduino 1 GND --> GND arduino 2. And I have power!
Reluctant as I am to destroy my boards, I have not tried the example from the video. Props to anyone who can explain it.

The explanation is that supply pins are neither inputs nor outputs, merely supply lines with a maximum load.

I have powered numerous arduino's via the 5V pin. I would however call this an advanced usage because there are some limitation/dangers.
First of all: Power your arduino via 5V and plugin a powered USB cable or a powered plug and it may (probably will) damage your USB or arduino or both.
Secondly; it is best to assume that all arduino's are different on behalf of the behaviour of the +5V pin. I know for a fact there is a difference with uno,yun,due.
thirdly: The way it is used on the video -you linked to- (power jack 5V arduino 1 to 5V arduino 2 and ground arduino 1 to ground arduino 2) makes that all power goes through the voltage converter on the Arduino 1.
These voltage converters can not handle much current. This is only sufficient in very low power drawing applications.
It s not a good idea to connect the 5V pin of arduino 1 to Vin of the arduino 2. This because the voltage converter on arduino 2 will not be able to provide 5V to The 5V cirquitry.
It is mutch smarter to connect the Vin from arduino 1 to Vin of Arduino2.
When I power arduino's from "standard batteries" I use a switching power supply that powers the arduino over a cut in halve USB cable. This way it is lots safer as I can add power over the jack and I can not plugin a second USB cable.

Thanks, I don't have a high load but I have gone with VIN to VIN. There seems to be no advantage in using 5V over VIN. And more current and protection with VIN to VIN.

You could put the 12v from the barrel jack on both Arduninos Vin pins by jumpering the Vin pins together instead of the Vin->+5 or +5->+5.  Then they'd have independent protection and regulation of 1A, 5V through their NCP1117ST50T3G chips.

Connecting the +5V pins together is acceptable providing you don't exceed the total load that the source of the +5V can provide. This would be either:

The maximum the USB interface can provide:
Bus 003 Device 013: ID 2341:0043 Arduino SA Uno R3 (CDC ACM)
Device Descriptor:
...
  bDeviceClass            2 Communications
...
  idVendor           0x2341 Arduino SA
  idProduct          0x0043 Uno R3 (CDC ACM)
...
  Configuration Descriptor:
...
    MaxPower              100mA

That would seem to be 100 mA from doing lsusb -v on my Ubuntu system.
The maximum that the voltage regulator can provide (if you are using the power jack, or Vin). This would depend on the model of Arduino, plus what your input voltage is (the higher the input voltage, the hotter the voltage regulator will get).

When I am testing things like sending I2C from one Arduino to another, I will often connect the USB to one of them, and just connect together the +5V pins (and ground of course) so that the second Arduino gets powered.

Caveat : my page about power indicates that without using sleep modes and other techniques, a Uno may consume 50 mA on its own. Thus connecting two Unos is likely to be reaching the limit that the USB interface can provide. Connecting three or more is likely to be problematic.

Regarding the USB power issue, see How to get more than 100mA from a USB port. On that page it says:

USB-100mA
USB by default will deliver 100mA of current (it is 500mW power because we know it is 5v, right?) to a device. This is the most you can pull from a USB hub that does not have its own power supply, as they never offer more than 4 ports and keep a greedy 100mA for themselves.
...
Near the end of enumeration you setup device parameters. Very specifically the configuration descriptors. If you look on this website they will show you all of the different pieces that can be set. It shows that you can get right up to 500mA of power requested.

As the negotiation in this case appears to be requesting 100 mA (and not 500 mA) the port on the PC may well limit you to that.

Good answer (+1), but as per USB specification, maximum current a USB 1.1/2.0 port can provide is 500 mA.

See expanded answer.

nice extension :-)

Yeah, thanks. Loads of information. And your page on power and sleep modes is excellent reading. Bookmarked!

This surprised me as I was not aware the 5V could operate as a power input. I was expecting the use of the VIN pin somewhere along the line.

Power is just power. It doesn't have a "direction" like an IO pin. It just flows from a point of higher potential to a point of lower potential. If you put a load onto the 5V pin then the power will flow out of the 5V pin, through the load, to the lower GROUND potential. And that is all the other Arduino is - a load. The power flows out of the 5V, into the other Arduino, through it, and down to the lower GROUND potential.
It's just like a rechargeable battery. Put a light on the battery and the electricity flows out of the battery to light the lamp. Apply a higher voltage to the battery from another supply and the power flows out of the supply into the battery, recharging it (or making it explode if the voltage is too high).

Thank you, this is a very clear explaination. So polarity is not an issue when powering the arduino?

Polarity is a different thing altogether. Reversing the polarity would involve connecting 5v of one to gnd of the other and vice versa. That would result in the death of one arduino.


text:
How long does my digital pulse need to be for it to be read?
I have the following really simple code. On every iteration it'll read the first pin, and if it's high - do some serial IO. Then do the same with the second pin. Nice and simple, works during my tests.
My concern is that (in production), the digital pulse I'm receiving (and trying to mimic during testing) would be too quick for the arduino to read. So, for example, the race condition could be:

First pin is low Read first pin - result is low.
First pin is now high Read second pin - result is low.
Fist pin now low again Read first pin - result is low again (missed the 'high')

How much of an 'edge case' is this? Am I worrying about something that's likely to be a non-issue here? In production, each single pulse would represent a significant amount of product (I multiply it elsewhere) - so even skipping one could throw my data off.
boolean count1High = false;
boolean count2High = false;
int count1 = 7;
int count2 = 8;
int a = 1;
void setup() {
  pinMode(count1, INPUT);
  pinMode(count2, INPUT);
  Serial.begin(9600);
}

void loop()
{
  if (digitalRead(count1) == HIGH)
  {
    if (!count1High)
    {
      count1High = true;
      a++;
      Serial.println(a);
    }
  }
  else
  {
    count1High = false;
  }

  if (digitalRead(count2) == HIGH)
  {
    if (!count2High)
    {
      count2High = true;
      a++;
      Serial.println(a);
    }
  }
  else
  {
    count2High = false;
  }
}

EDIT:
I know best approach here might be to attach an interrupt but I've been advised to avoid serial IO from within interrupts, I don't see an alternative here.

This is exactly the reason interrupts were invented. They can respond a lot faster than a simple digital read. By "a lot" I mean orders of magnitude.
When an interrupt is triggered your interrupt handler for that interrupt executes. If another interrupt occurs whilst your interrupt handler is running the interrupt controller remembers it and the interrupt handler for that interrupt will execute as soon as the previous one is finished.
So you won't miss that pulse while the other pulse is processing.
However note that you shouldn't use Serial in interrupts, since Serial itself uses an interrupt internally to control the transmission, so transmission can't happen properly if your interrupt is already running. So instead your interrupt routine should just set a flag which you then check for in your main loop. You then benefit from the ability to notice a pulse while processing another pulse and still be able to use Serial. In fact, if you arrange it right, you can recognise and remember a pulse on the same input as the one you're currently processing.

As explained by Majenko's answer, you should detect the pulses from an
interrupt and print the result from the regular code. However, instead
of just setting a flag in the interrupt handler, I suggest you instead
count the pulses within the handler. This will make the handler a tiny
bit slower, which is often something you want to avoid. However, the
extra overhead is really tiny, and you gain the ability to count
not only pulses that are short but also pulses that are closely spaced.
There is, however, something to be aware of when sharing a variable
between interrupt code and regular code. If the variable cannot be read
in a single CPU instruction (which is the case of an int on an
AVR-based board), there is some risk that the value gets changed in the
middle of you reading it. To void this problem, you have to disable
interrupts when reading the variable from regular code.
Here is an implementation of this strategy highlighting this point:
const uint8_t intPin1 = 2;
const uint8_t intPin2 = 3;

// This is volatile because it is shared between interrupt context
// and regular code.
volatile unsigned int sharedCount = 0;

// Interrupt handler.
void countPulse() { sharedCount++; }

// A variable shared with interrupt context should be accessed from
// regular code with interrupts disabled, in order to avoid race
// conditions.
unsigned int getCount() {
    noInterrupts();
    unsigned int countCopy = sharedCount;
    interrupts();
    return countCopy;
}

void setup() {
    pinMode(intPin1, INPUT);
    pinMode(intPin2, INPUT);
    attachInterrupt(digitalPinToInterrupt(intPin1), countPulse, RISING);
    attachInterrupt(digitalPinToInterrupt(intPin2), countPulse, RISING);
    Serial.begin(9600);
}

void loop() {
    static unsigned int previousCount = 0;
    unsigned int count = getCount();
    if (count != previousCount) {
        Serial.println(count);
        previousCount = count;
    }
}

Note that if the pulses come very fast, you may miss printing the
value, but you will not miss counting it (up to some limit, of
course). Thus you may see non-consecutive numbers being printed.

It depends where the signal comes from and on other code in your sketch.
Typically, a sketch is rather way too fast for a mechanical switch, and you have to debounce it.
If your fear to lose events is realistic, interrupts are the way to go. But an ISR is some very special code: You won't do more than collect the information that there was an event. And you have to assert your main sketch won't interfere with the ISR.

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


text:
Unable to analogWrite to MOSFET properly (IRLB3034)
I've got a 5 meter LED strip connected to a breadboard as such
12V Supply
(+) -> (+) on breadboard rail
(-) -> ground on breadboard rail
Arduino (Wemos D1, all pins w/ PWM)
pin7 -> gate(1st MOSFET)
pin8 -> gate(2nd MOSFET)
pin9 -> gate(3rd MOSFET)
GND -> ground on breadboard rail
MOSFETs (IRLB3034 equivalent)
Gates (already explained)
Drain(1st MOSFET) -> Red line on WS2812 strip
Drain(2nd MOSFET) -> Green line on WS2812 strip
Drain(3rd MOSFET) -> Blue line on WS2812 strip
Source(all MOSFETs) -> (-) on breadboard
And despite this, when I run an extremely simple program such as this, I get white light (all being lit up), and can never individually address a color. I can write all to 0 and will still have a white light, same with writing all to 255, and same again with writing one or two to 255 and the remainder to 0.
int redPin = 7;
int bluePin = 8;
int greenPin = 9;

void setup() {

}

void loop() {
  analogWrite(redPin, 255);
  analogWrite(bluePin, 0);
  analogWrite(greenPin, 0);

}

I'm thinking my AliExpress board may just be faulty, advertising PWM on every pin when that is not the case, or I may have selected the wrong MOSFETs for this application. Using this identical setup (same breadboard, same MOSFETs) with my Raspberry Pi 2B I was able to change the color of the lights.
Hoping someone here has worked with the Wemos D1 and can help. The documentation on this board seems to indicate that everything should be working, but it is not. I have two boards (same seller) and can confirm that it works with neither.

"Red line on WS2812 strip" Uh... WS2812 only have power and data.

You say “with my Raspberry Pi 2B I was able to address the lights individually” ... was the program the same?  Or perhaps you used a WS2812 library on the Raspberry?  Anyhow, each WS2812 has a chip that PWM's the lights; they aren't intended for external PWM.

A schematic (instead of the text) would greatly improve the quality of your question.

Please supply some details on the LED strip you have and how it is powered since it's clearly not WS2812's.

Unfortunately the WS2812 LEDs color is set by powering it up and sending data to it. This means that you don't need the FETs at all.
Sparkfun have a really good walkthrough for hooking up and controlling these LEDs:
WS2812 Breakout Hookup Guide
To achieve what you set out to do (ie controlling the color with the FETs) you will need a different analog LED strip (such as this). Adafruit have a really good walkthrough for hooking up and controlling the LEDs in this fashion.
Controlling Analog RGB LED Strips

The setup duplicates this ( http://popoklopsi.github.io/RaspberryPi-LedStrip/#!/ ) to a T. The strip I have is non-addressable, and needs about 5A to power it when R,G, and B are at full throttle. Unfortunately none of the examples in that Sparkfun link apply to my case, as each refer to individually addressable strips. The way I understood it was that the lines each carry 12v and use the PWM to dim/brighten each color individually, hence the MOSFET.
This has worked before in an identical setup, with the only change being using a RPi instead of the Wemos.

Are you sure that the LED strip is using WS2812 LEDs. According to the datasheet (https://cdn-shop.adafruit.com/datasheets/WS2812.pdf) it is controlled by digital data.

@Logan Halloran, thanks for the link. Just to prove that your circuit works, have you tried the program controlling the I/O digitally (ie. digitalWrite())?  You may need to add a pull down resistor to the gate of the FETs. Something like this: https://github.com/freetronics/NDriveModule/raw/master/NDRIVE_NDriveModule.pdf


text:
What happens if I don't use a relay for 5V pump
I am trying to build an automatic watering system by following some examples. However, I don't have all the components for the entire system, therefore I have built it in Fritzing using only the components that I have (see scheme below):

I didn't build the physical version yet, because I am not sure that such a system would work without burning anything. In many examples, people connect the pump to a Relay Module, but since I don't have it yet, I would like to build it like this until I set up the watering system.
Can anyone help me understand why a relay would make it better or worse?
P.S. I have a JPC-3F relay, but I can see that the Relay Module contains multiple components. Is it possible to add the JPC relay to the pump without having the entire Relay Module? Would I need extra components for that?
Thank you!
EDIT: Thanks to the answer from ratchet freak, I have added resistances and a transistor. It works fine, but the same question stands. Do I still need a relay in this case?

You should put a resistor in series with the led to limit the current.
The IO pins cannot source enough current to run the pump without damaging themselves. That's why you need a buffer of some kind.
The extra components in the relay module are a transistor to do the actual switching and a reverse-biased flyback schottky diode in parallel with the relay coil. The flyback diode is required to absorb the voltage spike generated by the coil getting switched off and acting like an inductor.
You can use a transistor to switch the motor directly assuming you can find one that can handle the current draw. If you do then you absolutely will need a flyback diode on the motor to avoid damage to the transistor.

Thank you very much for the explanation. Can you please tell me which transistors should I use? In my kit I have one IRF520N, one ST8050 and one S8550  . Would any of these work? I can see that only S8550 can work with 5V, but negative. And will I have to supply extra energy for the pump or it'll work through the IO pins?

You'll need extra energy.

Thank you all. I have tried with only the IRF520N and it works perfectly. Is there any danger in this?

Doesn't the IRF520N already have an internal diode?

this is not an answer to the question you asked, but you need to understand this:
generic DC relay advice. Use commutating diodes. this is not a special kind of diode, it is a particular use of a generic diode. you want 2:
one across the coil, reversed biased - cathode to +VDC. The coil throws a huge spike of negative DC when power to the coil is cut and the magnetic field collapses. this diode eats that spike
second one from the load to ground, reverse biased. this eats any spike from the load to ground - the fat blue arc you see when you disconnect a load by yanking the wire
https://www.allaboutcircuits.com/textbo ... -circuits/
https://www.allaboutcircuits.com/textbo ... ing-diode/
https://en.wikipedia.org/wiki/Flyback_diode
G

The relay have a coil resistance of 70 ohm for the 5 Volt version.
Ohms law, U = I x R
I = U/R = 0.071 Ampere, and now you have to find out, can an Arduino I/O pin drive a load of 71 mA? If not you have to add a driver aka most commonly a transistor.
And now you should ask yourself, can I drive the motor directly with a transistor driver and skip the relay? So do you have any data on the pump?
And if you look at the datasheet for IRF520, fig 3 and fig 4 have the data for planning if it will work or not.
Ref.: https://www.infineon.com/dgdl/irf520npbf.pdf?fileId=5546d462533600a4015355e340711985

Thank you for the answer. The pump is AD20P (5V). It works very nice with transistor only (and a 5V power supply), but I don't know if this is a good idea.

Datasheet for the AD20P ? To post only the AD20P mean that I have to search for the datasheet...

Sorry: Input Voltage: DC 3.5-9V, Power: 1-3W, Qmax = 120L / H (44GPH). This is what I could find.

Worst case is 3 W and 5 Volt:  I = P/U = 3/5 = 0.6Amp then will the IRF520 handle the pump without problem.


text:
Arduino or XBee unique identifier?
Is there anything built into the Arduino Uno or the XBee Pro 2 radio module that I can poll within my Arduino script to act as a unique identifier? Mac address or otherwise? If anyone has a code snippet that can do this it'd be extremely appreciated.
Currently my Arduino nodes are broadcasting only to my node.js server, but my server is broadcasting to all the nodes, so if they're all waiting to be assigned an identifier number through the handshake function I wrote, they all receive the same one. If I stagger powering them up this is avoided and they each get a unique ID, but I hope there exists a cleaner solution.

I guess I can make a random number work.

When programming the Uno's, you could write identifying values into particular EEPROM bytes.  To automate the process, write a development-system program to produce serial-numbered HEX files, with the serial number counting up each time the program runs.
For example, if you store IDs into byte 0x1E of EEPROM, the serial number file would look as follows when the serial number is 0x23:
:01001E0023BE
:00000001FF

The first line in the above file says 01 bytes of payload, stored at address 001E, record type 00 (data), payload byte 23, checksum BE.   See wikipedia's Intel HEX article for further explanation of HEX file format.  In brief, each time the serial number byte goes up by one, the checksum byte goes down by one.
To program a serial number byte into EEPROM from a file called SNfile.hex, issue a command like the following.
avrdude -p atmega328p -c arduino -P /dev/ttyUSB1 -b57600 -U eeprom:w:SNfile.hex:i

See the avrdude manpage for explanation.
In your sketch, use EEPROM.read(address) to read a unit's serial number.  For example:
#include <EEPROM.h>
byte mySN = EEPROM.read(0x1E);

[Note, regarding your question about  “anything built in... to act as a unique identifier”, I once spent quite a while looking for such a thing on Uno, Nano, and Mega2560 Arduinos, and found nothing.  I haven't looked at XBee radio modules for such data.]


text:
Arduino char showing as 2 characters
I'm writing the character 1 from a node.js XBee using the code sp.write("1"); to my Arduino's XBee. Then on my Arduino's XBee I read it like this (inside a loop):
  if (XBee.available()) {
    do {
      r = XBee.read();
      Serial.print(r);
    }
    while (r != -1);

And the input char r shows up as 1� instead of just 1. Why is this and how can I remove the added invalid character from the char? Also is this char now 2 chars, how does this work? Thanks.
EDIT:
Arduino code:
#include <SoftwareSerial.h>

// Global variables
int AnalogPin = A2; // has much less jumpy readings than A0 (maybe A0 slightly damage from overuse)
int ledPin = 13;
SoftwareSerial XBee(2,3); // RX, TX

// Setup
void setup() {
  Serial.begin(9600);
  pinMode(AnalogPin, INPUT);
  XBee.begin(9600);
  for (int i=0; i<100; i++)
    Serial.print("\n");
  // Random ID
  Serial.println("Listening...");
}

// MAIN LOOP
void loop() {
  char r;
  // Allow data reception while waiting for handshake confirmation
  while (1) {
      if (XBee.available()) {
        do {
          r = XBee.read();
          Serial.println(r);
        }
        while (r != -1);
      }
      delay(500);
        if (r == 'Q') {
          Serial.println(r);
          Serial.println();
          Serial.println("Turning LED OFF.");
          digitalWrite(ledPin, LOW);
          Serial.println();
          exit(1);
        }
       else if (r == '1') {
          Serial.println(r);
          Serial.println();
          Serial.println("Turning LED on.");
          digitalWrite(ledPin, HIGH);
          Serial.println();
        }
  }
} // end main loop

Node code:
var SerialPort = require('serialport');
var express = require('express');
app = express();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var ON_DEATH = require('death');

    /* ------------- Connecting to Serial Port ---------------- */
    var portName = '/dev/cu.usbserial-AD01SSII',
    portConfig = {
        baudRate: 9600,
    };

    var sp;
    sp = new SerialPort(portName, portConfig);
    sp.on("open", function (err) {

        console.log("Sending LED on signal.");
        console.log("Ctrl+C: quit and send LED off signal.");
        sp.write('1');

        // Cleanup when termination signals are sent to process
        ON_DEATH(function(signal, err) {
            var death_msg = 'Q';
            sp.write(death_msg);
            sp.close();
            console.log("\n\nSending reset signal to nodes.\n\n")
            process.exit();
        })
*/
  }); // end open

All I'm really trying to do here is turn an LED on and off when I start or end the node program. Maybe I'm just too exhausted to think straight.

In passing a char to Serial.println(), this code cannot produce the claimed output.

What happens now is it produces this: 1
�   (new line in between) So that the last r value is the invalid char instead of the 1 that I want it to be.

Maybe with what was originally there using Serial.print, but not with the code currently in your question using Serial.println it doesn't!

It really does.. I'm running it right now. Actually, I forgot to remove the comment ending thing. But besides that it's the same.

It produces it with a newline, which is not what your questions says.  Your question must be accurate, literally at character level, if you want help.

Sorry, someone else answered and then deleted, and I was kind of mid-edit.

I answered and deleted, after your edit invalidated that answer.

 do {
      r = XBee.read();
      Serial.print(r);
    }
    while (r != -1);

Think about it. Since you tested for XBee.available() you will have at least one iteration of this loop. And then you do a second read, and print it, before finding that the second character is -1.
You need to re-order your loop, or your tests. The second character will be what -1 looks like on your monitor.

A better loop would be:
  while (XBee.available()) {
      r = XBee.read();
      Serial.println(r);
  }

This is the standard way of looping and reading. You won't get -1 from the read here, because if something is available, you will get that something.

I think the -1 means nothing is coming in?

K i just removed all of the while loop and it works a bit. will keep playing with it.

That's right: -1 means no input.


text:
Does millis() conflict with the PWM pins associated with timer 0?
I've read that the millis() function uses the same timer as a couple of PWM pins.
If you're using those PWM pins, will millis() still return the correct value?

They do not conflict as millis() strictly reads the immediate value in TCNT0 whereas PWM via timer 0 uses the hardware's ability to compare the value of TCNT0 with the values in OCR0x without affecting the value of any of them.

millis() just uses Timer 0 overflow counts. micros() reads the immediate value in TCNT0.

Just to add to @Ignacio's answer which has directly answered your question. The "conflict" you speak of is in relation to Timer0's prescaler.
For the most part, you can use those pins (incidentally pins 5 and 6 on the UNO) with PWM without an issue, and read the correct value of millis() (as well as get the expected delay from delay)
Where you run into problems is if you want to change the prescaler (usually to modify the frequency of the PWM signal). If you change this, then you directly affect the calculation and reporting of millis() and the length of delay(x).

You can read your timer's prescaler by the bottom bits of Serial.println(TCCR0A,BIN);  If they are '11' then your prescaler is clk/64.  You could then calculate the factor for modifying millis() and delay().

That's a very good point and I've always just steered clear of modifying it, but there's no reason if you really want/need to. The other point is that if you've modified it you already know the new prescaler and could in turn write wrappers for millis () or delay () anyway


text:
Best way to interact arduino and python
So, i've worked with the pySerial module for python, where I communicated with my arduino via serial. However, this module only works for 32bits and I would like to make my project work on both architectures (I know the person could just install the 32-bits version on the 64-bits architecture). Also, the connection fails a lot of times and I wasn't able to correct it.
I think I can use the true USB power of the arduino Leonardo to connect to the python in a different way, but I don't know where to start. But I think this approach will be more professional.
Im really intersted in learning, so if you guys could at least indicate documents so I can understand how to make this connection between Leonardo and Python, I'll be happy. I've read the arduino page about the CDC but couldn't find useful information.
Thank you so much.
Update:
When i used serial, I had problems with messages getting acumulated at the buffer, and then after some seconds i was reading 10s delayed messages. Also, when I sent a string like: "12345678", it was really easy to get one number less, like: "1345678". This happened frequently to me. So I think I need to implement a protocol to deal with these problems.

Where do you get the idea that PySerial is not x64 compatible? It most certainly is. Also, I've done enormous amounts of data-transfer over serial interfaces. They can be extremely reliable. If you are having issues, it's not because it's a serial connection, there are deeper issues.

I concur with @Connor Wolf, serial comms are perfectly reliable.  You may need to implement some buffering and/or handshaking in your protocol.

I did some work in Java using USB some years ago and I can share some experiences:

Things are not neary as straightforward as using serial.
Your code will probably be platform specific, windows being a bit more weird about handling usb. (unless using something to abstract that away, like PyUSB which wraps libUSB or openUSB, this however does not guarantee platform independency because these libraries also have their weirdnesses).
If you drop down to USB level programming, things can get very messy (again, this can be abstracted away). USB is (at least in my opinion) a complicated protocol, especially for beginners.

So unless you really need something that only USB can provide, a nice and dandy serial communication will give you much less headaches. Thats why serial did not die until now.
As for debugging why your communication is not reliable I would try several things:

See if your application might send something that is interpreted as a control character
Drop your baud rate to something lower and see if it still loses data. If so, you might overflow the buffer of your receiver (and you would need flow control in this case)
Check your hardware! I've had bad wires or solders on numerous occasions

I'll use Serial, then. Do you have some ideas of what protocol I should implement? Because the pure serial comunication fails a lot.

If you update your question to show how it "fails a lot", we might be able to point out how to make it better.

I added some suggestions.


text:
Conditional randomization gets stuck
First-time poster here...
I have the following code to randomize note values and store them in an array loop1[i], where i is a specific step in the loop:
nextNote = random(-2, 3);
note = note + nextNote;

loop1[i] = note;

while (loop1[i] == loop1[i - 1] ||
       loop1[i] == loop1[i - 2] ||
       note > 6 ||
       note < 0) {
  nextNote = random(-2, 3);
  note = note + nextNote;
  loop1[i] = note;
}

(I hope this is clear enough).
Now, it usually works to a certain point until the sketch loops forever in order to randomize an allowed number. Therefore, my questions are:
Running an ATmega 2560, is this actually a task too demanding for the processor or should I suspect that it's not working properly?
How can I optimize the code, but retain the conditions above in order to avoid the loop getting stuck?

if note is bigger that 6 before the while, and your random value for nextNote has a higher chance of being positive rather than negative, the most likely scenario is that note will gradually keep increasing, and increasing, and increasing. So your while loop will get "stuck" gradually increasing note, and not doing anything else. Are you sure you don't mean note>0 and note<6 to limit the note values to between -1 and 9.

Thanks for your reply. Short answer to your last question: my intention was to limit the number range from 0 to 6. I fixed that using constrain().

Well, constrain isn't used inside this while loop, so it will still give the problem I described above. I think you'd need something like if(note>6)nextNote=random(-2,-1);else nextNote=random(1,3); in order to ensure it goes back into range again. That should fix the "infinite-loop" problem you are now having.

Now i understand what you're getting at. I've rewritten the code to make it entirely conditional instead of re-randomize prohibited values. Appreciate the input.

I think you have a problem with your math here, not with your code. What
you are simulating is very similar to a 1-dimensional random
walk.
According to the linked MathWorld page, for such a process “the most
probable number of sign changes in a walk is 0”.
If, at some point in your program, the loop starts with note == 6, and
then it starts randomly going up, there is a sizable probability for it
to never go back to values below 7.

Edit: One possible solution could be to avoid the random-walk notion
and instead repeat the random choice always from the same starting
point.
int oldNote = note;  // starting point
do
    note = oldNote + random(-2, 3);
while (
    note == loop1[i - 1] ||
    note == loop1[i - 2] ||
    note > 6 ||
    note < 0);
loop1[i] = note;

Yes, i think you have a point. Earlier i used a model for statistically distributing the probability, in order to restrain the randomization within range. It became a bit overdone, so i was aiming for an easier solution. Now i have new problems, haha... Care to elaborate on a solution? Math is definitely not one of my strengths.

@Erik: I edited the answer with a suggested solution. Not the most effective, by far, but close enough to the code you posted.

Some reasons why it will not work:

My feeling is that i gets too big, i.e. it is higher than the length of the array you are using. That can cause crashes, or at least unpredicted results. You can easily check this by printing the value of i (and check against the maximum value).
I don't see problems with the while loop (although I would use brackets around note > 6 and around note < 0, but I don't think this is really needed.
If the value gets below 0 or higher than 6, still random values are added, assume the value is +10... then it might take a lot of time (if ever) for that value to reach max 6 again. The same is true for values < 0. Maybe you should never allow values of less than 0 and higher than 6 anyway, or making the random values in such a way they tend to go towards the average (3).

Tip to debug:
However, the easiest way to debug this is to print all relevant variables (e.g. nextNote, note, i, the last two notes loop[i-2], loop[i-1] and the current note loop[i]... Also print a line inside the while loop so you know when you skip it or not. This probably will give you enough information to see what is wrong.

Thanks for your quick feedback, i should probably have included the code for the entire for-loop as it loops OK. However, i did a bit of optimization using constraint() and do/while conditions instead.

The line loop1[i] = note doesn't belong in the loop (or above it); you're not changing i in the loop, so you're just rewriting the same location over and over again.
As for the loop itself, what sort of use case do you have for this, and what sort of distribution do you want? Waiting until it's between 0 and 6 is horribly inefficient. You need to decide what sort of distribution you want and implement it more directly. For instance, you could have a piecewise quadratic distribution by getting a random number between zero and sqrt(3), then squaring the result, and then randomly choosing whether to subtract the result from 6.