I have a project in mind for which Arduino may be the solution. I don’t have any experience with Arduino, nor do I have any components. I’ve spent an hour or so reading up on it, so have a general idea of the system. My programming experience is pretty much limited to Excel macros, although I've had some exposure to C. (The one university level computer course I took was in Fortran, on punch cards, so a little dated). For this post, I’m mostly looking for an assessment of how much cost and effort would be involved, although specific recommendations are appreciated too. Let’s start with “is Arduino even the right approach?”.
I’m part of a group that runs a miniature railway. The project would be to build a device for monitoring the condition of the track. The concept is to detect when the device passes over a tie and then measure various parameters. Ties are spaced every 10 inches and there's a few thousand of them. Measurements and sensors would all have to be non-contact and would include:
Something to detect the tie, perhaps a metal detector as the ties are steel. The rails are 1” high, so it must have at least that much offset. There’s stone between and level with the ties.
An encoder on the wheels to give location on the track. This one https://store.qkits.com/2-speed.html might be ok. In order to work with the rail gap sensor (see below), I would need mm resolution, keeping in mind the wheels may be ~100 mm diameter.
A way of measuring horizontal angle. The device would be towed behind a locomotive and this measurement would be simply to discriminate between straight and curved track. Low resolution is ok; it’s really a yes/no check. This would depend on the geometry of the mechanical components, but I could arrange pointer with 10-20mm movement between straight and curve. Is there a sensor for this?
Measurement of gauge; the distance between the steel rails. Nominal is 7.25”. I’d need resolution of maybe a half mm over a range of +/- a few mm around the nominal gauge. Is there a sensor for this?
A way to measure the gap between rails at a joint. Coupled with the encoder, it really just needs to be a Boolean check of steel vs air, then count encoder pulses until it hits steel again. Gaps are in the range of 0-15mm. As long as the response time of the sensor is quicker than the time for a loop of code, it would give sufficient precision. This one would not be tied to the tie sensor as it would need to detect the gap independently of the ties. That is, all the other measures are across the rail and this one would be along the rail. Is there a sensor for this?
And of course the Arduino itself. I see a wide range of models and haven’t yet made sense of what the differences are and what would be most appropriate. I’d appreciate a suggestion here. Is there a summary comparison listed somewhere?
The data would need to be stored for later off-line analysis. Output to a csv file on USB would be convenient but I'm willing to consider alternatives. In any event, I’m not clear how this is typically done, either in hardware or software.
Also not clear how the components are assembled. I see tutorials with breadboards and coding, but I’m not seeing field ready components with cases, enclosures or mounting. How do I get from, say, a rotary encoder board+wheel to a finished sensor connected to the Arduino I/O?
As far as programming, I think I can figure that out. I see how to get input from sensors, and the logic itself would be pretty simple. I haven’t yet come across how to read out the data so I may be coming back for help with that.
In general, how much time and money should I expect to put into this?
Thank you all for the help.
If you are starting from scratch , this a very ambitious project with a number of issues .
In my opinion you need to play with an Arduino to get some experience of coding and sensors ..Then you will be in a better position to decide if it is a feasible task m, and something you can tackle..
In general start by designing a system block diagram.
This block diagram contains all hardware components and their dependencies.
The physical and logical properties of the interfaces are identified, as well as the respective energy consumption.
In the next step start with sketch design using the hardware design given. In this design step, you can create a cost calculation for the project.
As an HO scale modeler who also worked in an R&D environment, I have several thoughts on this.
Timeline - the more you have to come up with 'from scratch', the more you have to learn. DIY means this will be a long project. Is that acceptable, both to you and the organization?
Endurance/perseverance - several of the measurements you want to make will require adaptation of existing sensors, or creation of a sensor. That implies repetitive design, testing, failure, try again cycles, and a relatively non-changing testbed that has elements of all your key parameters.
expertise - do you have other resources to draw upon? I see three 'areas of expertise' needed. Electrical/electronics tech, a Mechanical tech or engineer, and someone experienced to write the code. One person can wear more than one of those hats, but you need coverage.
Software - I think you've underestimated the coding. What you want is not rocket science, and there are a lot of elements of what you need out there already 'in the wild', but you'll need patience and the perspicacity to judge what you see in order to merge several elements into one wholistic code, adapting each to a common framework.
Arduino - yes. Not an Uno, though. Not enough I/O, code space, etc. etc., so to compensate you'd end up using multiple Unos, then dealing with communication issues, etc. etc. That could be done, but why? To avoid restarting with a new processor part way through the project, aim high and don't fret if you find you're not maxing out the product. You'll have enough issues.
Communication - thought A - use wifi, log directly on a PC. But then this is an outside RR, right, so wifi might not be the answer. So, back to storing then analysing afterwards. Store to SD card. Beware, many of the SD implementations have their own drawbacks(e.g. blocking code that prevents realtime measurements), so look carefully, and test thoroughly.
Packaging - you've nailed an issue there. A prototype can be circuit cards and components scattered across a flatcar, but ultimately you'll want to make it more robust, but still be able to change out components as the project matures. 3D printing can help a lot, because you can vary your enclosure relatively easily. Add someone with 3D printer AND DESIGN EXPERTISE to your list; not just someone who has downloaded a bunch of figurines off the web and printed them. The right skillset here could be useful for making gadgets/bits for your sensing apparatus as well.
That's the negativity/reality part. On the flip side, this could be a fun project, indeed. Far outside the humdrum beginner stuff, and likely to present several challenges; that's when it gets fun!
The above is, after all, free advice. For what it's worth. YMMV.
Thank you to those that replied. I’ve still not spent much time on this, but have looked at some tutorials based on the replies. Some questions remain:
In my opinion you need to play with an Arduino to get some experience of coding and sensors > To avoid restarting with a new processor part way through the project, aim high
Ok, so which one. I can do my “playing” by starting my project, say by counting pulses on an encoder. But which model of Arduino do I start with such that I can expand to the whole project later?
> Timeline, Endurance/perseverance - design, testing, failure, try again cycles
This isn’t my first rodeo. I understand how development works.
> Software – I think you've underestimated the coding.
Could you be more specific – why do you think that? From a couple of Youtube tutorials, I’m seeing fairly short sections of code to read each sensor; call it 8-10 lines each x 6 sensors. There will be some conditionals, a Schmidt trigger on the tie sensor and some overhead for declaring variables and the like. I’m expecting something in the 200-300 lines of code. Does that sound right, or is it likely to be much more than that?
> Store to SD card.
Ah, that was one of the pieces I was missing. That seems like the simplest approach.
> Expertise - do you have other resources to draw upon? I see three 'areas of expertise' needed. Electrical/electronics tech, a Mechanical tech or engineer, and someone experienced to write the code.
I have exposure in all of these areas, plus the mechanical components of the carriage. What I’m not familiar with is the Arduino infrastructure. In particular, I don’t know much about the kinds of sensors I’ll need, especially those I highlighted in my original post. Do you have any recommendations there? Is there a library of compatible sensors, or is everything “make from first principles”?
> Add someone with 3D printer AND DESIGN EXPERTISE to your list.
I’ve done some pretty complicated 3D modelling, but frankly I don’t see the attraction. I could have enclosures out of wood or metal completed before the printer even heats up. Is there a reason I should be looking at plastic instead of those options?
What scale miniature railway?
1:8 scale, 7 1/4" gauge. The rail is not true to scale though. Rail is 1" high by 3/8" wide, welded to steel ties 1" wide by 1/4" thick, which are then screwed to 2x4's buried in stone ballast.
What would you use to detect a curve.
I'm open to suggestions. I'm not familiar with what sensors are available or compatible with Arduino, so this is probably the area I need most help right now.
My only thought on the subject is to have a pointer rigidly attached to the cart carrying the instrumentation that would traverse relative to the linkage that's used to tow it. Then detect the movement of the pointer. All the rail is basically either straight or the same radius of curvature, so I really just need a binary output. There are switches that would complicate this a little, but could be dealt with in post processing so I would ignore them in the instrument design. One real issue is that when passing over a switch, there will be a rail that (from the perspective of the instrumentation) traverses laterally. Hence, anything used to detect the ties needs to be at least an inch above, otherwise it would hit that traversing rail.
You can use the wokwi simulator and get the code mostly working without worrying about spending money or dodgy wiring or breaking or broken components.
If you start there with a Mega, you can work through the examples on offer in the IDE, or example sketches that come with libraries you may find convenient.
A suggestion, include an RFID reader and have RFID tags located around the track. Reading a tag will give you an exact location on the track. Counting the ties will give you a location between the RFID tags. No need to count wheel rotations.
Counting ties 1) is the problem and 2) does give me a location anyway as long as I know where it started. Besides, if I also can discriminate straight from curves and id the rail gaps, I have multiple interim locations. RFID wouldn't add anything useful. So one key question now is how to detect the ties?
GPS location could serve;
Same issue, GPS is far less precise. "Close" can be 10m.
Metal detector, I thought you had already worked that out.
You can buy hand held metal detectors for finding cables, nails etc in walls. Such detectors don't cost much and could easily be modified for what you are doing. Alternatively search the internet for metal detector circuits or ready built detectors.
Sensing distance will be a BIG factor in a metal detecting device, IMHO. Whatever is used will, I presume, have to be above the railhead so the inevitable turnout/crossover rail doesn't break it. What about a vision system in the form of a Pixy?
I also thought a camera or two might work in this application, with a camera you can detect the ties, detect the rail joints, photograph them for later analysis and measurement, the shots can be kept in a database, a camera can help count the ties which can aid with keeping track of location.
I thought the rfid idea had possibilities, if the track is 1/2 a mile a mile or even greater splitting it into zones of maintenance seems like it would be a more manageable system
You can use the wokwi simulator and get the code mostly working
I've started a sketch using the simulator. I'm trying to read out to the SD card. The simulator shows SD files, but there are none listed. It seems to be just ignoring the "read" command. Is this an artifact of the simulator, or am I expecting to see an actual file output?
Code is attached below. The serial monitor does give the two "check" outputs, so it looks like the SD read functions are working. I just don't see anywhere there's an output.
Serial monitor output:
check1check2The distance is: 1.00 pulses
check1check2The distance is: 1.00 pulses
check1check2The distance is: 1.00 pulses
check1check2The distance is: 1.00 pulses
/*
declarations for sd card reader
hookup is different for mega from uno in examples
Miso pin 50 (output)
Mosi pin 51 (input)
Sck pin 52 (clock)
chip select pin 53, not 4 as in uno
vcc to 5V. 3.3V not used
*/
#include <SD.h> //Load SD card library
#include<SPI.h> //Load SPI Library, necessary for SD card
const int chipSelect = 53; //chipSelect pin for the SD card Reader - 4 for uno 50 for mega
File RailSensorData; //Data object to write sensor data to
// end sd declarations
#include "Wire.h" // imports the wire library for talking over I2C to addressable sensors
/* declarations for distance (rotary encoder) on pin 2
encoder has 3 pins: 5V, Gnd, and output.
connect output to (digital) pin 2
*/
#define ENCODER_CLK 2 // get pulse from encoder on pin 2.
double distance; // pulse counts so integer values. It may generate large numbers
int newClk;
int lastClk;
float speed; // speed from rotary sensor and clock - add later
// end encoder declarations
// declarations for tie sensor (metal detector) on pin ?
boolean tie;
// end declarations for tie sensor
// declarations for tilt (level) sensor on pin ?
float level; // check what the level sensor puts out - add later
// end level declarations
// declarations for accelerometer on pin ?
// check what outputs from this device
// end declarations for accelerometer
// declarations for left and right rail gap sensors on pins ??
// device will use an optical sensor, so should be just yes/no input, but input value and split to true/false.
// end declarations for rail gap sensors
void setup(){
// general setup
Serial.begin(9600); //turn on serial monitor
// SD card reader setup
pinMode(10, OUTPUT); //SD library wants pin 10 reserved, even though not used.
// see LESSON 21 at www.toptechboy.com.
SD.begin(chipSelect); //Initialize the SD card reader on pin 53
// end sd setup
// distance measure setup
// distanceSensor.begin(); //initialize DistanceSensor
pinMode(ENCODER_CLK, INPUT);
// end distance measure setup
// tie sensor
// level sensor
// accelerometer
// left and right rail gap sensor
}
void loop() {
//
// check if rotary sensor moved. Clk is input from rotary enoder
newClk = digitalRead(ENCODER_CLK);
if (newClk != lastClk) {
// There was a change on the CLK pin
lastClk = newClk;
distance = distance + newClk;} // if click, then sensor moved
// read out to serial monitor for troubleshooting
// copied from example
Serial.print("The distance is: "); //Print Your results
Serial.print(distance);
Serial.println(" pulses");
delay(250); //Pause between readings - take this out later and only output on tie sensor
// read out to SD card. Railsensordata is a file object for SD card.
RailSensorData = SD.open("Rail.txt", FILE_WRITE); // keep filename short or it won't run
Serial.print("check1");
if (RailSensorData) {
Serial.print("check2");
RailSensorData.print(distance); //write distance data to card
RailSensorData.print(","); //write a commma
RailSensorData.println(level); //write level and end the line (println)
RailSensorData.close(); //close the file
}
}
Please say you found the documentation for the wokwi SD card reader, tried the examples then slavishly followed every step it takes it your own code.
Documentation can be found here: wokwi-microsd-card Reference | Wokwi Docs
I don't see any mention of where the output goes or how to tell if it's successfully writing.
The example listed there is quite different from what I'm trying to do, so I based my code mostly on:
I note in running the example that it only writes to the serial monitor, not the SD card, so that's not helpful to me. I was puzzled to see SD listed as a tab with a "no files yet" message, although the output shows multiple files.
The links I posted also had a couple of tips that aren't in the simulator documentation, such as keeping filenames short and blocking pin 10. He didn't explain, and I haven't seen that elsewhere yet.
When you make a wokwi project and come here for help, post a link to it
So I'm still puzzled; my code seems to work since it writes my debugging statements to the serial monitor after the if statement, but I don't see output anywhere. I still have the original question: is this an artifact of the simulator? If not, where did my output go?
You and me both. Sry, usually the wokwi parts and documentation can be met halfway with some common sense and logic.
I have spent some time just now and must stop… trying this and that just won't work in this case; one hopes the entire SD feature of the wokwi is documented somewhere. I made no sense of what was happening with the examples.
I hope you can get that working. IRL or wherever. With the simulator, however, from time to time you might benefit from doing entire sections of the code as promises or proxies.
Promise that a function will eventually get its data, or write its data, to a file. Write simple code to fake it.
Use pushbuttons, pots and LEDs to stand in for sensors and actuators that are either unavailable, less convenient or impossible to use in simulation.
I use a slide fader instead of the fiddle rotary pot, and I use a slide fader rather than use a "real" DS1820, it's just easier to fake.
@railwayguy to add files to the wokwi SD example you need a "Club" subscription, but you can still test SD operations without actually being able to add the files to the SD tab.
My modifications are a from the Arduino example and are a little crude but should be fairly easy to figure out and make them work for your own purpose.
First thing is to add a read and write function at the end of the existing code
void write_file(){
File myFile = sd.open("test.txt", FILE_WRITE);
// if the file opened okay, write to it:
if (myFile) {
Serial.print("Writing to test.txt...");
myFile.println("testing 1, 2, 3.");
}
// close the file:
myFile.close();
Serial.println("done.");
}
void read_file(){
File myFile = sd.open("test.txt");
if (myFile) {
Serial.println("test.txt:");
// read from the file until there's nothing else in it:
while (myFile.available()) {
Serial.write(myFile.read());
}
}
// close the file:
myFile.close();
}
To make this work we need a small alteration in the setup method, its pretty easy to see where this goes