Posted June 1, 20159 yr After a month, my Arduino clone has arrived from China. I plan to use it to add some inexpensive automation to our LUG's ad hoc layout. We are starting to display trains and don't have anything permanently built. Some of our events are outside in the park where there is no plug in power. One of the requirements would be battery power option. We are basically starting new with the current LEGO train and power offerings. We agreed to make Power Functions our club standard. I selected an Arduino clone. I figured for $4 USD, it is not a big lost if I fried it. There is a reason it is $4. The clone is not quite exactly the same as the real Arduino UNO. It uses a CH340 USB to serial chip instead of the FTDI USB to serial chip found on the real Arduino. In order for the Arduino IDE to communicate with the board, the CH341 driver has to be installed. It doesn't come with the IDE software from the Arduino website. The driver can be downloaded from the Chinese manufacturer's website. Note the site is in Chinese: http://www.wch.cn/do...341SER_EXE.html For a quick test, I hooked up an IR LED desoldered from an old DVD player remote to the board and wrote a simple sketch. I made use of a LEGO Power Function library (http://forum.arduino...p?topic=89310.0) Some resources on the Internet say IR LED in the 940nm range works best for Power Function IR receivers. It worked! And it was not as difficult as I thought it would be. I've never used an Arduino before. More eBay parts are to arrive from China. I'm planning to use reed switches for detection. I think they are the simplest to set up and tear down with just two wires to connect. I ordered inexpensive SG90 servo motors to control the switches. I still have to figure out how to mount them on other club members switch tracks and remove at the end of events. I think this is going to be fun.
June 2, 20159 yr I keep hearing about how there's extra codes left over in the PF protocol that aren't being used right now. What happens if you add those codes into the sketch? Do they do anything special?
June 2, 20159 yr Author I keep hearing about how there's extra codes left over in the PF protocol that aren't being used right now. What happens if you add those codes into the sketch? Do they do anything special? Which codes are those? Are they implemented in the PF IR receivers (V1 or V2)?
June 2, 20159 yr Yes, if you google, "lego power functions protocol" you will get hits like this. Oh, and there are at least 3 versions of IR receivers, 1.0, 1.1 and 2.... oh, wait, look at the file title, looks to be for 1.2 so presumably the code should apply to 1.2 and perhaps the other versions. If your IR receiver was purchased since 2010 and is not marked v2 then this code is probably for you. One of the big things about this code is that it lets you set a specific speed instead of simply "increase/decrease". I think there was some discussion that not all of the functions work on v1.0. I THINK the newer versions of v1 the green led on the receiver turns on momentarily when powered up.
June 2, 20159 yr Author Interesting. They added an address bit in the protocol that could be used for an additional 4 channels. According to Philio, there is a bug with single pin mode on the version 1.0 of the IR Receiver. It appears that all my IR receivers are version 1.1 that blink blink when powered on. Are you refering PWM to set the speed to one of 7 levels? I used this in the video of my Amtrak train engine. I start off with level 4 in reverse. Stop and then level 3 forward... Level 7 was too much around the curve with the tracks sliding around on the folding table. void loop() { lego.SingleOutput(0, PWM_REV4, RED, CH2); delay(5000); lego.SingleOutput(0, PWM_FLT, RED, CH2); delay(1000); lego.SingleOutput(0, PWM_FWD3, RED, CH2); delay(5000); lego.SingleOutput(0, PWM_FWD4, RED, CH2); delay(5000); lego.SingleOutput(0, PWM_FWD5, RED, CH2); delay(5000); lego.SingleOutput(0, PWM_FWD6, RED, CH2); delay(15000); lego.SingleOutput(0, PWM_FWD5, RED, CH2); delay(5000); lego.SingleOutput(0, PWM_FWD4, RED, CH2); delay(5000); lego.SingleOutput(0, PWM_FWD3, RED, CH2); delay(5000); lego.SingleOutput(0, PWM_FLT, RED, CH2); delay(1000); } I think Roland Wiersma's LEGO Power Function library also supports the PWM increase/decrease modes. I found this in his header file. #define INC_PWM 0x4 #define DEC_PWM 0x5 I haven't tried all the different modes. I am not sure I need to use them all to operate trains although they could be handy to "momentum" brake the train into a station and stuff like that. Maybe I could implement speed sensing with two or more reed switches using time between switch trigger to calculate train speed. Positive Train Control so I don't get my Amtrak train fly off the curve. Another idea might be to let kids at events control the trains with the IR Speed Remote and use the Arduino to monitor and send an over-ride stop or slow the train command if the kids break a speed limit or run a signal.
June 6, 20159 yr Author My reed switch order has arrived from China. This calls for a quick test. The LED goes on when the reed switch detects the train motor's magnetic field. To test I put wrote this simple Arduino sketch making use of Roland Wiersma's PF library. ======================== /* Train move with detection Channel 1 Blue dr_spock_888 June 5, 2015 LEGOPowerFunctions library by Roland Wiersma */ #include <legopowerfunctions.h> LEGOPowerFunctions lego(12); // IR LED on pin 12 const int reed1Pin = 2; // Reed switch1 on pin 2 const int ledPin = 13; // LED on pin 13 int reed1State = 0; // Variable for reading reed switch1 status int reed1Pass = 0; // Variable for counting train passing reed switch1 int dtime = 2000; // Delay time void setup() { pinMode(ledPin, OUTPUT); // Init LED pin as output pinMode(reed1Pin, INPUT); // Init reed switch1 as input lego.SingleOutput(0, PWM_FWD1, BLUE, CH1); // Start up train delay(dtime); lego.SingleOutput(0, PWM_FWD2, BLUE, CH1); delay(dtime); lego.SingleOutput(0, PWM_FWD3, BLUE, CH1); delay(dtime); lego.SingleOutput(0, PWM_FWD4, BLUE, CH1); delay(dtime); lego.SingleOutput(0, PWM_FWD5, BLUE, CH1); } void loop() { reed1State = digitalRead(reed1Pin); // Read state of reed switch1 if (reed1State == HIGH) { digitalWrite(ledPin,HIGH); // Turn on LED delay(500); digitalWrite(ledPin, LOW); // Turn off LED reed1Pass = reed1Pass + 1; // Increment pass reed switch1 } if (reed1Pass > 5) { lego.SingleOutput(0, PWM_FWD4, BLUE, CH1); // Slow down train delay(dtime); lego.SingleOutput(0, PWM_FWD3, BLUE, CH1); delay(dtime); lego.SingleOutput(0, PWM_FWD2, BLUE, CH1); delay(dtime); lego.SingleOutput(0, PWM_FWD1, BLUE, CH1); delay(dtime); lego.SingleOutput(0, PWM_FLT, BLUE, CH1); // Stop the train delay(10000); // Wait 10 seconds lego.SingleOutput(0, PWM_FWD1, BLUE, CH1); // Start up train delay(dtime); lego.SingleOutput(0, PWM_FWD2, BLUE, CH1); delay(dtime); lego.SingleOutput(0, PWM_FWD3, BLUE, CH1); delay(dtime); lego.SingleOutput(0, PWM_FWD4, BLUE, CH1); delay(dtime); lego.SingleOutput(0, PWM_FWD5, BLUE, CH1); reed1Pass = 0; // Reset pass reed switch1 } } ====================== CAUTION: Be careful with glass reed switches. They break easily. Sharp glass.
June 14, 20159 yr Author What is your testing result? I am interested in that! It seems to work as programmed. But I did notice as the battery in the train engine worn down the train wasn't stopping at the same spot originally. A possible solution might be to use two reed switches. First one triggers train slow down routine. The second triggers the slam on brake command. Hi, that looks to work really well Thank you.
June 15, 20159 yr Author Can you tell me where did you buy that clone arduini? I ordered on eBay from one of the sellers in China called Worldchips.
June 15, 20159 yr I ordered on eBay from one of the sellers in China called Worldchips. Thanks! But there are a lot of arduino items, can you tell me your item's name? I am new at arduino:(
June 15, 20159 yr Author Thanks! But there are a lot of arduino items, can you tell me your item's name? I am new at arduino:( No problem, I'm new at Arduino too. UNO R3 ATmega328P CH340 Mini USB Board for Compatible-Arduino This may sound stupid but what is the use of arduino? Arduino is an open-source electronics platform based on easy-to-use hardware and software. It's intended for anyone making interactive projects. In LEGO terms, think of it like a very inexpensive Mindstorm NXT.
July 20, 20159 yr Author Now that Brickfete is over. I have a little more time to play with my Arduino like Train PONG between two magnetic reed switches. I think this could morph into a Great Ball Contraption. I could use the red channel on the IR receiver to drive a motor to operate a dump car.
July 20, 20159 yr This may sound stupid but what is the use of arduino? Arduino is a software + hardware platform (open source) around mostly Atmel Microcontrollers. A microcontroller is a computer in a chip (it has a processor, internal and 'external' memory to run programs etc.). I'm working on a transfer table that uses Arduino with PF compatibility right now :) Since it is a little and inexpensive computer you can program stuff in it to control your house, a robot or your LEGO. In some Railbricks there are tutorials of how to do this (I wrote them). p.s. although the glass reed sensors are less expensive, better try to use these: http://www2.mouser.c...cs/Hamlin-MDSR/
July 20, 20159 yr Another idea might be to let kids at events control the trains with the IR Speed Remote and use the Arduino to monitor and send an over-ride stop or slow the train command if the kids break a speed limit or run a signal. This is a great idea, but there would be as much use for it at our home:) Have you tried using photoresistors to sense the trains? I used them many years ago for an N-scale railway to control level crossing lights. The advantage is it can sense all of the cars, not just the motor. I agree, reed switches are the way to go for signalling and train control.
July 20, 20159 yr This is a great idea, but there would be as much use for it at our home:) Have you tried using photoresistors to sense the trains? I used them many years ago for an N-scale railway to control level crossing lights. The advantage is it can sense all of the cars, not just the motor. I agree, reed switches are the way to go for signalling and train control. The reed sensors will also detect the PF motors :) I also program emergency stops, you just make a for loop and fire a stop command at each channel / color. @dr_spock: it is better to try to avoid delay statements since they will essentially block your entire Arduino loop and then you can't react to input changes anymore (unless you use interrupts). An other advice is to use state machines. They are a kind of design pattern that will really help to understand how the states of your own system works. I'll try to add my own code to github in af few days/weeks to give an idea how to do that (I teach programming basics also embedded programming to sophomores in college ;))
July 20, 20159 yr Author This is a great idea, but there would be as much use for it at our home:) Have you tried using photoresistors to sense the trains? I used them many years ago for an N-scale railway to control level crossing lights. The advantage is it can sense all of the cars, not just the motor. I agree, reed switches are the way to go for signalling and train control. Thanks. I did look at photoresistors. I had some concerns with passing clouds confusing the sensors since our LUG display at outdoor events. We could probably put a strong magnet in a caboose or FRED device if end of train detection is needed. The reed sensors will also detect the PF motors :) I also program emergency stops, you just make a for loop and fire a stop command at each channel / color. @dr_spock: it is better to try to avoid delay statements since they will essentially block your entire Arduino loop and then you can't react to input changes anymore (unless you use interrupts). An other advice is to use state machines. They are a kind of design pattern that will really help to understand how the states of your own system works. I'll try to add my own code to github in af few days/weeks to give an idea how to do that (I teach programming basics also embedded programming to sophomores in college ;)) I made an Arduino device that sends out a stream of TV power off/on IR codes. I suppose it can be done blasting out the halt codes for Power Functions and mess up your Tech Ball opponents. I noticed that it just sits there with the delay() statement. It could be ok if I am not expecting any other events to happen during that time. State machines sound interesting. How is that done on Arduino?
July 21, 20159 yr Now that Brickfete is over. I have a little more time to play with my Arduino like Train PONG between two magnetic reed switches. I think this could morph into a Great Ball Contraption. I could use the red channel on the IR receiver to drive a motor to operate a dump car. This would be perfect for a single line tram on a city layout going from one station to another and then back again on a continual basis.... Just what I need!
July 21, 20159 yr This would be perfect for a single line tram on a city layout going from one station to another and then back again on a continual basis.... Just what I need! ...cheaper than monorail parts too!!!
July 21, 20159 yr Author Here is the sketch for the train ping pong: /* Train move back and forth between 2 reed switches Channel 1 Blue dr_spock_888 July 17, 2015 LEGOPowerFunctions library by Roland Wiersma */ #include <legopowerfunctions.h> LEGOPowerFunctions lego(12); // IR LED on pin 12 const int reed1Pin = 2; // Reed switch1 on pin 2 const int reed2Pin = 3; // Reed switch2 on pin 3 const int ledPin = 13; // LED on pin 13 int reed1State = 0; // Variable for reading reed switch1 status int reed2State = 0; // Variable for reading reed switch2 status void setup() { pinMode(ledPin, OUTPUT); // Init LED pin as output pinMode(reed1Pin, INPUT); // Init reed switch1 as input pinMode(reed2Pin, INPUT); // Init reed switch2 as input lego.SingleOutput(0, PWM_FWD2, BLUE, CH1); // Start up train } void loop() { reed1State = digitalRead(reed1Pin); // Read state of reed switch1 reed2State = digitalRead(reed2Pin); // Read state of reed switch2 if (reed1State == HIGH) { lego.SingleOutput(0, PWM_FLT, BLUE, CH1); // Stop the train digitalWrite(ledPin,HIGH); // Turn on LED delay(2000); // Pause at station digitalWrite(ledPin, LOW); // Turn off LED lego.SingleOutput(0, PWM_REV2, BLUE, CH1); // Start up train other direction delay(1000); // Pause to ignore reed switch on the way back } if (reed2State == HIGH) { lego.SingleOutput(0, PWM_FLT, BLUE, CH1); // Stop the train digitalWrite(ledPin,HIGH); // Turn on LED delay(2000); // Pause at station digitalWrite(ledPin, LOW); // Turn off LED lego.SingleOutput(0, PWM_FWD2, BLUE, CH1); // Start up train other direction delay(1000); // Pause to ignore reed switch on the way back } } This would be perfect for a single line tram on a city layout going from one station to another and then back again on a continual basis.... Just what I need! It would work for that. It wouldn't be hard to add additional stops along the way. Just have to keep track of which direction the tram is going. ...cheaper than monorail parts too!!! Yup, it also was cheaper to make a Power Function monorail style railcar set than buying Airport Shuttle. Stadler GTW 2/6 by dr_spock_888, on Flickr
July 22, 20159 yr Author Two Power Functions trains. I didn't account for the condition at the end happening.
July 23, 20159 yr Very nice work! Brick-on dr_spock! If you position the reed sensor very well it works every time, again and again as you can well see :)
July 26, 20159 yr Have you tried using photoresistors to sense the trains? I used them many years ago for an N-scale railway to control level crossing lights. The advantage is it can sense all of the cars, not just the motor. I agree, reed switches are the way to go for signalling and train control. It has been a long time, but I had a few wayside bits controlled by RCX and homebrew sensors. I found that reed switches between the rails responded 90% of the time to the magnets too... and I was stumbling around. Someone with actual experience would likely to do better. I noticed that it just sits there with the delay() statement. It could be ok if I am not expecting any other events to happen during that time. State machines sound interesting. How is that done on Arduino? My more recent RCX creations use the photosensor. At startup I do a 30 sec calibration so that it can sense the ambient light and then use that setting. You could get fancier and sample the light once per second and use the median value over the past minute. Unless you are running train lengths that are comparable to half your loop, taking the median like this should filter out the train. I used this on a pair of semaphores. To keep the "wait for next event" from hanging everything, I just put all of the actions in a big loop, While (infinite) if sensor occupied and did not start then start motor to close semaphore, set time stop variable, then continue with loop if time stop variable < current time then stop motor to close semaphore, then continue with loop repeat for second sensor etc. end In this fashion, it checked the status of things, if it was time for a change it would take that change (skipping a few cycles if the change was demanding) and then resume scanning. It never sat there idle.
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.