Jump to content
 

Deev

Members
  • Posts

    199
  • Joined

  • Last visited

Profile Information

  • Location
    Bristol

Recent Profile Visitors

582 profile views

Deev's Achievements

66

Reputation

  1. Yes, I've seen that. Everything about that layout is something else. Simply a masterpiece. Regarding the costs, hard to give a definitive figure, but here are my guesses: 1 x Controller (Einsy Rambo) = £70 1 x Optocoupler board = £5 4 x NEMA 17 stepper motors - 4 x £15 = £60 4 x 8mm leadscrews with POM nuts = 4 x £15 = £60 2 x pairs 600mm drawer runners - 2 x £10 = £20 Aluminium section = £30 Sheet of 15mm Plywood = £100 Cable chain = £10 200w Power supply = £20 Screws, glue, microswitches, bolts = £20 TOTAL = £395 Add to this the track and copper-clad. I may point out that you could buy a lot of points and motors for £400.
  2. Hi Hector, Well, I like your plans - I'm always a massive fan of complex multi-level layouts. What I will say is that the traverser looks quite short. I don't know what length trains you'll be running, but I reckoned on a traverser about 2500mm long to allow a full length HST set to be moved. If you're running shorter rakes, then this won't be an issue. This said, your layout might look better served using more traditional points and servo motors to avoid the obvious complexity, not to mention the cost, of scratch-building a traverser. If you are after the technical challenge of it, then I commend you. Other considerations are the amount of space in front of and behind the traverser you'd need to allow it to traverse. Also, have you considered building a helix so that you have the possibility of a second traverser? How are you going to run cabling to the traverser? Are you going to fit sensors on it to automatically stop trains? A cable chain might be a worthwhile investment here. My final thoughts are with a traverser, to buy the most expensive and powerful mechanism you can. Depending on the length of the traverser, and the amount of stock on it, you're liable to have a lot of weight to shift, so you'll probably need multiple NEMA17s, say four at least by my reckoning. If I were building one, I'd use the best mechanisms I could find (8mm diameter, 8mm pitch, 4 threaded leadscrews with POM (not brass) nuts and use an Einsy Rambo control board, purely because all the hard work is done for you and it can run 4 steppers silently. Having a noisy stepper driver would drive you insane after a while. It would be annoying to build a traverser cheaply and then curse every time it jammed or stopped working.
  3. I managed to get one of these working, but it wasn't easy and I moved house before I could take acceptable photos of it. My experience is that you need provide much more power than you think you'll need, but drawer runners are the things to use as they are fiendishly accurate. I'd look at a 3d-printer driver board and NEMA17 motors. The world of 3d printers has exploded over the last 10 years and you can buy a fully-populated motherboard that includes the Arduino, silent motor drivers (eg. TMC2208) as well as all the connectors for things like limit switches for less than £60.. Search for Einsy RAMBO. Obviously you'll need to write your own code for it (and before you ask, I've lost the code that I wrote) but it isn't actually that difficult. You'll also need to work out a way of calibrating it, either through limit switches or through stall-monitoring through back-EMF.
  4. Hi Adam, I can't remember exactly how I did it, probably set a 'float' with the number of the road in it. I lost my code, so will have to start again on it. Dave
  5. Interesting. I'd looked at the NEMA23 and was surprised how high the current draw on them was, which is something I was hoping to avoid. Instead I was planning on using 8 x NEMA17 motors directly mounted to 8mm 4-lead leadscrews with a balancing gas strut to help the lift.
  6. I recently travelled from London Heathrow to Filton Abbeywood and noticed this whilst waiting for a security check to take place on the platform at T5. Looks like the doors of the Heathrow Express run on what are basically drawer runners, making me think that they'll be more than adequate for my vertical storage yard.
  7. Wow, that's fantastic. Would love to see it in action, can you upload to YouTube then post the link?
  8. This is a note to self post rather than noting any progress. Height of stock + track = 55mm. 65mm would give ample clearance, so 70mm between top of bed and bottom of mechanism.
  9. Hi JD, I'm curious as to why you're using a photo interruptor? Can you explain? Anyway, if you take a look at the link to my Filton Abbeywood thread (link on my signature) you'll find the code and some experimentation with the HES. Note: the code is for RS485 and JMRI. Let me know if it works.
  10. Hi JB, It'd be a useful skill - ou can tailor your own code that way, and use the Arduino to do pretty much whatever you want. I've managed to get mine to work as a position feedback sensor! Dave
  11. Solved it! The problem lay with the Arduino code. I reprogrammed it to call an interrupt when the Hall Effect Sensor went high, and hey presto, it worked!
  12. No problem, I don;t know that it'll actually work as I've not been able to test it!
  13. Try the code below. It might work. Use accessory decoder addresses 711 to 717. Dave #include <DCC_Decoder.h> #include <AFMotor.h> AF_Stepper motor(200, 1); ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // Defines and structures // #define kDCC_INTERRUPT 0 typedef struct { int address; // Address to respond to byte output; // State of output 1=on, 0=off int road; // Position of road on the traverser boolean isDigital; // true=digital, false=analog. If analog must also set analogValue field boolean isFlasher; // true=flash output, false=no time, no flash. byte analogValue; // Value to use with analog type. int durationMilli; // Milliseconds to leave output on for. 0 means don't auto off unsigned long onMilli; // Used internally for timing unsigned long offMilli; // } DCCAccessoryAddress; DCCAccessoryAddress gAddresses[8]; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // Decoder Init // void ConfigureDecoder() { gAddresses[0].address = 711; gAddresses[0].output = 1; gAddresses[0].road = 0; gAddresses[0].isDigital = true; gAddresses[0].isFlasher = false; gAddresses[0].analogValue = 250; gAddresses[0].durationMilli = 0; gAddresses[1].address = 712; gAddresses[1].output = 1; gAddresses[1].road = 1; gAddresses[1].isDigital = true; gAddresses[1].isFlasher = false; gAddresses[1].analogValue = 0; gAddresses[1].durationMilli = 0; gAddresses[2].address = 713; gAddresses[2].output = 0; gAddresses[2].road = 2; gAddresses[2].isDigital = true; gAddresses[2].isFlasher = true; gAddresses[2].analogValue = 250; gAddresses[2].durationMilli = 500; gAddresses[3].address = 714; gAddresses[3].output = 0; gAddresses[3].road = 3; gAddresses[3].isDigital = true; gAddresses[3].isFlasher = true; gAddresses[3].analogValue = 0; gAddresses[3].durationMilli = 500; gAddresses[4].address = 715; gAddresses[4].output = 0; gAddresses[4].road = 4; gAddresses[4].isDigital = true; gAddresses[4].isFlasher = false; gAddresses[4].analogValue = 250; gAddresses[4].durationMilli = 0; gAddresses[5].address = 716; gAddresses[5].output = 0; gAddresses[5].road = 5; gAddresses[5].isDigital = true; gAddresses[5].isFlasher = false; gAddresses[5].analogValue = 0; gAddresses[5].durationMilli = 0; gAddresses[6].address = 717; gAddresses[6].output = 0; gAddresses[6].road = 6; gAddresses[6].isDigital = true; gAddresses[6].isFlasher = false; gAddresses[6].analogValue = 0; gAddresses[6].durationMilli = 0; gAddresses[7].address = 718; gAddresses[7].output = 0; gAddresses[7].road = 7; gAddresses[7].isDigital = true; gAddresses[7].isFlasher = false; gAddresses[7].analogValue = 0; gAddresses[7].durationMilli = 0; // // Setup output pins // for(int i=0; i<(int)(sizeof(gAddresses)/sizeof(gAddresses[0])); i++) // { // if( gAddresses.outputPin ) // { // pinMode( gAddresses.outputPin, OUTPUT ); // } // gAddresses.onMilli = 0; // gAddresses.offMilli = 0; // } } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // 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; for(int i=0; i<(int)(sizeof(gAddresses)/sizeof(gAddresses[0])); i++) { if( address == gAddresses.address ) { // Serial.print("Basic addr: "); // Serial.print(address,DEC); // Serial.print(" activate: "); // Serial.println(enable,DEC); if( enable ) { gAddresses.output = 1; gAddresses.onMilli = millis(); gAddresses.offMilli = 0; }else{ gAddresses.output = 0; gAddresses.onMilli = 0; gAddresses.offMilli = millis(); } } } } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // Setup // int posn = 0; void setup() { // DCC setup Serial.begin(9600); // set up Serial library at 9600 bps DCC.SetBasicAccessoryDecoderPacketHandler(BasicAccDecoderPacket_Handler, true); ConfigureDecoder(); DCC.SetupDecoder( 0x00, 0x00, kDCC_INTERRUPT ); // Stepper setup motor.setSpeed(90); // 90 rpm } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // Main loop // void loop() { static int addr = 0; //////////////////////////////////////////////////////////////// // Loop DCC library DCC.loop(); //////////////////////////////////////////////////////////////// // Bump to next address to test if( ++addr >= (int)(sizeof(gAddresses)/sizeof(gAddresses[0])) ) { addr = 0; } //////////////////////////////////////////////////////////////// // Turn off output? // if( gAddresses[addr].offMilli && gAddresses[addr].offMilli<millis() ) // { // // Clear off time // gAddresses[addr].offMilli = 0; // // // Disable output // if( gAddresses[addr].isDigital ) // { // digitalWrite( gAddresses[addr].outputPin, LOW); // }else{ // analogWrite( gAddresses[addr].outputPin, 0); // } // // // If still enabled and a flash type, set on time // if( gAddresses[addr].output && gAddresses[addr].isFlasher) // { // gAddresses[addr].onMilli = millis() + gAddresses[addr].durationMilli; // }else{ // gAddresses[addr].output = 0; // } // // return; // } //////////////////////////////////////////////////////////////// // Turn on output? if( gAddresses[addr].onMilli && gAddresses[addr].onMilli<=millis() ) { // Clear off time gAddresses[addr].onMilli = 0; // Enable output if(gAddresses[addr].road-posn == 0) { Serial.print("Position: "); Serial.println(posn, DEC); Serial.print("Moving to: "); Serial.println(gAddresses[addr].road, DEC); Serial.println("Moving: 0"); posn = gAddresses[addr].road; Serial.print("New position: "); Serial.println(posn, DEC); Serial.println(" "); delay (200); } else if(gAddresses[addr].road-posn == -1) { Serial.print("Position: "); Serial.println(posn, DEC); Serial.print("Moving to: "); Serial.println(gAddresses[addr].road, DEC); Serial.println("Moving: -1"); posn = gAddresses[addr].road; motor.step(250, BACKWARD, DOUBLE); Serial.print("New position: "); Serial.println(posn, DEC); Serial.println(" "); delay (200); } else if(gAddresses[addr].road-posn == -2) { Serial.print("Position: "); Serial.println(posn, DEC); Serial.print("Moving to: "); Serial.println(gAddresses[addr].road, DEC); Serial.println("Moving: -2"); posn = gAddresses[addr].road; motor.step(500, BACKWARD, DOUBLE); Serial.print("New position: "); Serial.println(posn, DEC); Serial.println(" "); delay (200); } else if(gAddresses[addr].road-posn == -3) { Serial.print("Position: "); Serial.println(posn, DEC); Serial.print("Moving to: "); Serial.println(gAddresses[addr].road, DEC); Serial.println("Moving: -3"); posn = gAddresses[addr].road; motor.step(750, BACKWARD, DOUBLE); Serial.print("New position: "); Serial.println(posn, DEC); Serial.println(" "); delay (200); } else if(gAddresses[addr].road-posn == -4) { Serial.print("Position: "); Serial.println(posn, DEC); Serial.print("Moving to: "); Serial.println(gAddresses[addr].road, DEC); Serial.println("Moving: -4"); posn = gAddresses[addr].road; motor.step(1000, BACKWARD, DOUBLE); Serial.print("New position: "); Serial.println(posn, DEC); Serial.println(" "); delay (200); } else if(gAddresses[addr].road-posn == -5) { Serial.print("Position: "); Serial.println(posn, DEC); Serial.print("Moving to: "); Serial.println(gAddresses[addr].road, DEC); Serial.println("Moving: -5"); posn = gAddresses[addr].road; motor.step(1250, BACKWARD, DOUBLE); Serial.print("New position: "); Serial.println(posn, DEC); Serial.println(" "); delay (200); } else if(gAddresses[addr].road-posn == -6) { Serial.print("Position: "); Serial.println(posn, DEC); Serial.print("Moving to: "); Serial.println(gAddresses[addr].road, DEC); Serial.println("Moving: -6"); posn = gAddresses[addr].road; motor.step(1500, BACKWARD, DOUBLE); Serial.print("New position: "); Serial.println(posn, DEC); Serial.println(" "); delay (200); } else if(gAddresses[addr].road-posn == -7) { Serial.print("Position: "); Serial.println(posn, DEC); Serial.print("Moving to: "); Serial.println(gAddresses[addr].road, DEC); Serial.println("Moving: -7"); posn = gAddresses[addr].road; motor.step(1750, BACKWARD, DOUBLE); Serial.print("New position: "); Serial.println(posn, DEC); Serial.println(" "); delay (200); } else if(gAddresses[addr].road-posn == 1) { Serial.print("Position: "); Serial.println(posn, DEC); Serial.print("Moving to: "); Serial.println(gAddresses[addr].road, DEC); Serial.println("Moving: +1"); posn = gAddresses[addr].road; motor.step(250, FORWARD, DOUBLE); Serial.print("New position: "); Serial.println(posn, DEC); Serial.println(" "); delay (200); } else if(gAddresses[addr].road-posn == 2) { Serial.print("Position: "); Serial.println(posn, DEC); Serial.print("Moving to: "); Serial.println(gAddresses[addr].road, DEC); Serial.println("Moving: +2"); posn = gAddresses[addr].road; motor.step(500, FORWARD, DOUBLE); Serial.print("New position: "); Serial.println(posn, DEC); Serial.println(" "); delay (200); } else if(gAddresses[addr].road-posn == 3) { Serial.print("Position: "); Serial.println(posn, DEC); Serial.print("Moving to: "); Serial.println(gAddresses[addr].road, DEC); Serial.println("Moving: +3"); posn = gAddresses[addr].road; motor.step(750, FORWARD, DOUBLE); Serial.print("New position: "); Serial.println(posn, DEC); Serial.println(" "); delay (200); } else if(gAddresses[addr].road-posn == 4) { Serial.print("Position: "); Serial.println(posn, DEC); Serial.print("Moving to: "); Serial.println(gAddresses[addr].road, DEC); Serial.println("Moving: +4"); posn = gAddresses[addr].road; motor.step(1000, FORWARD, DOUBLE); Serial.print("New position: "); Serial.println(posn, DEC); Serial.println(" "); delay (200); } else if(gAddresses[addr].road-posn == 5) { Serial.print("Position: "); Serial.println(posn, DEC); Serial.print("Moving to: "); Serial.println(gAddresses[addr].road, DEC); Serial.println("Moving: +5"); posn = gAddresses[addr].road; motor.step(1250, FORWARD, DOUBLE); Serial.print("New position: "); Serial.println(posn, DEC); Serial.println(" "); delay (200); } else if(gAddresses[addr].road-posn == 6) { Serial.print("Position: "); Serial.println(posn, DEC); Serial.print("Moving to: "); Serial.println(gAddresses[addr].road, DEC); Serial.println("Moving: +6"); posn = gAddresses[addr].road; motor.step(1500, FORWARD, DOUBLE); Serial.print("New position: "); Serial.println(posn, DEC); Serial.println(" "); delay (200); } else if(gAddresses[addr].road-posn == 7) { Serial.print("Position: "); Serial.println(posn, DEC); Serial.print("Moving to: "); Serial.println(gAddresses[addr].road, DEC); Serial.println("Moving: +7"); posn = gAddresses[addr].road; motor.step(1750, FORWARD, DOUBLE); Serial.print("New position: "); Serial.println(posn, DEC); Serial.println(" "); delay (200); } else { return; } } } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  14. Hi JB, Sorry, I can't because I don't have it any more. Have a look at post #80 as there are links to some code there. You'll probably have to do some rewriting of the code as it is very unlikely that it'll do exactly what you want. Always good to practice some Arduino code writing though! DAve
×
×
  • Create New...