This is a VERY short post to describe how "I" connected permanently to the underside pins on my Teensy 3.1's
To get
access to the extra pins on the bottom of the teensy, I used a dual row
header, and bent the inside pins at a 90 degree angle, trimmed, and
soldered. That's it. Easy peasy!
This shot shows the Real Time Clock crystal soldered into place.
There's some further discussion on the subject here...
There are also breakout boards designed to give you easy access to these pins...
Search This Blog
Showing posts with label hackaday. Show all posts
Showing posts with label hackaday. Show all posts
Monday, 30 March 2015
Sunday, 28 December 2014
Prototype Board: DC motor/Encoder - Teensy 3.1 based 3D printer controller
I had mentioned putting up pictures as I go along, so I took this to show the first prototype of the controller board.
Here is the layout of my Teensy 3.1 based 3D printer controller.
As of this shot, I have not yet wired it. Nor have I installed the analog components (power supply, heater drivers, pullup resistors, filter capacitors, etc...). It is also missing the connector for the extruder stepper motor.
As I described in my previous post, my motor control design is based on Adafruit's Motor Shield V2.3. For my prototype... well... I'm using their shield, pilfered from one of my older robots. This fantastic design employs an NXP PCA9865 16 channel 12 bit PWM controller, intended to drive LEDs, but instead to driving a pair of dual Mosfet H bridge TB6612FNG motor drivers.
The Library for this Shield works with the Teensy 3.1 just fine. (It is just I2C after all).
Ok... I'm off to wire this up... wish me luck.
Wednesday, 21 May 2014
Dancing Brushbot assembly...
Update on the Dancing Brushbot:
This is the underside of our friendly Hexbot Nano, with the battery removed. I'll be simply connecting to the positive and negative battery wires for this build.
Opened up, you can see the miniature "pager" motor with the offset weight that vibrates the Hexbot Nano.
I've also placed the protection diode inside the body of the Hexbots, as there was no room on the main circuit board.
I then hotglued the Dancing bot's feet onto the tops of the Hexbot Nano's and drilled a hole to pass the motor wires through.
Luckily, an Attiny84 in socket, as well as a power connector and the ISP header all fit exactly on the board! I couldn't have asked for a better fit!
The Sharp GP2Y0A21YK Infrared Distance Sensor is hotglued onto the stub that held the original Dancing bot's head, and the LiPo battery is velcroed onto the front of the body.
Here, the ATtiny84 control board is placed into the body for sizing.
Assembled, and ready to code. I've placed the AA battery in the picture to demonstrate the size of this guy.


Watch this space over the next few days, as I get this guy up and dancing...
(currently having problems with balance/center of gravity... this too will be conquered)
References:
Programming an ATtiny w/ Arduino 1.0
LetsMakeRobots: Mogul - Program standalone ATtiny / ATmega chips through an Arduino
LetsMakeRobots: Ladvien - Robot Metallurgy 101 -- AVR Lesson Journal
LetsMakeRobots: attiny85 h-bridge ldr robot
LetsMakeRobots: Lumi - TinySpider
http://www.iheartrobotics.com/2009/12/upgrade-led-hexbug-hack.html
In my last posting, I mused about the potential of making this cheap wind-up toy actually move about...
possibly avoid obstacles...
Well, I've had some time to think and plan, and dismember the cheerful little dude...
Here is the sum of his parts.
You'll notice the little white box lower middle of the picture. That is the spring wound mechanism that made him dance...
The is the space I have for electronics...
This is the underside of our friendly Hexbot Nano, with the battery removed. I'll be simply connecting to the positive and negative battery wires for this build.
Opened up, you can see the miniature "pager" motor with the offset weight that vibrates the Hexbot Nano.
I've also placed the protection diode inside the body of the Hexbots, as there was no room on the main circuit board.
I then hotglued the Dancing bot's feet onto the tops of the Hexbot Nano's and drilled a hole to pass the motor wires through.
Here is the blank board in it's body casing. That's it. That's all the room I have for electronics.
Luckily, an Attiny84 in socket, as well as a power connector and the ISP header all fit exactly on the board! I couldn't have asked for a better fit!
The Sharp GP2Y0A21YK Infrared Distance Sensor is hotglued onto the stub that held the original Dancing bot's head, and the LiPo battery is velcroed onto the front of the body.
Here, the ATtiny84 control board is placed into the body for sizing.



Watch this space over the next few days, as I get this guy up and dancing...
(currently having problems with balance/center of gravity... this too will be conquered)
References:
Programming an ATtiny w/ Arduino 1.0
LetsMakeRobots: Mogul - Program standalone ATtiny / ATmega chips through an Arduino
LetsMakeRobots: Ladvien - Robot Metallurgy 101 -- AVR Lesson Journal
LetsMakeRobots: attiny85 h-bridge ldr robot
LetsMakeRobots: Lumi - TinySpider
http://www.iheartrobotics.com/2009/12/upgrade-led-hexbug-hack.html
Friday, 16 May 2014
Upcoming fun project with dual Brushbot and ATtiny84...
While I'm waiting on parts (extruder, beated bed, and hotend) for my RepScrap 3D printer, I thought I would have a bit more fun...
Someone sent me this hilarious video, and it started me thinking...

So I happen to have a pair of these "electronic devices" in my parts bin. I think they are commercially known as "Hexbot Nanos"
They would effectively replace the toothbrush head and pager motor in the above video....
But I also received one of these little wind up distractions to the left here...
Mechanical spring wound clockworks makes him do a little dance...
For some strange reason, he hadn't quite made it to the kids yet... hmmm....
It looks like those Hexbots might just fit the bottom of his feet.....
Maybe I could run them directly from an ATtiny84 as in THIS blog...
yes, I know I should add a transistor to drive each motor, but when I looked up the current draw on a free running pager motor, low and behold they are around 20-40ma... well within the range of the ATtiny84 pins capability.
Someone sent me this hilarious video, and it started me thinking...
I frequently attend various vendor trade shows, and invariably, the vendors hand out useless trinkets as advertising... I usually do one of three things with these...
1) anything electronic gets tossed into the parts bin,
2) anything of a "toy" nature goes to my children (yes, I got that order straight)
3) everything else gets tossed them into the garbage.

So I happen to have a pair of these "electronic devices" in my parts bin. I think they are commercially known as "Hexbot Nanos"
They would effectively replace the toothbrush head and pager motor in the above video....
But I also received one of these little wind up distractions to the left here...
Mechanical spring wound clockworks makes him do a little dance...
For some strange reason, he hadn't quite made it to the kids yet... hmmm....
It looks like those Hexbots might just fit the bottom of his feet.....
Maybe I could run them directly from an ATtiny84 as in THIS blog...
yes, I know I should add a transistor to drive each motor, but when I looked up the current draw on a free running pager motor, low and behold they are around 20-40ma... well within the range of the ATtiny84 pins capability.
Current and RPM specs:
Voltage | RPM | Current (free) | Current (stall) |
1.5V | 9700 | 17.5mA | 120mA |
3.0V | 18420 | 22mA | 260mA |
5.0V | 31900 | 32.1mA | 420mA |
Add a Sharp IR proximity sensor onto his chest, a small LiPo battery on his back for balance, the gratuitous leds on the head, and I think we just may have ourselves the next project.... It doesn't get much simpler...
(ok, ok... yes, I'll likely wire in a connector for the AVR programmer... but that's it... well... and maybe find another pager motor to replace the spring wound mechanism that makes him dance... but THATs it... really...
maybe...)
References and prior art:
Monday, 12 May 2014
Using the Arduino PID Library for position control of X and Y axis on RepScrap printer
I've updated the test code I'm using to manage my X and Y axis DC motor / linear encoder closed loop controller.
I am currently using the Arduino PID Library by Brett Beauregard for this, and having great success. Videos to come tomorrow.
I am *NOT* going to explain what PID is, or how PID works.... I couldn't possibly do it justice. I'll simply point you to Brett's wonderful explanation:
In the following example, I set up two axis, X and Y, each using a DC motor run from the Adafruit Motor Shield V2. This shield provides PWM control for up to four separate DC motors via I2C communications.
I then set up two Quadrature encoders, one for each axis, using the Hardware Interrupts 0 and 1 (Arduino digital pins 2 and 3) and high speed digital port reads for one half of each encoder, and then validate the state of the other phase pin of the encoder during the interrupt routine:
Graciously borrowed from http://forum.arduino.cc/index.php?topic=41615.20;wap2
The ZERO endstop for each axis is set up using the Arduino PinChangeInterrupt library watching a pin attached to a photo-interrupter.
Inside the loop portion of my code, I run the PID controls as per the library, providing motor speed control via the Adafruit motor class, and periodically check to see if both X and Y axis have reached their goal. At which time, I randomly select a new target for each. When I get to the real application of this, the random selection of X and Y axis targets will be replaced by GRBL coordinates.
I then set up two Quadrature encoders, one for each axis, using the Hardware Interrupts 0 and 1 (Arduino digital pins 2 and 3) and high speed digital port reads for one half of each encoder, and then validate the state of the other phase pin of the encoder during the interrupt routine:
Graciously borrowed from http://forum.arduino.cc/index.php?topic=41615.20;wap2
The ZERO endstop for each axis is set up using the Arduino PinChangeInterrupt library watching a pin attached to a photo-interrupter.
I would certainly accept any advice on a proper sequence to initialize each axis to the ZERO endstop.
Right now, I arbitrarily send the carriage forward for 100ms assuming this is enough time to get on the positive side of the endstop, if we were beyond it. Then I set my current position to the maximum possible location, and start travelling back to the endstop, knowing that once I actually reach it, the interrupt routine will Zero out my position, and initialize my PID setpoint to zero as well, thus stopping travel at ZERO.
Is there a more efficient way of doing this?
Inside the loop portion of my code, I run the PID controls as per the library, providing motor speed control via the Adafruit motor class, and periodically check to see if both X and Y axis have reached their goal. At which time, I randomly select a new target for each. When I get to the real application of this, the random selection of X and Y axis targets will be replaced by GRBL coordinates.
And without further ado, here is my working code for precise position control in X and Y axis using the Arduino PID library:
https://github.com/michaeljball/RepScrap/**************************************************************************************** Lin_Enc_02.ino 05-12-2014 unix_guru at hotmail.com @unix_guru on twitter* http://arduino-pi.blogspot.com** This sketch allows you to run two salvaged printer carriages for X/Y axis using their* linear encoder strips for tracking.* This example uses the Arduino PID Library found at:* https://github.com/br3ttb/Arduino-PID-Library/archive/master.zip** Hardware Interrupt 0 on Digital pin2 is used to determine X-Axis position* Hardware Interrupt 1 on Digital pin3 is used to determine Y-Axis position* PinchangeInterrupt is used to identify the Zero Endstop for X and Y axis*****************************************************************************************/#include <Wire.h>#include <Adafruit_MotorShield.h>#include "utility/Adafruit_PWMServoDriver.h"#include <PID_v1.h>#include <PinChangeInt.h>#define frontstop = 100 // Right most encoder boundary#define backstop = 3600 // Left most encoder boundary// Create the motor shield object with the default I2C addressAdafruit_MotorShield AFMS = Adafruit_MotorShield();// Select which 'port' M1, M2, M3 or M4. In this case, M1Adafruit_DCMotor *XaxisMotor = AFMS.getMotor(1);Adafruit_DCMotor *YaxisMotor = AFMS.getMotor(2);const int XaxisENCPinA = 2; // X-AXIS encoder 1 on pins 2 and 4const int XaxisENCPinB = 4;const int XaxisENDSTOP = 10; // Endstop photointerrupter for X-Axisvolatile double XaxisENCPos = 0;const int YaxisENCPinA = 3; // Y-AXIS encoder 2 on pins 3 and 5const int YaxisENCPinB = 5;const int YaxisENDSTOP = 11; // Endstop photointerrupter for Y-Axisvolatile double YaxisENCPos = 0;double XaxisSpd, YaxisSpd; // Carriage speed from 0-255double XaxisPos, YaxisPos; // Current Carriage position/*working variables for PID routines*/// Tuning parametersfloat KpX=0, KpY=0; //Initial Proportional Gainfloat KiX=10, KiY=10; //Initial Integral Gainfloat KdX=0, KdY=0; //Initial Differential Gaindouble XaxisSetpoint, YaxisSetpoint; // Taget position for carriage// Instantiate X and Y axis PID controlsPID XaxisPID(&XaxisPos, &XaxisSpd, &XaxisSetpoint, KpX, KiX, KdX, DIRECT);PID YaxisPID(&YaxisPos, &YaxisSpd, &YaxisSetpoint, KpY, KiY, KdY, DIRECT);const int sampleRate = 1;long int reportTime;void setup() {Serial.begin(115200);Serial.println("Linear Encoder Test 05-12-2014");AFMS.begin(); // Set up MotorsXaxisMotor->run(BACKWARD); // Bring carriage to home position.XaxisMotor->setSpeed(70);delay(100); // Get endstop limiter working hereXaxisMotor->run(FORWARD); // Bring carriage to home position.XaxisMotor->setSpeed(0);
YaxisMotor->run(BACKWARD); // Bring carriage to home position.YaxisMotor->setSpeed(70);delay(100); // Get endstop limiter working hereYaxisMotor->run(FORWARD); // Bring carriage to home position.YaxisMotor->setSpeed(0);attachInterrupt(0, doXaxisENC, CHANGE); // encoder pin on interrupt 0 (pin 2)attachInterrupt(1, doYaxisENC, CHANGE); // encoder pin on interrupt 1 (pin 3)PCintPort::attachInterrupt(XaxisENDSTOP,doXaxisEndstop,FALLING); //X-axis Endstop ISRPCintPort::attachInterrupt(YaxisENDSTOP,doYaxisEndstop,FALLING); //Y-axis Endstop ISRrandomSeed(analogRead(0)); // Used to select random setpoints for testingXaxisPID.SetMode(AUTOMATIC); //Turn on the PID loopXaxisPID.SetSampleTime(sampleRate); //Sets the sample rateYaxisPID.SetMode(AUTOMATIC); //Turn on the PID loopYaxisPID.SetSampleTime(sampleRate); //Sets the sample ratereportTime = millis()+2000;}void loop() {uint8_t oldSREG = SREG; // Store interrupt status registercli();XaxisPos = XaxisENCPos;YaxisPos = YaxisENCPos;SREG = oldSREG; // Restore interrupt status register// Temporary to create random X and Y axis setpoints for testingif(millis() > reportTime) { // Only validate this every 2 secondsif(XaxisPos == XaxisSetpoint && YaxisPos == YaxisSetpoint) {// If both X-axis and Y-axis have reached their target - get new targetsXaxisSetpoint = random(200,3500); // Keep target within bounds of EndpointsYaxisSetpoint = random(200,3500); // Keep target within bounds of Endpoints}reportTime = millis()+2000;}// Manage X-axis positioningXaxisPID.Compute(); //Run the PID loopif(XaxisSetpoint < XaxisPos) XaxisMotor->run(BACKWARD); // Determine direction of travelelse XaxisMotor->run(FORWARD);XaxisMotor->setSpeed(XaxisSpd); // Apply PID speed to motor// Manage Y-axis positioningYaxisPID.Compute(); //Run the PID loopif(YaxisSetpoint < YaxisPos) YaxisMotor->run(BACKWARD); // Determine direction of travelelse YaxisMotor->run(FORWARD);YaxisMotor->setSpeed(YaxisSpd); // Apply PID speed to motor}/***************************************************************************************The following code was taken from http://forum.arduino.cc/index.php?topic=41615.20;wap2to utilize the fast port based encoder logic. Thank you Lefty!please go there for a full explanation of how this works. I have truncated the commentshere for brevity.***************************************************************************************/void doXaxisENC() { // ************** X- AXIS ****************if (PIND & 0x04) { // test for a low-to-high interrupt on channel A,if ( !(PIND & 0x10)) { // check channel B for which way encoder turned,XaxisENCPos = ++XaxisENCPos; // CW rotation}else {XaxisENCPos = --XaxisENCPos; // CCW rotation}}else { // it was a high-to-low interrupt on channel Aif (PIND & 0x10) { // check channel B for which way encoder turned,XaxisENCPos = ++XaxisENCPos; // CW rotation}else {XaxisENCPos = --XaxisENCPos; // CCW rotation}}} // End of interrupt code for encoder #1void doYaxisENC(){ // ************** X- AXIS ****************if (PIND & 0x08) { // test for a low-to-high interrupt on channel A,if (!(PIND & 0x20)) { // check channel B for which way encoder turned,YaxisENCPos = ++YaxisENCPos; // CW rotation}else {YaxisENCPos = --YaxisENCPos; // CCW rotation}}else { // it was a high-to-low interrupt on channel Aif (PIND & 0x20) { // check channel B for which way encoder turned,YaxisENCPos = ++YaxisENCPos; // CW rotation}else {YaxisENCPos = --YaxisENCPos; // CCW rotation}}} // End of interrupt code for encoder #2void doXaxisEndstop() {XaxisENCPos=0; // X-Axis Endstop indicates ZERO position}void doYaxisEndstop() {YaxisENCPos=0; // Y-Axis Endstop indicates ZERO position}
Updated diagram for reference:
References:
DIYDrones: Tutorial series for new Arduino PID library
http://brettbeauregard.com/blog/2011/04/improving-the-beginners-pid-introduction/
http://robotics.stackexchange.com/questions/1232/how-can-i-use-the-arduino-pid-library-to-drive-a-robot-in-a-straight-line
Tim Wescott's PID without a PHD
http://abigmagnet.blogspot.ca/2008/10/dc-motor-control-part-one.html
http://www.pdx.edu/nanogroup/sites/www.pdx.edu.nanogroup/files/2013_Arduino%20PID%20Lab_0.pdf
https://www.youtube.com/watch?v=ZZYgZjMnGXU
https://www.youtube.com/watch?v=wbmEUi2p-nA
http://blog.solutions-cubed.com/pid-motor-control-with-an-arduino/
http://forum.arduino.cc/index.php/topic,45169.0.html
http://playground.arduino.cc/Code/PIDLibrary
http://playground.arduino.cc/Code/PIDAutotuneLibrary
Arduino Playground: PinChangeInterrupt Library
https://code.google.com/p/arduino-pinchangeint/downloads/list
LetsMakeRobots: PID Control by Big Face
LetsMakeRobots: PID Tutorials for Line Following by Enigmerald
LetsMakeRobots: PID without a PHD by BDK6
LetsMakeRobots: Using Motor Encoders to Control Speed by Oddbot
Thursday, 8 May 2014
Further Progress on framing my RepScrap 3D printer.
Well, this is what the RepScrap looks like today.
I finished the Y-Axis table late last week, and tested the moment. It's a little sluggish with the printer motor driving the bed, but will do for now. I foresee burning this poor motor out, so will probably have to replace it with a gear motor at some point in time.
The Y-Axis bed is the glass top of the all-in-one printer's scanner. The aluminum cross bars come from the bottom track of a sliding closet door.
As I mentioned in my previous posting, the frame for this was scavenged from exterior railing extrusions.
Here, I am truing up frame that houses the Z-axis ball bearing slider rail, shown below. These drawer sliders seem to be very tight, as in, there doesn't seem to be much slop at all.
At the top of the Z-Axis frame, I am placing the two DC-Motor /Encoder assemblies used for the paper feed on the inkjet printers.
I am opting to run a threaded rod through each to drive the Z-axis gantry. It had been suggested over on Reddit, that I might have success with a taught wire or line looped around the rough tubing of the sheet feed roller, but I think the threaded rod will be easier to design and troubleshoot.

And below, is my test circuit for the motor/encoder interface.
One thing that I am doing instead of having a separate Optical Endstop for each axis, is that I am making a larger black bar at each end of the linear optical encoder strip. This can then be identified as a discrepancy during the encoder interrupt routine, and trip the endstop routine.
And a few more pictures of the Z-Axis gantry assembly with the X-Axis rail attached.

Friday, 2 May 2014
My Repscrap: DC motors and rotary encoders for Z-Axis too?
I took a few pictures this morning, to give me something to think about while I was at the cottage for the weekend.
Pictured here, to the right, is the frame I made up to house the Y-Axis table. You can see the carriage assembly, motor and rail running horizontally in this image. There are ball bearing slider rails in the "top" and "bottom" sections of the frame that will be attached to the Y-Axis carriage and table.
The frame itself is made from 3 inch extruded Vinyl exterior railing. It is 28" long to accommodate the travel of the Y-Axis table, and it is 16" wide. I will be putting threaded adjustable feet in each corner for leveling. The ball bearing slider rails fit very snugly inside the extrusion.
I have laid the X-Axis carriage and rail across it, simply to visualize the mounting options and location.
Pictured here, are two identical paper feed roller assemblies from scavenged Canon inkjet printers.
They are driven by brushless 12v DC motors, and have a high resolution rotary optical encoder on the end of the hollow paper feed shafts.
My train of thought is something like this...
If I were to cut the hollow shafts short... say 3 inches in length, then support them with bushings, I could cement a threaded rod inside them, and theoretically create a Z-Axis identical in function to many of the existing Reprap stepper motor Z-Axis implementations. But with 0.08mm resolution....
This is RepRrap Prusa implementation using two Z-Axis steppers...
This is just another view of the potential Z-Axis assemblies I have to work with.
I have another couple days until I'm home again to work on them. I would *love* to get some input and ideas as to how I should/could implement this.
Comments please...
Pictured here, to the right, is the frame I made up to house the Y-Axis table. You can see the carriage assembly, motor and rail running horizontally in this image. There are ball bearing slider rails in the "top" and "bottom" sections of the frame that will be attached to the Y-Axis carriage and table.
The frame itself is made from 3 inch extruded Vinyl exterior railing. It is 28" long to accommodate the travel of the Y-Axis table, and it is 16" wide. I will be putting threaded adjustable feet in each corner for leveling. The ball bearing slider rails fit very snugly inside the extrusion.
I have laid the X-Axis carriage and rail across it, simply to visualize the mounting options and location.
Now: On to the good stuff...
Pictured here, are two identical paper feed roller assemblies from scavenged Canon inkjet printers.
They are driven by brushless 12v DC motors, and have a high resolution rotary optical encoder on the end of the hollow paper feed shafts.
My train of thought is something like this...
If I were to cut the hollow shafts short... say 3 inches in length, then support them with bushings, I could cement a threaded rod inside them, and theoretically create a Z-Axis identical in function to many of the existing Reprap stepper motor Z-Axis implementations. But with 0.08mm resolution....
This is RepRrap Prusa implementation using two Z-Axis steppers...
This is just another view of the potential Z-Axis assemblies I have to work with.
I have another couple days until I'm home again to work on them. I would *love* to get some input and ideas as to how I should/could implement this.
Comments please...
Subscribe to:
Posts (Atom)