M-Code steered Arduino Mega Shield to control servos in 3d printed feeder. Additionally firmware has capabilities to read some analog channels (e.g. for vacuum sensors) and switch some mosfets to power some peripherials. Used in combination with 3d printed 0816-automatic feeder.
Native Shield | Arduino Mega Sensor Shield v2.0 | |
---|---|---|
supported by firmware out of the box | ✓ | ✓ |
Number of feeder | 24 | 48 |
Manual feed by tapping on tape tensioner | ✓ | - |
Check feedback line for sufficient tape tension | ✓ | - |
2 optional vacuum sensors | ✓ | - |
4 optional power output | ✓ | - |
power from arduino or external | ✓ | ✓ |
enable/disable power for all feeder via g-code | ✓ | - |
where to get? | OSHpark and co. | amazon.com and others |
Choose how to supply power to the feeder:
type | source | how to activate that type? | useful for | precaution |
---|---|---|---|---|
internally powered | arduino 5v line | set a jumper on the pinheader INT_PWR (native shield) resp. PWR_SEL (sensor shield) | prototyping | don't connect external power |
externally powered | external 5V power supply | remove jumper from INT_PWR (native shield) resp. PWR_SEL (sensor shield) and connect supply to FEEDER_PWR resp. the only screw block (sensor shield) | production |
Get the currentmost firmware at https://github.com/mgrl/0816-feeder-firmware.
Use Arduino IDE to build and upload to microcontroller. Precompiled files are not available. Adapt firmware to your needs by modifying config.h. Most of the settings should not need to be touched as they are preconfigured properly already.
Anyway there is a config.h to enable/disable debugging, change serial baud rate and choose the controller shield.
#define DEBUG // disabled (commented) by default. uncomment to get some debug data printed via serial #define CONTROLLER_SHIELD NATIVE_SHIELD //compile for native shield (NATIVE_SHIELD) or sensor shield (SENSOR_SHIELD) #define SERIAL_BAUD 115200 //set speed of serial communication
Install the following libraries via Arduino Library Manager:
Open serial monitor within Arduino IDE and see whether the controller works. There should be messages on startup that inform about the settings hold in eeprom. Test some commands in the serial monitor to see whether communication works as expected before setting up in OpenPnP.
In combination with the native shield all 4 pin connect to the controller. If you chose to use the sensor shield, the feedback line is left unconnected.
The native shield has the maptable printed on. For the sensor shield the maptable is as the image depicts:
The following commands should work if everything is setup properly. A full list of available commands is listed below.
M610 S1 ; enable feeder M600 N0 F4 ; feeder N0 advance tape 4mm M601 N0 ; retract advancing lever (next time feed is faster, this command is a post-pick command) M600 N0 F2 ; feeder N0 advance tape 2mm M600 N0 F2 ; feeder N0 advance tape 2mm M600 N0 F12 ; feeder N0 advance tape 12mm M610 S0 ; disable feeder
If the feeder doesn't move and an error pops up on the console, check the feeder status with
M602 N0 ; print N0 feeder status
If it reports an error, the feedback-line might not setup properly. Fix it by checking the cabling. Temporarily the error check can be overridden by adding X1 to the feed command:
M600 N0 F4 X1 ; feeder N0 advance tape 4mm ignoring errors
The firmware comes preset for the feeders mechanics. But it may be the case, that the servo angle is a little different from manufacturer and how the servo controller handles the incoming PWM signal. For this reason every feeder has a configuration set. Adapt it so that commanding the servo to 0°/90° indeed makes the servo go to 0°/90°. The current configuration setting per feeder is printed with
M620 N0 ; display settings for feeder N0
The meaning of each argument is to be seen in the detailed list.
M603 N0 A55; set servo on feeder N0 to angle 55°
Once found a proper configuration, set the values globally in config.h or issue an M620 command with correct values for every feeder.
→ see next chapter
The feeder and its controller are designed to suit well to OpenPnP, so nothing special is required to get them to work with OpenPnP. To set up one or more feeder follow the next three steps.
<gcode-driver port-name="COM15" baud="115200" flow-control="Off" data-bits="Eight" stop-bits="One" parity="None" set-dtr="false" set-rts="false" units="Millimeters" max-feed-rate="1000" backlash-offset-x="-1.0" backlash-offset-y="-1.0" non-squareness-factor="0.0" backlash-feed-rate-factor="0.1" timeout-milliseconds="10000" connect-wait-time-milliseconds="1000" visual-homing-enabled="false" name="0816 feeder controller"> <command type="COMMAND_CONFIRM_REGEX"> <text><![CDATA[^ok.*]]></text> </command> <command type="COMMAND_ERROR_REGEX"> <text><![CDATA[^error.*]]></text> </command>
In general, there are as many actuators needed as feed lengths are desired. Example: The feeder shall be able to feed 4mm (0805 resistors), 8mm (some ICs) and 12mm there will be 3 actuators to be created, each for one feed length. Every feed-length has to be setup only once, not per feeder. See machine.xml regarding the actuator elements:
<actuator class="org.openpnp.machine.reference.ReferenceActuator" id="actAutoFeeder4mm" name="AutoFeeder_4mmAdvance" index="0"> ... </actuator> <actuator class="org.openpnp.machine.reference.ReferenceActuator" id="actAutoFeeder8mm" name="AutoFeeder_8mmAdvance" index="1"> ... </actuator> <actuator class="org.openpnp.machine.reference.ReferenceActuator" id="actAutoFeeder12mm" name="AutoFeeder_12mmAdvance" index="2"> ... </actuator> <actuator class="org.openpnp.machine.reference.ReferenceActuator" id="actAutoFeederPostPick" name="AutoFeeder_PostPick" index="3"> ... </actuator> <actuator class="org.openpnp.machine.reference.ReferenceActuator" id="actAutoFeederEnable" name="AutoFeeder_Enable" index="4"> ... </actuator>
For each actuator the G-Code passed to the 0816-controller when a feed command is issued has to be added (example below). The feed command is M600 per default. The Parameter N is the index of the feeder (zero based) and F the feed length in millimeter. Please note that the actuator's name and the value for the parameter F correspond each other. So actAutoFeeder4mm will have the command M600 N{IntegerValue} F4.
<command head-mountable-id="actAutoFeeder4mm" type="ACTUATE_DOUBLE_COMMAND"> <text><![CDATA[M600 N{IntegerValue} F4]]></text> </command> <command head-mountable-id="actAutoFeeder8mm" type="ACTUATE_DOUBLE_COMMAND"> <text><![CDATA[M600 N{IntegerValue} F8]]></text> </command> <command head-mountable-id="actAutoFeeder12mm" type="ACTUATE_DOUBLE_COMMAND"> <text><![CDATA[M600 N{IntegerValue} F12]]></text> </command> <command head-mountable-id="actAutoFeederPostPick" type="ACTUATE_DOUBLE_COMMAND"> <text><![CDATA[M601 N{IntegerValue}]]></text> </command> <command head-mountable-id="actAutoFeederEnable" type="ACTUATE_BOOLEAN_COMMAND"> <text><![CDATA[M610 S{True:1}{False:0}]]></text> </command>
In the actuators tab click one of the actuators just setup. Put a “0” into “Set Double” to issue a feed command on the first feeder. Click “Set” fires the G-Code to be sent off to the controller and makes the feeder advance the desired length.
Add a ReferenceAutoFeeder in the feeder tab for every physically existing feeder lane. In the field “actuator-name” fill in one of the actuators created in step 2. Example: If the feeder shall advance 8mm, set the actuator-name to “AutoFeeder_8mmAdvance”. In field “actuator-value” the ID of the feeder comes into. The index is 0 based, so 0 will be the first feeder, 23/47 the last. The PostPick actuator is optional but useful to speed up feeding. After a pick, the feeder retracts if needed and gets ready for next feed.
<feeder class="org.openpnp.machine.reference.feeder.ReferenceAutoFeeder" id="autofeeder0" name="auto_id0_8mm" enabled="false" part-id="R0805" retry-count="3" actuator-name="AutoFeeder_4mmAdvance" actuator-type="Double" actuator-value="0.0" post-pick-actuator-name="AutoFeeder_PostPick" post-pick-actuator-type="Double" post-pick-actuator-value="0.0"> .. </feeder> <feeder class="org.openpnp.machine.reference.feeder.ReferenceAutoFeeder" id="autofeeder1" name="auto_id1_8mm" enabled="false" part-id="R0603-1K" retry-count="3" actuator-name="AutoFeeder_4mmAdvance" actuator-type="Double" actuator-value="1.0" post-pick-actuator-name="AutoFeeder_PostPick" post-pick-actuator-type="Double" post-pick-actuator-value="1"> .. </feeder>