Jump to content
 

Pandasum

Members
  • Posts

    5
  • Joined

  • Last visited

Profile Information

  • Location
    Upper Hutt, NZ

Recent Profile Visitors

86 profile views

Pandasum's Achievements

5

Reputation

  1. Hi Robin2, Thanks for the tip. The green LED on the Motor shield was lit so I figured all was OK, but I will now revert to using a 12V supply via the DC jack on the Arduino with the jumper or the direct shield connection without the jumper, rather than USB alone. P
  2. I have updated the Code posting so it should be able to be copied now. (Pasting as Javascript and leaving the line number box blank is the answer in case you were wondering) Thanks for the positive feedback and additional info. Apologies too to Deev - I also followed his post with interest (hence the stepper motors and gear racks) but neglected to acknowledge that as a source. Robin2 - Thanks for the tip. I also intend to use a separate power supply for the motors once installed but the Arduino power has been enough so far so I haven't done that yet. Cornerman - hope the Postman arrives soon and good luck! Cheers Paul
  3. Sorry about the code - if someone can give me directions I'll re-post cleanly so it can be copied. Thanks Paul
  4. Hi again, Here is the sensor schematic: (Apologies for the quality - I am also still learning how to use the fantastic Fritzing software too! The sensor itself is fairly robust and includes mounting holes so I reckon makes a good solution with a plastic post or similar attached to the turntable/moving part to trigger it. As I mentioned I got mine from Jaycar (Aus and NZ co) but I would expect Maplin or someone similar would have an equivalent. Here is the package image and datasheet: The resistor values used give an output voltage of around 0.12v when not blocked and just under 4v when obstructed which appears to be enough difference for the Arduino to detect the change of state. I am powering it directly from the 5v and gnd pins on the Arduino along with Ray's Isolator DC circuit and the seven segment LED. For reference here is the hardware list I have used: Arduino Duemilianove w/ ATmega328 Adafruit Motor Shield V2 DCC circuit as per Ray's posting Sensor circuit: ZD1901 x 1 220 ohm resistor x 1 4K7 ohm resistor x 1 Motors: Mercury Motor SM-42BYG011-25 (200 steps per revolution) "Transmission" Acetal MOD 1 gear racks 4 x 250mm and 12 tooth Spur gears by HUCO via Farnell (element 14) LED display RS987-894 (I think these are now obsolete (80's vintage from my components box) but I am sure there is a modern equivalent. And the code: (Hopefully it posts OK) Please note: I am a novice programmer so it isn't that elegant and although this works on my hardware, it is still a work in progress, so please use with caution (and at your own risk). Apart from that, please feel free to use it as you wish - any suggestions for improvements are welcome. Many Thanks also to Ray for the initial code posting which was a great help in getting me started. //////////////////////////////////////////////////////////////////////////////// // // DCC Turntable Control Test Routines (Accessory Address 200) #include <DCC_Decoder.h> #include <AccelStepper.h> #include <Wire.h> #include <Adafruit_MotorShield.h> #include "utility/Adafruit_PWMServoDriver.h" ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // Defines and structures // #define kDCC_INTERRUPT 0 typedef struct { int address; // Address to respond to } DCCAccessoryAddress; DCCAccessoryAddress gAddresses[1]; //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // // Adafruit Setup Adafruit_MotorShield AFMStop(0x60); // Default address, no jumpers // Connect stepper with 200 steps per revolution (1.8 degree) // to the M3, M4 terminals (blue,yellow,green,red) Adafruit_StepperMotor *myStepper2 = AFMStop.getStepper(200, 2); // you can change these to SINGLE, DOUBLE, INTERLEAVE or MICROSTEP! // wrapper for the motor! (3200 Microsteps/revolution) void forwardstep2() { myStepper2->onestep(FORWARD, MICROSTEP); } void backwardstep2() { myStepper2->onestep(BACKWARD, MICROSTEP); } //Variables long lngMotorPos; long lngTargetPosition; const long lngOneRev = 5690.021; int intPos = 0;//set initial LED value //set up for LED Display // bits representing segments A through G (and decimal point) for numerals 0-9 const byte numeral[10] = { //ABCDEFG /dp B11111100, // 0 B01100000, // 1 B11011010, // 2 B11110010, // 3 B01100110, // 4 B10110110, // 5 B00111110, // 6 B11100000, // 7 B11111110, // 8 B11100110, // 9 }; // pins for decimal point and each segment // dp,G,F,E,D,C,B,A const int segmentPins[8] = {7,11,10,9,8,6,5,4};//defines Arduino pins for each segment const int segmentSpin[6] = {4,5,6,8,9,10};// used to "rotate" the segments while motor is moving to sensor position // Now we'll wrap the stepper in an AccelStepper object AccelStepper stepper2(forwardstep2, backwardstep2); ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // Decoder Init // void ConfigureDecoder() { gAddresses[0].address = 200; gAddresses[1].address = 201; gAddresses[2].address = 202; gAddresses[3].address = 203; gAddresses[4].address = 204; gAddresses[5].address = 205; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // Basic accessory packet handler // void BasicAccDecoderPacket_Handler(int address, boolean activate, byte data) { // Convert NMRA packet address format to human address address -= 1; address *= 4; address += 1; address += (data & 0x06) >> 1; boolean enable = (data & 0x01) ? 1 : 0; // Check for DCC imput & determine entered address switch (address) { //Set target position based on address selected case 200: lngTargetPosition = lngOneRev*1; intPos=1; break; case 201: lngTargetPosition = lngOneRev*2; intPos=2; break; case 202: lngTargetPosition = lngOneRev*3; intPos=3; break; case 203: lngTargetPosition = lngOneRev*4; intPos=4; break; case 204: lngTargetPosition = lngOneRev*5; intPos=5; break; case 205: lngTargetPosition = lngOneRev*6; intPos=6; default: //nothing selected lngMotorPos=stepper2.currentPosition(); Serial.println(lngMotorPos,DEC); } // Serial.print("Basic addr: "); // Serial.print(address,DEC); // Serial.print(" activate: "); // Serial.println(enable,DEC); if ( enable ) { Serial.print("Motor at: "); lngMotorPos=stepper2.currentPosition(); Serial.println(lngMotorPos,DEC); Serial.print("Moving to: "); Serial.println(lngTargetPosition); showDigit(intPos); stepper2.moveTo(lngTargetPosition); while (stepper2.currentPosition() != lngTargetPosition) // move to target position stepper2.run(); digitalWrite(segmentPins[0],0); } else { // stepper2.moveTo(2000); lngMotorPos=stepper2.currentPosition(); Serial.println(lngMotorPos,DEC); delay(1000); // showDigit(intPos); } } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // Setup // void setup() //runs once to determine start position when sensor reached. { Serial.begin(9600); AFMStop.begin(); // Start the shield //configure pin3 as an input and enable the internal pull-up resistor pinMode(3, INPUT_PULLUP); //read the sensor (open collector type) value into a variable int sensorVal = digitalRead(3); //set stepper motor speed and acceleration stepper2.setMaxSpeed(10000.0); stepper2.setAcceleration(100.0); // stepper2.setSpeed(100); // stepper2.moveTo(800); for(int i=0; i < 8; i++)//assign pins for led display { pinMode(segmentPins[i], OUTPUT); // set segment and DP pins to output } showDigit(10); Serial.println("At switch off segments"); delay(1000); // if near reference point move away Serial.println("Check for reference point"); // delay(2000); sensorVal = digitalRead(3); while (sensorVal == HIGH) { Serial.println("At Sensor"); Serial.print("Motor at: "); lngMotorPos=stepper2.currentPosition(); Serial.println(lngMotorPos,DEC); intPos=0; showDigit(intPos); sensorVal = digitalRead(3); // forwardstep2(); delay(50); } // step forward to sensor index point while (sensorVal == LOW) { sensorVal = digitalRead(3); Serial.println("Moving to sensor"); backwardstep2(); //stepper2.run(); digitalWrite(segmentPins[0],0);//DP off //digitalWrite(segmentPins[1],1); for(int i=0; i < 7; i++)//Switch onsegments { digitalWrite(segmentSpin[i],1); delay(50); digitalWrite(segmentSpin[i],0); digitalWrite(segmentPins[0],1);//DP on //digitalWrite(segmentPins[1],1); } // delay(50); } DCC.SetBasicAccessoryDecoderPacketHandler(BasicAccDecoderPacket_Handler, true); ConfigureDecoder(); DCC.SetupDecoder( 0x00, 0x00, kDCC_INTERRUPT ); } void showDigit( int number) //display number on seven segment display { boolean isBitSet; for(int segment = 0; segment < 8; segment++) //was 1 { if( number < 0 || number > 9){ isBitSet = 0; // turn off all segments digitalWrite( segmentPins[segment], isBitSet); } else{ // isBitSet will be true if given bit is 1 isBitSet = bitRead(numeral[number], segment); } isBitSet = ! isBitSet; // remove this line if common cathode display digitalWrite( segmentPins[segment], isBitSet); } } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // Main loop // void loop() { static int addr = 0; //////////////////////////////////////////////////////////////// // Loop DCC library DCC.loop(); //////////////////////////////////////////////////////////////// // Loop Stepper stepper2.run(); }
  5. Hi All, I have been following this project with keen interest and have been working on automating a traverser for my OO layout using an Arduino, stepper motors and DCC accessory control (using a Hornby Elite). Thanks to Ray's pointers and inspiration on his turntable project I have made a reasonable amount of progress (at least on the electronics side), including incorporating an optical sensor and a seven segment LED display to indicate the selected lane. Next steps are to work on the drive mechanism (the traverser is mounted on ball bearing drawer slides and the plan is to mount the stepper motors to the traverser bed with a gear on each shaft driving along a rack fixed to the drawer slide supports. I will wire the stepper motors in parallel to the same output on the Arduino Motor shield which should keep them synchronized... I know Ray is planning an update shortly and I certainly don’t want to “step on his toes” but I thought I would take the liberty of posting this in case it is of any use to anyone in the meantime? Although I have adapted Ray’s code etc for my traverser, the principles could readily be used for a turntable. How it works: Once the Arduino is powered up, the stepper motors move the traverser bed slowly towards the sensor until that is tripped by a mechanical fixture breaking the IR beam and they then stop. The “zero” position is then set ready for that session. It is possible to save the last position on the Arduino while it is powered down but I figured it wouldn’t hurt to keep this as a calibration procedure for each session to ensure a known start point to calculate steps from without any need to calculate movement and direction relative to the current position. The desired track address can then be selected on the DCC controller and once enabled, the LED displays the desired track number and the motors will move to the designated position and stop when it is reached. The decimal point then lights up to indicate the traverser is in position. There is also acceleration built in to give a soft start and end to the movement to reduce any “jolt” to the rolling stock. By having set the zero position at the start, the Moveto command is used to drive the motors to move to a predetermined target position (number of steps) based on the track selected on the controller. I currently have six parallel tracks on 67mm centres so I have currently set it up to move a fixed number of steps multiplied by the track number to determine the step count required. However, I am planning to load the step counts for each of the track positions into an array at the start of the code so I can readily accommodate any variances between the physical track centres into the step count for each track. I also plan to add a “kill” switch for emergency stops (I probably should have done that first but as it is all on breadboard at this stage, I haven’t made the effort!) I am new to the forum so will upload the schematic for the sensor circuit and the code when I work out how to do that. The sensor I used is a ZD1901 photo interrupter from Jaycar here in NZ, but I am sure there would be suitable alternatives readily available elsewhere. Apologies too for such a long first post! Cheers Paul
×
×
  • Create New...