Close, I have to wire the FET and links, and cut the insulation gaps, a job best done when I can keep my eyes open. Time for bed I think Paul
Thats it wired, tested for short circuits etc and all seems ok, just needs the optoisolator plugging in. So that brings back to part 2 of the sketch The next part of the sketch deals with the DCC addresses ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // DCC 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<maxservos; i++) { if(address == servos.address) { if(enable) servos.output = 1; else servos.output = 0; } } } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// This is a sub-routine that the sketch calls each time it recieves a data packet - Essentially it looks at the packets on the DCC track bus, and detects if any are to do with the DCC accessory addresses of our servos, and if so sets the output to either 1 or 0, and if that is different to the current value then the servo will move (that bit is later in the program) Within all arduino sketches there are a minimum of two sections Setup & Main Loop or Loop This sketch has 4 definitions, routines, setup and Main loop The Setup section runs once after any definitions. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Setup (run once) ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void setup() { DCC.SetBasicAccessoryDecoderPacketHandler(BasicAccDecoderPacket_Handler, true); ConfigureFunctionsAndServos(); for(int i=0; i<maxservos; i++) { pinMode (servos.outputPin, OUTPUT ); digitalWrite (servos.outputPin, LOW); servos.angle = servos.offangle; // Set start up angle to avoid movement at power on } DCC.SetupDecoder( 0x00, 0x00, kDCC_INTERRUPT ); pinMode(2,INPUT_PULLUP); //Interrupt 0 with internal pull up resistor (can get rid of external 10k) pinMode(13,OUTPUT); digitalWrite(13,LOW); //led off at startup } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void setup() tell the sketch this is the setup section and runs between the first { and last } Firstly it starts the DCC packet handler Then uses a for / next loop ConfigureFunctionsAndServos(); for(int i=0; i<maxservos; i++) { pinMode (servos.outputPin, OUTPUT ); digitalWrite (servos.outputPin, LOW); servos.angle = servos.offangle; // Set start up angle to avoid movement at power on } to set every servo to the off position Next Setup the DCC input pin - D2 in our case which is also interupt 0 pins D2 & D3 are unique as they can be defined as normal digital I/O pins, or as a Interupt pin, any time the is a change on the pin, it will interupt the program to check what it is. DCC.SetupDecoder( 0x00, 0x00, kDCC_INTERRUPT ); pinMode(2,INPUT_PULLUP); //Interrupt 0 with internal pull up resistor (can get rid of external 10k) By setting pinMode(2,INPUT_PULLUP); and using the PULLUP the arduino uses an internal pullup resistor allowing me not to have to put one on the circuit board. and the last section pinMode(13,OUTPUT); digitalWrite(13,LOW); //led off at startup This sets pin 13 to an output, then sets the output off (LOW) Remember from part 1 the servos[0].outputPin = 13; was set to 13, so when the accy is moving the output pin 13 is on. Pin 13 also has a inbuilt led on the board so you can tell if the servo has been activated and should be moving. Now after a discussion with Ruud, as mentioned earlier he has pointed out the 10 servo max limitation of the servo library, but also that I can use the Analog ports A0 to A5 as digital I/O ports, now that is a game changer for me So the ports are mapped as follows D0 + D1 TX & RX serial comms ports, not used on this sketch, so could be used if needed. D2 set as input - Interupt 0 used for used for DCC data in. D3 to D12 Set as outputs and used a signal outputs for servos 1 to 10 D13 set as output and used to indicate active servo D14 set as output (this is actually port A0) and triggers the FET gate. so added to Ruud's sketch is the following 2 lines pinMode(14,OUTPUT); digitalWrite(14,HIGH); //turn FET gate on Were almost done now The work part of a sketch is called the Main Loop, because once the definitions and setup have completed, the main loops just keepd repeating itself untill stopped. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Main loop (run continuous) ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void loop() { static int addr = 0; DCC.loop(); // DCC library if(++addr >= maxservos) addr = 0; // Next address to test // Set servos output pin if (servos[addr].output) digitalWrite(servos[addr].outputPin, HIGH); else digitalWrite(servos[addr].outputPin, LOW); // Every 'servotimer' ms, modify setpoints and move servos 1 step (if needed) if (millis() > timetoupdatesetpoint) { timetoupdatesetpoint = millis() + servotimer; for (int n=0; n<maxservos; n++) { if (servos[n].output) servos[n].setpoint=servos[n].onangle; else servos[n].setpoint=servos[n].offangle; if (servos[n].angle < servos[n].setpoint) servos[n].angle++; if (servos[n].angle > servos[n].setpoint) servos[n].angle--; servos[n].servo.write(servos[n].angle); } } } //END MAIN LOOP This just keeps checking for DCC commands, and when it recieves one it checks to see if it applies to any on the Accy addresses assigned to the servos and if so then moves the servo. Next step is to connect everything up and test it. Paul
The only bit you need to know / do, is define the number of servos - lines 24 Then for each of the servos set the accy address, off & on point values. For windows pc's, open device manager And take a note of the active com ports Connect the 5V supply to the board, and connect the nano to the usb port of your PC. A new comm port should be displayed. In my case COM3 - note changing the port you connect to or going via a hub can change the port number. Open the arduino software and load the sketch, from where you saved it to. Goto the Tools >Port and select the the correct com port Note in the above screen shot under Board If it does not display Arduino Nano, then use the side menu to select the Arduino Nano. Click on the upload button, and the software will validate the sketch and upload it to the Nano. And when finished will display a few bits of information on how much free space is left, or give you an error message for any problems. Phew it loaded without errors Currently testing with a phone charger as a 5V supply (5.2V actually ), and is capable of powering the servo Now just need to set up a DCC feed to complete the testing. Paul
One slight modification - a 10K rersistor added between the FET Gate and ground. This is to prevent the gate voltage from floating and will ensure the gate is off untill the arduino has booted and activated the gate output (A0) So the final parts list is 1 x Arduino Nano 1 x 36 pin Female 0.1" pitch header strip 1 x 30 pin Male 0.1" pitch header strip 1 x 24 Row by 37 column Stripboard 2 x 0.1" pitch 2 pole terminal blocks 1 x 10K resistor 3 x 1K resistor 1 x IRLZ44N nMOSFET 1 x 1N4148 Diode 1 x 6N137 Optoisolator Various lengths of solid wire to make the connections. Anyone wanting the Arduino Sketch and or the Fritzing circuit diagram, PM me with your email address and I will send you the files. Paul
Finally got back into the shed today after being a dutiful Hubby, Dad, son in law, future father in law etc..Paul you have been a busy boy. This is looking very exciting. I'm on another project just now but will almost certainly will be into this next. Col
Completed moving my computer, and other DCC test stuff downstairs after my Mums visit over the christmas period.. Fitted the opto isolator, powered up the decoder, and powercab, and it worked first time. So I thought I better prove it and make a short video ..... https://youtu.be/nliEwpVziw8 Paul
Think I'm gonna have to try and get my head around this Arduino stuff sooner or later. I do find it interesting, but it could (will) lead to some headscratching on my part! Keith.
Have this up and running , thanks, excellent job Paul. Building a test rig now, just two points. I have a couple of old DMU's I will chip to play with. I intend to use jmri to run it eventually as the lenz LH90 hand control is a pain to use. Am I right in thinking the S88 module is a feed back system by the way ? Is it me or is it getting darker on this side ?? Col As a PS Keith I think you would enjoy these things mate, great range of plugins for them.
I have a convert, my job is done I said at the start of this thread that I would produce a non-DCC version ...... well I've been thinking about this, and may have an alternative solution - DCC for DC layouts. Has he finally sniffed too much flux I hear you ask, maybe, but ... One of the major advantages of DCC is the two wire track bus, this provides track power and control signals to the loco's and accessory decoders. And - what has this to do with DC you may ask, well what if we had an arduino powered simple command station, capable of sending the commands to the accessory decoders, only two wires around the layout, and place the accesory decoders where you need them. What do you think - worth looking into ? Paul
So the loco's run normally via DC and another set of bus wires specifically for arduino controlled accessories giving a DC system some of the automated perks of a type of digital system.
Any DCC accessories would work, Switch 8's, Hornby, Digitrax etc etc, provided they would normally be connected to the track / accessory bus, and not the propriety control busses. So yes DC to control the trains, and DCC to control points etc etc. Paul
Good morning world, I'm still kicking round the shed etc.. as there is no snow and therefore no ski season here . I'm sure this is because I won a free day ticket to the Nevis Range ski area in a raffle. So back to reality. Paul this is a great idea and indeed has been done by MERG (Kit 51 TB 11/11-12-13-14). I built it and it worked reasonably well but I had intermittent reliability problems ( mine I suspect not the kit) and put it aside for a rainy day. Having fumbled about with the Lenz LH90 hand control last week for the servo decoder I think this idea is well worth another visit. Are you thinking Arduino again? The merg kit uses pic 16f628's and I always struggled coding these things, although the merg chips come with the program loaded. Also up to 128 switches!! bit of overkill for my layout skills, matrix switch wiring .I watch and wait in anticipation / trepidation (delete as required). Col Just re-read your post where it says " well what if we had an arduino powered simple command station" Stupid boy
Hi Colin. You're not alone in finding the Lenz LH90 to be a pain in the backside to use! I have 3 LH100's which I use to control loco's, but only use my LH90 to control my motorised turntable, 'cos it's such a struggle (at least for me!) to remember the sequence to change the programme. In contrast, the LH100 is a doddle! Can I ask, are you using a Lenz control system, or am I seemingly the only member using Lenz? Keith.