Venderwel

New (Noob) Arduino Train automation project.

Recommended Posts

15 minutes ago, GianCann said:

I think a range of 10cm is an optimal solution to detect a train.

For sure!

Mine is a tailored solution: As there is not that much stray light in my attic (either the sun blasts into the room heating up to +30 °C in no time - and I close the blinds = low light) - or there is not enough light to set the sensors off), I have them facing upward and sensitivity to very low. A train is detected rather securely as the object needs to be closer than 1 cm to be detected.

Best
Thorsten 

@Venderwel: No they don't - modulated IR light is sent out by the integrated IR diode and the detector looks for that light. At a distance larger than 1 ... 1.5 cm they can also be used for black/white determination - black no trigger, white trigger. Below 1 cm they always trigger for an object with a reflective surface (LEGO brick) regardless of color.

I believe these are preferentially used as line followers for robots etc. But I am not sure.

Best
Thorsten 

Edited by Toastie

Share this post


Link to post
Share on other sites
1 hour ago, GianCann said:

have also buyed a small laser sensor: the TOF10120.

NICE one!

Looking forward to what you find out!

Best
Thorsten

Share this post


Link to post
Share on other sites
1 hour ago, Toastie said:

Mine is a tailored solution: As there is not that much stray light in my attic (either the sun blasts into the room heating up to +30 °C in no time - and I close the blinds = low light) - or there is not enough light to set the sensors off), I have them facing upward and sensitivity to very low. A train is detected rather securely as the object needs to be closer than 1 cm to be detected.

So is every movement detected within that 1cm? For example if you put your hand on top of it?

 

1 hour ago, Toastie said:

No they don't - modulated IR light is sent out by the integrated IR diode and the detector looks for that light. At a distance larger than 1 ... 1.5 cm they can also be used for black/white determination - black no trigger, white trigger. Below 1 cm they always trigger for an object with a reflective surface (LEGO brick) regardless of color.

I am not sure how that will work. The IR that I use is a beam between sender and reflector. The train driver through and that is the trigger.
I am curious about your IR solution, because it will save wires and as my IR stuff is visible next to the rails yours can be 'hidden' in the rails. I'll see if I can get such a sensor here to do some tests with.

Share this post


Link to post
Share on other sites
3 hours ago, aawsum said:

So is every movement detected within that 1cm? For example if you put your hand on top of it?

Yes.

And about its functionality: Here is another video explaining it - he does the 1 cm detection approach and "makes" the IR light visible

 

Best
Thorsten

 

Share this post


Link to post
Share on other sites

Cool, I can now count the number of times the train passes sensor 1 and make it stop at sensor 2 every 5 passes!

Just have to work out something that the counter sensor counts right. I now just build in a delay of one second. But if the train takes longer then one second to pass, if will count it as a new pass. So I think I will need to build in some kind of sensor state.

Share this post


Link to post
Share on other sites
2 minutes ago, Venderwel said:

some kind of sensor state

That is the way to go.

There may be multiple triggers when the train passes the sensor. What I do is branch away from the detection loop when it initially fires - and only return when required or some time has elapsed (not wait/delay, as this stalls the program).

Best
Thorsten 

Share this post


Link to post
Share on other sites

Exactly, delays in your code will give big headaches. I use counters and case statements. There are a few ways to do this, but delays definitely not ;-)

Share this post


Link to post
Share on other sites

So this is what I have now.....it works as it is. But how should I clean it up?

 

#define LDR1 34
#define LDR2 35

#include "PoweredUpHub.h"

// create a hub instance
PoweredUpHub myTrainHub;
PoweredUpHub::Port _port = PoweredUpHub::Port::A;

//settings
char hubName[] = "Yellow train";

//variables
int Traindetect;
int Station;
int TDcounter = 0;


void setup() {

pinMode (LDR1, INPUT);
pinMode (LDR2, INPUT);
Serial.begin(9600);


}

// main loop
void loop() {
//connect the powerdUP train
 if (!myTrainHub.isConnected() && !myTrainHub.isConnecting()) 
  {
    myTrainHub.init(); // initalize the PoweredUpHub instance
    //myTrainHub.init("90:84:2b:03:19:7f"); //example of initializing an hub with a specific address
  }

  // connect flow. Search for BLE services and try to connect if the uuid of the hub is found
  if (myTrainHub.isConnecting()) {
    myTrainHub.connectHub();
    if (myTrainHub.isConnected()) {
      Serial.println("Connected to HUB");
    } else {
      Serial.println("Failed to connect to HUB");
    }
  }

// if connected, set train name and color
 if (myTrainHub.isConnected()) {

    myTrainHub.setHubName(hubName);
  
    myTrainHub.setLedColor(GREEN);
    delay(1000);

  } else {
    Serial.println("Train hub is disconnected");
  }
 
  
  Train_Detector();
  Station_Stopper();
  

}

//code where LDR1 will count how many times a train passes
void Train_Detector() {
Traindetect = digitalRead(LDR1);

if (Traindetect == 1) {
TDcounter++;
Serial.print("The train passed ");
Serial.print(TDcounter);
Serial.println(" times!");
Serial.print("Value Traindetect:");
Serial.println(Traindetect);
delay(1000);

} else {
Serial.print("The train passed ");
Serial.print(TDcounter);
Serial.println(" times!");
Serial.print("Value Traindetect:");
Serial.println(Traindetect);
delay(1000);

}

}
//station code: using counter to decide what to do, every 5 passes at Train_Detector should make the train stop at the station.
void Station_Stopper() {
Station = digitalRead(LDR2);
int Scounter = TDcounter % 5 ; //if the traincounter reaches a number that can be devided by 5 it will set Scounter = 0

if (Station == 1 && Scounter == 0) {  //train is detected and 5 passes have been done the train stops and leaves again after 3 seconds (Future: trackswitch not allowed to this section!)

    myTrainHub.stopMotor(_port);
    delay(1000); 
    Serial.print(hubName);
    Serial.println(" has stopped at the station!");
Serial.print("Value Station:");
Serial.println(Station);
delay(3000);
    myTrainHub.setMotorSpeed(_port, 35);
    Serial.print(hubName);
    Serial.println(" has left the station!");
    delay(2000);
} 
  else if (Station == 0 && Scounter == 0) { //train is not detected yet but 5 passes have been done, message train is coming (Future: trackswitch should react)

Serial.println("Train should stop when arriving at station!");
Serial.print("Value Station:");
Serial.println(Station);
delay(1000);
}
else { //let it go let it go

Serial.println("Train should pass the station!");
Serial.print("Value Station:");
Serial.println(Station);
delay(1000);
}

}

There are a lot of print commands, but that basically is for me to see what is going on. Am I in the right piece of code? And since I don't want to have the text rambling on my screen, I put in the delay;s. The delay's do what I want, meaning I don't see a message every millisecond, but it halts the code too right?

Edited by Venderwel

Share this post


Link to post
Share on other sites
38 minutes ago, aawsum said:

There are a few ways to do this,

Absolutely! I also like the "last_time = millis()" and "if (millis() < (last_time + wait_time)) {do something else}" approach ...  

Best
Thorsten

Share this post


Link to post
Share on other sites

 

2 minutes ago, Toastie said:

Absolutely! I also like the "last_time = millis()" and "if (millis() < (last_time + wait_time)) {do something else}" approach ...  

Best
Thorsten

I probably should do something with that. 

Edited by Venderwel

Share this post


Link to post
Share on other sites
7 minutes ago, Venderwel said:

but it halts the code too right

Yes. It does nothing than counting nanoseconds :pir-huzzah1:

On the other hand: When your code does not become longer and more complex, nothing is wrong with that. However, when there are a lot of things going on (just imagine you want to detect an asynchronously operated push button, e.g. "BREAK") and many delays are implemented, things may become unpredictable at some point.

Best
Thorsten

 

Share this post


Link to post
Share on other sites

so regarding the code, I see a lot of delays(). Every delay makes the loop through the code stop and wait.... When you run 1 train only, then this will not be a big issue, if you want to run more and have more sensors triggered then this will case issues.

Code in itself does not look like it needs a lot of cleanup. Like toastie says, when the code gets bigger and more complex it will need more looking into.

Share this post


Link to post
Share on other sites

In the Leguino code I used in my sketch, you see there is a possibility to put in the BT address of the powerd up hub. But where how do I get that address? 

I need it for this idea: To know where which train is, I first need to indentify my trains (see above) if I know that, I am planning to place every train is a fixed starting/end sector. Then when the program starts the trains will leave their sectors one by one with sufficient time between them. So let's say the program always commands train A to start first. It sector 1 as I told the program that's where Train A starts. And let's asume I didn't screw it up by putting it in a different sector. Sensor in sector one detects it's not blocked anymore and soon after that the sensor in sector 2 detects a train. It has to be Train A, because other trains didn't get a move order yet. So I can now link sector 2 to Train A.....train moves on, sensor 2 is free and sensor in sector 3 gets blocked. It has to be Train A because that one was previously in sector 2. So I can link them together and free sector 2. Etc etc.  Same goes for the other trains ofcourse. 

I know it's full of assumptions, but is it the right way to do it? Or do you people do it in a different way?

Edited by Venderwel

Share this post


Link to post
Share on other sites
1 hour ago, Venderwel said:

In the Leguino code I used in my sketch, you see there is a possibility to put in the BT address of the powerd up hub. But where how do I get that address? 

I need it for this idea: To know where which train is, I first need to indentify my trains (see above) if I know that, I am planning to place every train is a fixed starting/end sector. Then when the program starts the trains will leave their sectors one by one with sufficient time between them. So let's say the program always commands train A to start first. It sector 1 as I told the program that's where Train A starts. And let's asume I didn't screw it up by putting it in a different sector. Sensor in sector one detects it's not blocked anymore and soon after that the sensor in sector 2 detects a train. It has to be Train A, because other trains didn't get a move order yet. So I can now link sector 2 to Train A.....train moves on, sensor 2 is free and sensor in sector 3 gets blocked. It has to be Train A because that one was previously in sector 2. So I can link them together and free sector 2. Etc etc.  Same goes for the other trains ofcourse. 

I know it's full of assumptions, but is it the right way to do it? Or do you people do it in a different way?

You could see if you can get the BT MAC address of the Hub

https://www.quora.com/Does-each-Bluetooth-device-has-its-own-unique-MAC-Address-How-can-we-access-it-in-an-app?share=1

Share this post


Link to post
Share on other sites

If you are running Windows, it tells you the device address when you search for new devices upon "pairing".

Best
Thorsten 

Share this post


Link to post
Share on other sites

Okay so I just got my v9 motors in, tried them out with some simple code, but all they do is buzz instead of rotate. Is there someone who wants to share their ESP32 /l298 code with me?

Wow forget about not working, I forgot to connect ground to the arduino!

Edited by Venderwel

Share this post


Link to post
Share on other sites
On 8/31/2020 at 11:05 AM, GianCann said:

I have also buyed a small laser sensor: the TOF10120.

Amazon has finally delivered the sensor to me!
I am very surprised: it is very small (and the size can be further reduced by removing the connector and cutting off the excess of the PCB not used).
I plugged it directly into a UART adapter and opened a terminator session. He immediately started to send me the reading in mm of the detected distance.
With simple commands you can set the transmission speed of the readings (with a minimum of 10ms) and also the maximum range that you want to monitor.
Therefore, if it is set to the 100mm (10cm) range it will ignore anything beyond 10cm, even if it passes in front of the sensor.

IMG_20200902_154217.jpg

IMG_20200902_154234.jpg

IMG_20200902_154253-scaled.jpg

IMG_20200902_154150-scaled.jpg

IMG_20200902_154201-scaled.jpg

IMG_20200902_154105-scaled.jpg

Share this post


Link to post
Share on other sites
26 minutes ago, GianCann said:

I plugged it directly into a UART adapter and opened a terminator session.

WOW - this is really nice. This is really really nice as its eliminates so many obstacles - ambient light issues, fluorescent light issues (overtones etc.), LED light issues (same thing, they sometimes behave as were their main task to securely terminate any radio traffic within a range of meters :pir_laugh2:).

Any chance to explain what the sentence above means in laymen's terms? Let us assume an Arduino or ESP ... and now what?

 

WAIT Found this:

Man. That is so cool. Thanks for sharing!!!

Best
Thorsten   

 

Edited by Toastie

Share this post


Link to post
Share on other sites

Class one. They use it in the generic distance sensors (HomeDepot etc etc.). There is another variety that goes up to 4 m.

 

4 hours ago, Toastie said:

terminator session

Wait: You mean terminal session, right? As in: Arnold S. is sitting in front of a DEC VT100 terminal hooked up to a PDP11 and watches the numbers (in mm) coming up, correct? UART = Serial??? The video suggests that you can do RX/TX or I2C. Is that so? It would be convenient!

I will order a couple of these right away. Again: Thanks for sharing!

Best
Thorsten

Edited by Toastie

Share this post


Link to post
Share on other sites

@Venderwel As we are discussing Arduino+train related ideas, questions, solutions in your very thread (and let me know if this is not OK!) ... another thought:

Coming from the LEGO PBrick world (RCX, NXT, EV3), all of these allowed "parallel" processing. Let's put it this way: You can start multiple tasks at any time. This is extremely powerful when running microcontrollers taking care of more complex tasks.

The Arduino IDE does not per se allow you to do that. Thus, as with all "mainloop forever" programming, diverting away from the main loop needs to return control to this loop after branching off. I found that rather challenging as the LEGO PBricks simply allow you to startup several tasks and all you have to do is synchronizing then using state variables/functions.

There are solutions to that "challenge" out there (i.e., quasi parallel processing) for Arduino. I never tried them but rather like the idea of coping with a single forever loop, and branching off to "local loops" eventually returning control to the main loop.

Maybe others have other experiences! If so please share.

Best,
Thorsten

 

Share this post


Link to post
Share on other sites

Hey @Toastie, that's no problem at all! It's a thread about me getting my layout automised. With help of Arduino. Not being said all has to be in Arduino. If there are other programs that can make life easier and only use Arduino to control the switches and get input from the sensors. Even better! Also want others to learn from this thread.

What I'd like my system to do in the end is:

  • Be able to function on it's own: Random asign stations and routes to trains etc.
  • Be able to easily add and control trains of other users.
  • Also give me the option to asign stops to a train myzelf, handle that order and go on after the order is finished.
  • Have a digital overview of my layout and see what train is where. Like for example in nControl by 4DBrix, I believe @GianCann is very busy with this one... ;-) (but I am open for other suggestions!)
  • Be able to use something like https://scratch.mit.edu/ to have my kids (or maybe a class at school) program the tracks and trains.

It will be a lot of work to get there I think, or maybe it's easier then I think. 

Edited by Venderwel

Share this post


Link to post
Share on other sites

For switching points, SG90 type servos are a cheap alternative to Lego motors. You can get quite low quality ones for about $1 each and these are perfect for switching throw switches on points.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.