I got a new piece of old gear the other day, and it's FREE!
Here is a mug-shot of it, smelling of mildew and looking bad:
Yeah, it has some stickers on it, but who cares?
The yellow one mentions "Limited Calibration" limit: 1000MvAC & 200,2K Ohm ranges out of spec.
The red one mentions "Rejected or Uncertified" Pffft!
I opened it up for cleaning, here's a look at the internals:
Notice that the battery holder has broken but the springs are long enough to keep it in place.
Now that it's all clean, it looks like this:
All that's left to do is to actually use it, test its accuracy and maybe change the LCD for something with a backlight, or even 7segment leds because it's quite hard to read.
Momentum Zero
Going Nowhere, Not Fast
Sunday, August 26, 2012
Friday, November 26, 2010
Arduino, Steppers, EasyDriver and Python
After playing around with an Arduino and an EasyDriver (v43) I came up with the following solution. It is mostly inspired by Dan Thompson's Tutorial.
I tried unsuccessfully to use a binary communication scheme and ended up switching to ASCII and upping the speed to 115200 bauds. The Arduino code now uses the Messenger library which works quite well.
Here is a really ugly picture of the assembly: (stepper not included in picture)
Here is the Arduino sketch:
#includeMessenger message = Messenger(); ////// ED_v4 Step Mode Chart ////// // // // MS1 MS2 Resolution // // L L Full step (2 phase) // // H L Half step // // L H Quarter step // // H H Eighth step // // // //////////////////////////////////// const int DIR_PIN = 3; // PIN 3 = DIR const int STEP_PIN = 2; // PIN 2 = STEP const int MS1_PIN = 12; // PIN 13 = MS const int MS2_PIN = 9; // PIN 9 = MS2 const int SLEEP_PIN = 11; // PIN 12 = SLP const int LED_ERR = 7; unsigned int DIV=8; unsigned int DELAY=1600/DIV; int POSITION=0; int TARGET=0; int QUANTA = 10; int DIR=1; int MOVING=0; boolean bEnabled=false; int iPos=0; int iWait=0; void SetDivider( int div ); void SendSteps( int nb=1); void SetDirection( int dir ); void setup() { pinMode(DIR_PIN, OUTPUT); // set pin 3 to output pinMode(STEP_PIN, OUTPUT); // set pin 2 to output pinMode(MS1_PIN, OUTPUT); // set pin 13 to output pinMode(MS2_PIN, OUTPUT); // set pin 9 to output pinMode(SLEEP_PIN, OUTPUT); // set pin 12 to output pinMode(LED_ERR, OUTPUT); DIV=8; DELAY=1600/DIV; SetDivider( DIV ); Serial.begin(115200); // open the serial connection at 9600bps message.attach(messageCompleted); } void loop() { // The following line is the most effective way of // feeding the serial data to Messenger while ( Serial.available() ) { message.process( Serial.read() ); } MoveQuanta(); } void SendSteps( int nb) { for( int i=0; i<nb; ++i ) { // This LOW to HIGH change is what creates the.. digitalWrite(STEP_PIN, LOW); // .."Rising Edge" so the easydriver knows to when to step. digitalWrite(STEP_PIN, HIGH); delayMicroseconds(DELAY); } } void SetDirection( int dir ) { if( dir>0 ) { // CLOCKWISE DIR=1; digitalWrite(DIR_PIN, LOW); } else { // COUNTER-CLOCKWISE DIR=-1; digitalWrite(DIR_PIN, HIGH); } } void SetDivider( int div ) { switch( div ) { case 1: digitalWrite(MS1_PIN, LOW); digitalWrite(MS2_PIN, LOW); break; case 2: digitalWrite(MS1_PIN, HIGH); digitalWrite(MS2_PIN, LOW); break; case 4: digitalWrite(MS1_PIN, LOW); digitalWrite(MS2_PIN, HIGH); break; case 8: digitalWrite(MS1_PIN, HIGH); digitalWrite(MS2_PIN, HIGH); break; } } void MoveQuanta() { if( bEnabled ) { if( TARGET > POSITION ) { MOVING=1; SetDirection( 1 ); int steps = min(TARGET-POSITION, QUANTA); SendSteps( steps ); POSITION += steps; } else if( TARGET < POSITION ) { MOVING=1; SetDirection( -1 ); int steps = min(POSITION-TARGET, QUANTA); SendSteps( steps ); POSITION -= steps; } else { MOVING=0; } } } // Define messenger function void messageCompleted() { // commands: // e Enable Drives // d Disable Drives // sd999 Set Divider <int> // sw999 Set Wait <int> // gp Get Position // gd Get Divider // gw Get Wait // ma999 Move Absolute <int> // mr999 Move Relative <int> // rp Reset Position // x Stop All Movements if ( message.checkString("e") ) { /////////////////////////////////////// Enable digitalWrite(SLEEP_PIN, HIGH); bEnabled=true; } else if ( message.checkString("d") ) { /////////////////////////////////////// Disable digitalWrite(SLEEP_PIN, LOW); bEnabled=false; } if ( message.checkString("sd") ) { /////////////////////////////////////// Set Div int div = message.readInt(); if( div == 1 || div == 2 || div == 4 || div == 8 ) { DIV=div; SetDivider( DIV ); } } else if ( message.checkString("sw") ) { /////////////////////////////////////// Set Wait DELAY = message.readInt(); } else if ( message.checkString("sq") ) { /////////////////////////////////////// Set Quanta QUANTA = message.readInt(); } if ( message.checkString("im") ) { /////////////////////////////////////// Is Moving Serial.println( MOVING, DEC ); } if ( message.checkString("gd") ) { /////////////////////////////////////// Get Div Serial.println( DIV, DEC ); } else if ( message.checkString("gw") ) { /////////////////////////////////////// Get Wait Serial.println( DELAY, DEC ); } else if ( message.checkString("gp") ) { /////////////////////////////////////// Get Position Serial.println( POSITION, DEC ); } else if ( message.checkString("gq") ) { /////////////////////////////////////// Get Quanta Serial.println( QUANTA, DEC ); } else if ( message.checkString("gt") ) { /////////////////////////////////////// Get Target Serial.println( TARGET, DEC ); } if ( message.checkString("ma") ) { /////////////////////////////////////// Move Absolute if( bEnabled ) { int pos = message.readInt(); TARGET = pos; } } else if ( message.checkString("mr") ) { /////////////////////////////////////// Move Relative if( bEnabled ) { int pos = message.readInt(); TARGET += pos; } } else if ( message.checkString("rp") ) { /////////////////////////////////////// Reset Position POSITION=0; TARGET=0; } else if ( message.checkString("x") ) { /////////////////////////////////////// STOP! // stop on next MoveQuanta TARGET=POSITION; } else { digitalWrite( LED_ERR, HIGH ); } }
And here is the Python Stepper class:
# -*- coding: utf-8 -*- import serial import time ## The arduino can be reset by putting the DTR pin high, then low. ## This is normally done on connection by the PySerial module (on windows). ## This means that everytime a connection is made to the arduino, a reset is sent ## and about 5 seconds are necessary before sending commands. To prevent this, the ## line 61 in C:\Python26\Lib\site-packages\serial\serialwin32.py must be changed ## from: ## self._dtrState = win32file.DTR_CONTROL_ENABLE ## to: ## self._dtrState = win32file.DTR_CONTROL_DISABLE class Stepper: def __init__( self, COMPort ): self.COMMAND_ENABLE = "e" # no parameters self.COMMAND_DISABLE = "d" # no parameters self.COMMAND_SET_DIV = "sd " # <int> self.COMMAND_SET_WAIT= "sw " # <int> self.COMMAND_SET_QUANTA= "sq " # <int> self.COMMAND_GET_DIV = "gd" # no parameters self.COMMAND_GET_WAIT = "gw" # no parameters self.COMMAND_GET_QUANTA = "gq" # no parameters self.COMMAND_GET_TARGET = "gt" # no parameters self.COMMAND_GET_POSITION = "gp" # no parameters self.COMMAND_MOVE_ABS = "ma " # <int> self.COMMAND_MOVE_REL = "mr " # <int> self.COMMAND_RESET_POSITION = "rp" # no parameters self.COMMAND_STOP = "x" # no parameters self.COMMAND_IS_MOVING = "im" # no parameters self.Arduino = serial.Serial(COMPort, 115200, 8, 'N', 1 ) self.Arduino.open() def __del__(self): pass self.Disable() #self.Arduino.close() def _SendCommmand(self, command ): self.Arduino.write( command + "\r" ) def Enable(self): self._SendCommmand( self.COMMAND_ENABLE ) def Disable(self): self._SendCommmand( self.COMMAND_DISABLE ) def SetDiv(self, div): if div in [1,2,4,8]: self._SendCommmand( self.COMMAND_SET_DIV + str( div ) ) def GetDiv(self): self._SendCommmand( self.COMMAND_GET_DIV ) ret = self.Arduino.readline() return int(ret) def SetWait(self, wait): self._SendCommmand( self.COMMAND_SET_WAIT + str( wait ) ) def GetWait(self): self._SendCommmand( self.COMMAND_GET_WAIT ) ret = self.Arduino.readline() return int(ret) def SetQuanta(self, wait): self._SendCommmand( self.COMMAND_SET_QUANTA + str( wait ) ) def GetQuanta(self): self._SendCommmand( self.COMMAND_GET_QUANTA ) ret = self.Arduino.readline() return int(ret) def GetTarget(self): self._SendCommmand( self.COMMAND_GET_TARGET ) ret = self.Arduino.readline() return int(ret) def MoveRel(self, position): self._SendCommmand( self.COMMAND_MOVE_REL + str( position ) ) def MoveAbs(self, position): self._SendCommmand( self.COMMAND_MOVE_ABS + str( position ) ) def GetPosition(self): self._SendCommmand( self.COMMAND_GET_POSITION ) ret = self.Arduino.readline() return int(ret) def ResetPosition(self): self._SendCommmand( self.COMMAND_RESET_POSITION ) def Stop(self): self._SendCommmand( self.COMMAND_STOP ) def IsMoving(self): self._SendCommmand( self.COMMAND_IS_MOVING ) ret = self.Arduino.readline() return int(ret) == 1 def Reset(self): self.Arduino.setDTR( True ) self.Arduino.setDTR( False ) #should wait a few seconds after this! time.sleep(2)
Subscribe to:
Posts (Atom)