Jump to content




Gump's Universal K'NEX Coaster System

contest nolimits roller coaster simulator

  • Please log in to reply
34 replies to this topic

#21 TheSUCKCrew

TheSUCKCrew

    Way too old

  • 4095 posts

Posted 19 March 2012 - 01:40 PM

Not sure if I got the idea of this project right, but I thought this was meant to be intergradeable into any coaster, with only making software changes and no hardware changes. Therefor it would not hurt doing what ^ does with the 10pin cable. Breadboard wires don't hold very well. This will be less of a problem with the more expansive headers, but it will still be a problem. You should choose for yourself wether you are gonna keep it this way or not.



#22 ForgotToGrowUp

ForgotToGrowUp

    Lead Engineer

  • 1732 posts

Posted 21 March 2012 - 03:26 PM

Sorry, I realize this is slightly off topic but I didn't think it was worthy of it's own thread and I know Gump has more electric motors than anyone.

When I built Whirlwind one of the motors I had ran in the opposite direction of the others I used. It actually made combining motors on the same drive axle much better looking as I could put them on opposite sides of the white gear.

I now have 8 electric motors in total. I checked them all last night and found that 2 of them run opposite the other 6. Pretty significant in my small sample size.

How uncommon is this in your experience Gump? obviously if you are not expecting it it can really break things.

Comet Recreation still underway.

Proof you never grow up if you keep playing with toys!


#23 Jogumpie

Jogumpie

    Living through the great Gump hiatus...

  • 13586 posts

Posted 21 March 2012 - 04:32 PM

All of my motors are correctly polarized and turn in the same direction. If some of yours are running the other way, they must be incorrectly polarized within the assembly. With this system I built it is very easy to just switch the polarization. In the code I would replace the forward speed 255 by the reverse speed -256.


SSCoasters Administrator
The SSCoasters Forum Rules
DD_signature.jpg
YoutubeButton.pngFacebookButton.png


#24 Jogumpie

Jogumpie

    Living through the great Gump hiatus...

  • 13586 posts

Posted 25 April 2012 - 11:48 AM

If anyone is interested. This is the code I will use for Balrog. Of course I'll probably make minor changes before Balrog 'goes live'.

//Gump's Universal K'NEX Coaster System applied on Balrog

/*--------------------------------------------------------------  
-------------------------------PINS-----------------------------
--------------------------------------------------------------*/

/*
ER IS EEN PROBLEEM MET 12!!! PINS 47 en 52
Hij wordt niet positief, maar wel negatief. Pin 47 wil dus niet high worden. Slechte soldeerverbinding?
*/

///////////////////////////////////////////////////////////12////14///
int motor_non_pwm[] = {33,34,35,36,37,38,39,40,41,42,43,44,47,46,45,48}; //0-15 motors TOTAL
int motor_pwm[]   =   {12,11,10, 9, 8, 7, 6, 5, 4, 3, 2,53,52,51,50,49}; //0-10 motors PWM ; 11-16 motors non-PWM
int sensor_pin[] = {22,23,24,25,26,27,28,29,30,31,32,A15,A14,A13,A12,A11,A10,A9,A8,A7}; //20 sensors
int button_pin = A1; //Start button
int LED_pin = 13; //LED start button

/*--------------------------------------------------------------  
-----------------------------VARIABLES--------------------------
--------------------------------------------------------------*/

//Servos
#include <Servo.h>
Servo servo_gates;
//Servo servo_1;
//Servo servo_2;
//Servo servo_3;
//Servo servo_4;

//Blocks
boolean block_station_in;
boolean block_station_uit;
boolean block_remmen;
boolean block_mcbr;
boolean block_lift;
boolean block_lift_down; //Enkel voor initialisatie.

//States
int Init_State = 0;
int Station_In_State = 0;
int Station_Uit_State = 0;
int Remmen_State = 0;
int Mcbr_State = 0;
int Lift_State = 0;

//Motor variables
int motor_dead_zone_high = 100;
int motor_dead_zone_low = -100;
int skip_dead_zone;
int motor_current_speed[16] = {0};
int speed_step[16] = {0};
int xMotor_non_pwm[16] = {0};
int xMotor_pwm[16] = {0};

//Sensors
boolean sensor_post_station;
boolean sensor_station_in;
boolean sensor_station_uit;
boolean sensor_pre_station;
boolean sensor_transfer_back;
boolean sensor_transfer_front;
boolean sensor_remmen;
boolean sensor_post_mcbr;
boolean sensor_stop_mcbr;
boolean sensor_pre_mcbr;
boolean sensor_post_lift_top;
boolean sensor_pre_lift_top;

//Button and LED
boolean LED_State = LOW;
boolean button_State = LOW;

//Timers
unsigned long currentMillis = 0;
unsigned long previousMillisMotor[16] = {0};
unsigned long BlinkPrevious = 0;
long InitPrevious;
long StationInPrevious;
long StationUitPrevious;
int InitTimer;
int StationInTimer;
int StationUitTimer;

//Misc
boolean internal_station_move;

/*--------------------------------------------------------------
-------------------------------SETUP----------------------------
--------------------------------------------------------------*/
void setup() {
  Serial.begin(9600);
  
  for(int i = 0; i<=15; i++) {
    pinMode(motor_non_pwm[i],OUTPUT);
    pinMode(motor_pwm[i],OUTPUT);
  }
  
  pinMode(LED_pin,OUTPUT);
  
  for(int i = 0; i<=19; i++) {
    pinMode(sensor_pin[i],INPUT);
  }
  
  pinMode(button_pin,INPUT);
  
  servo_gates.attach(A6);
  //servo_1.attach(A5);
  //servo_2.attach(A4);
  //servo_3.attach(A3);
  //servo_4.attach(A2);
}
 
 
/*--------------------------------------------------------------
-------------------------------LOOP-----------------------------
--------------------------------------------------------------*/
void loop() {
  PII();
  currentMillis = millis();
  
  if(Init_State == -1) {
    station_in();
    station_uit();
    eindremmen();
    mcbr();
    lift();  
  }
  else {
    initialisatie();
  }
  
  PIQ();
}


/*--------------------------------------------------------------
--------------------------USER FUNCTIONS------------------------
--------------------------------------------------------------*/
void PII(){ //Proces Image Input (Ingangsregister)
  button_State = digitalRead(button_pin);
  sensor_post_station   = digitalRead(sensor_pin[0]);
  sensor_station_in     = digitalRead(sensor_pin[1]);
  sensor_station_uit    = digitalRead(sensor_pin[2]);
  sensor_pre_station    = digitalRead(sensor_pin[3]);
  sensor_transfer_back  = digitalRead(sensor_pin[4]);
  sensor_transfer_front = digitalRead(sensor_pin[5]);
  sensor_remmen         = digitalRead(sensor_pin[6]);
  sensor_post_mcbr      = digitalRead(sensor_pin[7]);
  sensor_stop_mcbr      = digitalRead(sensor_pin[8]);
  sensor_pre_mcbr       = digitalRead(sensor_pin[9]);
  sensor_post_lift_top  = digitalRead(sensor_pin[10]);
  sensor_pre_lift_top   = digitalRead(sensor_pin[11]);
  //sensoren 12-19 niet in gebruik
}

void PIQ(){ //Proces Image Output (Uitgangsregister)
  for(int i = 0; i<=15; i++) {
    digitalWrite(motor_non_pwm[i],xMotor_non_pwm[i]);
    analogWrite(motor_pwm[i],xMotor_pwm[i]);
  }
}

void motor(int motor, int value, int time) { //possible values from -255 to +255
  currentMillis = millis();
  if((currentMillis - previousMillisMotor[motor]) >= time) {
    previousMillisMotor[motor] = currentMillis;
    
    if     (motor_current_speed[motor] < value) {speed_step[motor] =  1; skip_dead_zone = motor_dead_zone_high;}
    else if(motor_current_speed[motor] > value) {speed_step[motor] = -1; skip_dead_zone = motor_dead_zone_low;}
    else if(motor_current_speed[motor] = value) {speed_step[motor] =  0;}
    
    if(motor_current_speed[motor] <= motor_dead_zone_low) {
      motor_current_speed[motor] = motor_current_speed[motor] + speed_step[motor];
      xMotor_non_pwm[motor] = LOW;
      xMotor_pwm[motor] = abs(motor_current_speed[motor]);
    }
    if((motor_current_speed[motor] > motor_dead_zone_low) && (motor_current_speed[motor] < motor_dead_zone_high)) {
      if((value > motor_dead_zone_low) && (value < motor_dead_zone_high)) {
        motor_current_speed[motor] = 0;
        xMotor_non_pwm[motor] = LOW;
        xMotor_pwm[motor] = 0;
      }
      else {
        motor_current_speed[motor] = skip_dead_zone;
      }
    }
    if(motor_current_speed[motor] >= motor_dead_zone_high) {
      motor_current_speed[motor] = motor_current_speed[motor] + speed_step[motor];
      xMotor_non_pwm[motor] = HIGH;
      xMotor_pwm[motor] = 255-abs(motor_current_speed[motor]);
    }
  }
}

void motor_lift(int value, int time) {
  motor(0,value,time);
  motor(1,value,time);
  motor(2,value,time);
  motor(3,value,time);
  motor(4,value,time);
  motor(5,value,time);
  motor(6,value,time);
  motor(7,value,time);
}
void motor_mcbr(int value, int time) { //Deels andersom gepolariseerd in de achtbaan
  motor(8,value,time);
  motor(9,-value,time);
  motor(10,value,time);
  motor(11,-value,time);
}
void motor_remmen(int value, int time) { //Andersom gepolariseerd in de achtbaan
  motor(12,-value,time);
}
void motor_station_uit(int value, int time) {
  motor(13,value,time);
}
void motor_station_in(int value, int time) {
  motor(14,value,time);
}

/*----------------------------------------------------
--------------------INITIALISATIE---------------------
----------------------------------------------------*/
void initialisatie() {
  if(currentMillis - InitPrevious > 1000) {
    InitPrevious = currentMillis;
    InitTimer++;
  }
  
  switch(Init_State) {
    
    case 0:  //Wachten op druk op knop
             if(currentMillis - BlinkPrevious > 500) {                                 //Elke halve seconde
               BlinkPrevious = currentMillis;                                          //Knippertimer resetten
               LED_State = !LED_State;                                                 //LED aan- of uitschakelen
               digitalWrite(LED_pin, LED_State);
             }
             if(button_State == HIGH) {                                                //Als knop wordt ingedrukt
               Init_State = 10;                                                        //Gaan wachten op loslaten knop
             }
             break;
             
    case 10: //Wachten op loslaten knop   
             LED_State = HIGH;
             digitalWrite(LED_pin, LED_State);
             if(button_State == LOW) {   
               LED_State = LOW;
               digitalWrite(LED_pin, LED_State);
               InitTimer = 0;
               Init_State = 20;
             }
             break;
             
    case 20: //Lift controleren
             if(InitTimer <= 50) {                                                     //Max 50 seconden draaien
               motor_lift(255,15);
               if(sensor_pre_lift_top == HIGH) {                                       //Trein blijft bovenaan de lift
                 motor_lift(0,15);
                 block_lift = HIGH;
                 InitTimer = 0;
                 Init_State = 30;
               }
               else if(sensor_post_lift_top == HIGH) {                                 //Trein gaat van lift naar mcbr
                 motor_lift(0,15);
                 block_lift = LOW;
                 Init_State = 21;
               }
             }
             else {                                                                    //Geen trein op de lift
               motor_lift(0,15);
               block_lift = LOW;
               InitTimer = 0;
               Init_State = 30;
             }
             break;
             
    case 21: //Wachten op mcbr
             if(sensor_pre_mcbr == HIGH) {                                             //Trein rijdt mcbr op
               motor_mcbr(255,15);
               Init_State = 22;
             }
             break;
             
    case 22: //Positioneren op mcbr
             if(sensor_stop_mcbr == HIGH) {                                            //Trein staat gepositioneerd
               motor_mcbr(0,15);
               block_mcbr = HIGH;
               InitTimer = 0;
               Init_State = 30;
             }
             break;
             
    case 30: //Station INSTAP controleren
             if(InitTimer <= 10) {                                                     //Max 10 seconden draaien
               motor_station_in(255,0);
               if(sensor_post_station == HIGH) {                                       //Trein van station instap naar onderkant lift
                 motor_station_in(0,0);
                 block_lift_down = HIGH;
                 InitTimer = 0;
                 Init_State = 40;
               }
             }
             else {                                                                    //Geen trein in station instap
               motor_station_in(0,0);
               block_lift_down = LOW;
               InitTimer = 0;
               Init_State = 40;
             }
             break;
             
    case 40: //Station UITSTAP controleren
             if(InitTimer <= 10) {                                                     //Max 10 seconden draaien
               motor_station_in(255,0);
               motor_station_uit(255,0);
               if(sensor_station_in == HIGH) {                                         //Trein van station uitstap naar station instap
                 motor_station_in(0,0);
                 motor_station_uit(0,0);
                 block_station_in = HIGH;
                 InitTimer = 0;
                 Init_State = 50;
               }
             }
             else {                                                                    //Geen trein in station uitstap
               motor_station_in(0,0);
               motor_station_uit(0,0);
               block_station_in = LOW;
               InitTimer = 0;
               Init_State = 50;
             }
             break;
             
    case 50: //Transfer aligned?
             if((sensor_transfer_front == HIGH) && (sensor_transfer_back == HIGH)) {
               InitTimer = 0;
               Init_State = 51;
             }
             break;
             
    case 51: //Eindremmen controleren
             if(InitTimer <= 30) {                                                     //Max 30 seconden draaien
               motor_remmen(255,0);
               motor_station_uit(255,0);
               if(sensor_station_uit == HIGH) {                                        //Trein van eindremmen naar station uitstap
                 motor_remmen(0,0);
                 motor_station_uit(0,0);
                 block_station_uit = HIGH;
                 InitTimer = 0;
                 Init_State = 60;
               }
               else if((sensor_transfer_front == LOW) || (sensor_transfer_back == LOW)) {
                 motor_remmen(0,0);
                 motor_station_uit(0,0);
                 Init_State = 50;
               }
             }
             else {                                                                    //Geen trein op eindremmen
               motor_remmen(0,0);
               motor_station_uit(0,0);
               block_station_uit = LOW;
               InitTimer = 0;
               Init_State = 60;
             }
             break;
             
    case 60: //Mcbr controleren
             if(InitTimer <= 10) {                                                     //Max 10 seconden draaien
               motor_mcbr(255,0);
               if(sensor_post_mcbr == HIGH) {                                          //Trein verlaat mcbr
                 motor_mcbr(0,0);
                 block_mcbr = LOW;
                 Init_State = 65;
               }
             }
             else {                                                                    //Geen trein op mcbr
               motor_mcbr(0,0);
               block_mcbr = LOW;
               Init_State = 70;
             }
             break;
             
    case 65: //Wachten op eindremmen
             if(sensor_remmen == HIGH) {                                               //Trein rijdt eindremmen in
               block_remmen = HIGH;
               InitTimer = 0;
               Init_State = 70;
             }
             break;
             
    case 70: //Lift nogmaals controleren
             if(block_lift == HIGH) {                                                  //Trein bovenaan lift
               motor_lift(255,15);
               if(sensor_post_lift_top == HIGH) {                                      //Trein van lift naar mcbr
                 motor_lift(0,15);
                 block_lift = LOW;
                 Init_State = 71;
               }
             }
             else {                                                                    //Geen trein bovenaan lift
               Init_State = 80;
             }
             break;
             
    case 71: //Wachten op mcbr
             if(sensor_pre_mcbr == HIGH) {                                             //Trein rijdt mcbr op
               motor_mcbr(255,0);
               Init_State = 72;
             }
             break;
             
    case 72: //Positioneren op mcbr
             if(sensor_stop_mcbr == HIGH) {                                            //Trein staat gepositioneerd
               motor_mcbr(0,0);
               block_mcbr = HIGH;
               Init_State = 80;
             }
             break;
             
    case 80: //Lift nogmaals controleren
             if(block_lift_down == HIGH) {                                             //Trein onderaan lift
               motor_lift(255,15);
               if(sensor_pre_lift_top == HIGH) {                                       //Trein bovenaan lift aangekomen
                 motor_lift(0,0);
                 block_lift = HIGH;
                 block_lift_down = LOW;
               }
             }
             else {                                                                    //Geen trein onderaan lift
               Init_State = 90;
             }
             break;
             
    case 90: //Posities van alle treinen bekend, door naar ritprogramma
             if(block_station_in == HIGH) {Station_In_State = 20;}
             if(block_station_uit == HIGH) {Station_Uit_State = 20;}
             if(block_remmen == HIGH) {Remmen_State = 10;}
             if(block_mcbr == HIGH) {Mcbr_State = 20;}
             if(block_lift == HIGH) {Lift_State = 20;}
             Init_State = -1;
             break;
  }
}
  
/*----------------------------------------------------
-----------------------RIT-CYCLUS---------------------
----------------------------------------------------*/

void station_in() {
  if(currentMillis - StationInPrevious > 1000) {
    StationInPrevious = currentMillis;
    StationInTimer++;
  }
  
  switch(Station_In_State) {
      
    case 0:  //Station_in is vrij
             if(internal_station_move == HIGH) {                                       //Trein rijdt station_uit in
               motor_station_in(255,0);
               Station_In_State = 10;
             }
             break;
      
    case 10: //Station_in is bezet, trein rijdt naar midden station_in
             if(sensor_station_in == HIGH) {                                           //Trein wacht in station_uit, poortjes openen
               motor_station_in(0,0);
               servo_gates.write(90);
               StationInTimer = 0;
               Station_In_State = 20;
             }
             break;
      
    case 20: //Station_in is bezet, trein wacht in station_in
             if(StationInTimer > 6) {                                                  //Na 6 seconden sluiten de poortjes
               servo_gates.write(0);
             }
             if((StationInTimer > 8) && (block_lift == LOW)) {                           //Trein heeft 8 seconden stilgestaan in station_in en lift is vrij
               motor_station_in(255,0);
               Station_In_State = 30;
             }
             break;
    
    case 30: //Station_in is bezet, trein vertrekt uit station_in
             if(sensor_post_station == HIGH) {                                         //Trein heeft station_in verlaten
               block_station_in = LOW;
               block_lift = HIGH;
               motor_station_in(0,0);
               Station_In_State = 0;
             }
             break;
  }
}

void station_uit() {
  if(currentMillis - StationUitPrevious > 1000) {
    StationUitPrevious = currentMillis;
    StationUitTimer++;
  }
  
  switch(Station_Uit_State) {
      
    case 0:  //Station_uit is vrij
             if((sensor_pre_station == HIGH)) {//Trein rijdt vlak voor station_uit
               Station_Uit_State = 5;
             }
             break;
             
    case 5:  //Station_uit is vrij, trein is vlak voor station_uit
             if((sensor_transfer_front == HIGH) && (sensor_transfer_back == HIGH)) {   //Staat de transfer track goed?
               motor_station_uit(255,0);
               Station_Uit_State = 10;
             }
             break;
      
    case 10: //Station_uit is bezet, trein rijdt naar midden station_uit
             if(sensor_station_uit == HIGH) {                                          //Trein wacht in station_uit
               motor_station_uit(0,0);
               StationUitTimer = 0;
               Station_Uit_State = 20;
             }
             break;
      
    case 20: //Station_uit is bezet, trein wacht in station_uit
             if((StationUitTimer > 5) && (block_station_in == LOW)) {                    //Trein heeft 5 seconden stilgestaan in station_uit en station_in is vrij
               motor_station_uit(255,0);
               internal_station_move = HIGH;
               Station_Uit_State = 30;
             }
             break;
    
    case 30: //Station_uit is bezet, trein vertrekt uit station_uit
             if(sensor_station_in == HIGH) {                                           //Trein heeft station_uit verlaten en is aangekomen in station_in
               block_station_uit = LOW;
               block_station_in = HIGH;
               motor_station_uit(0,0);
               internal_station_move = LOW;
               Station_Uit_State = 0;
             }
             break;
  }
}

void eindremmen() {    
  switch(Remmen_State) {
  
    case 0:  //Remmen zijn vrij
             if(sensor_remmen == HIGH) {                                               //Trein rijdt remmen in
               Remmen_State = 10;
             }
             break;
    
    case 10: //Remmen zijn bezet, trein staat stil
             if((block_station_uit == LOW) && (sensor_transfer_front == HIGH) && (sensor_transfer_back == HIGH)) {
               motor_remmen(255,0);
               Remmen_State = 20;
             }
             break;
    
    case 20: //Remmen zijn bezet, trein rijdt door
             if(sensor_pre_station == HIGH) {                                          //Trein nadert station, remmen weer vrij
               block_remmen = LOW;
               block_station_uit = HIGH;
               motor_remmen(0,0);
               Remmen_State = 0;
             }
             else if((sensor_transfer_front == LOW) || (sensor_transfer_back == LOW)) {
               motor_remmen(0,0);
               Remmen_State = 10;
             }
             
             break;
  }
}

void mcbr() {
  switch(Mcbr_State) {
      
    case 0:  //Mcbr is vrij
             if(sensor_pre_mcbr == HIGH) {                                             //Trein rijdt mcbr op
               motor_mcbr(255,0);
               Mcbr_State = 10;
             }
             break;
      
    case 10: //Mcbr is bezet, trein rijdt naar midden mcbr
             if((sensor_stop_mcbr == HIGH) && (block_remmen == HIGH)) {                //Trein gepositioneerd op mcbr, eindremmen NIET vrij
               motor_mcbr(0,0);
               Mcbr_State = 20;
             }
             else if((sensor_stop_mcbr == HIGH) && (block_remmen == LOW)) {            //Trein gepositioneerd op mcbr, eindremmen WEL vrij
               Mcbr_State = 30;
             }
             break;
      
    case 20: //Mcbr is bezet, trein wacht op mcbr op vrijkomen van eindremmen
             if(block_remmen == LOW) {                                                 //Trein wacht op mcbr, eindremmen komen weer vrij
               motor_mcbr(255,0);
               Mcbr_State = 30;
             }
             break;
    
    case 30: //Mcbr is bezet, trein vertrekt uit mcbr
             if(sensor_post_mcbr == HIGH) {                                            //Trein heeft de mcbr verlaten
               block_mcbr = LOW;
               block_remmen = HIGH;
               motor_mcbr(0,0);
               Mcbr_State = 0;
             }
             break;
  }
}

void lift() {
  switch(Lift_State) {
      
    case 0:  //Lift is vrij
             if(sensor_post_station == HIGH) {                                         //Trein rijdt richting lift
               motor_lift(255,15);
               Lift_State = 10;
             }
             break;
      
    case 10: //Lift is bezet, trein rijdt omhoog
             if((sensor_pre_lift_top == HIGH) && (block_mcbr == HIGH)) {               //Trein komt boven, mcbr NIET vrij
               motor_lift(0,15);
               Lift_State = 20;
             }
             else if((sensor_pre_lift_top == HIGH) && (block_mcbr == LOW)) {           //Trein komt boven, mcbr WEL vrij
               Lift_State = 30;
             }
             break;
      
    case 20: //Lift is bezet, trein wacht boven op vrijkomen van mcbr
             if(block_mcbr == LOW) {                                                   //Trein wacht boven, mcbr komt weer vrij
               motor_lift(255,15);
               Lift_State = 30;
             }
             break;
    
    case 30: //Lift is bezet, trein gaat over de top
             if(sensor_post_lift_top == HIGH) {                                        //Trein verlaat de lift
               block_lift = LOW;
               block_mcbr = HIGH;
               motor_lift(0,15);
               Lift_State = 0;
             }
             break;
  }
}



SSCoasters Administrator
The SSCoasters Forum Rules
DD_signature.jpg
YoutubeButton.pngFacebookButton.png


#25 15sgriggs

15sgriggs

    #1 Fanatic of Hines Ward

  • PipPipPip
  • 76 posts

Posted 25 April 2012 - 02:10 PM

wow, this is so far above my head I cant even dream of trying to understand any of this...

[SIGPIC][/SIGPIC]Hines Ward to the HOF!

#26 Maxlaam

Maxlaam

    Tracing Tyrant's Steps

  • 8116 posts

Posted 25 April 2012 - 02:34 PM

Well, if you are going to use an Arduino, that's basically what you'll end up with. Being this more of an advanced code. I haven't looked it completely through, but so far I didn't see any flaws. I really like the motorcontrol code! Very clever! May I give you compliment on the clean-ness of coding? Very easy to understand!


SSCoasters Administrator
Read The Forum Rules(smart)

Posted Image
Posted ImagePosted Image


#27 Jogumpie

Jogumpie

    Living through the great Gump hiatus...

  • 13586 posts

Posted 25 April 2012 - 07:09 PM

I really like the motorcontrol code! Very clever! May I give you compliment on the clean-ness of coding? Very easy to understand!

I'm rather proud of this motor function. I hope to fully exploit it after the Balrog project, when I start using other IC's for more possibilities with this 'Universal K'NEX Coaster System'.
I tried to make the code as understandable as possible. It's still a mix of Dutch and English, though.


SSCoasters Administrator
The SSCoasters Forum Rules
DD_signature.jpg
YoutubeButton.pngFacebookButton.png


#28 LaMbChOpZ

LaMbChOpZ

    Lead Particle Physicist and Musical Orchestrator

  • 2812 posts

Posted 25 April 2012 - 07:15 PM

But when you emailed it to me, no matter if it was English or Dutch, I could understand it based upon how well you set up your code. It's really good, for someone who says they don't know a lot of code/coding.

Member of a few physics experiments; Orchestrator and/or Copyist for a few musicals.


#29 Jogumpie

Jogumpie

    Living through the great Gump hiatus...

  • 13586 posts

Posted 25 April 2012 - 07:19 PM

for someone who says they don't know a lot of code/coding.

I think that sense for clean coding came from having experience in building PHP websites. :)


SSCoasters Administrator
The SSCoasters Forum Rules
DD_signature.jpg
YoutubeButton.pngFacebookButton.png


#30 Jogumpie

Jogumpie

    Living through the great Gump hiatus...

  • 13586 posts

Posted 09 July 2012 - 10:58 AM

Balrog sure gives me reasons to improve on this system. ;) For one I'd like to add circuits that detect currents flowing through the motors.


SSCoasters Administrator
The SSCoasters Forum Rules
DD_signature.jpg
YoutubeButton.pngFacebookButton.png


#31 ForgotToGrowUp

ForgotToGrowUp

    Lead Engineer

  • 1732 posts

Posted 24 July 2012 - 09:43 AM

Gump, I've read this several times and think I understand most of it. I have no familiarity with arduino, have just done a little reading recently. Since my project is on hold until the summer is over I am getting interested in using electronic controls.

A few questions could help save me a lot of time researching things.

Did you make your own motor shield because nothing out there will control as many motors as you needed? I see there are standard motor shields available but it looks like the most you can control is 4 motors. But I think most of those shields can provide up to 2A per H bridge. Could I wire multiple motors up to the same bridge circuit if they were always going to run at the same speed? For instance a set of motors driving a lift.

I am a software engineer but it has been over 25 years since I programmed anything as simple as a microcontroller. Your code is nicely organized and has some nice safety features built in. Did you develop that login incrementally because of issues you had in early versions or did you just try to cover all the bases when you first wrote it?

Also do you have any picutres of your servo controlled brakes either here or in the Balrog thread?

Comet Recreation still underway.

Proof you never grow up if you keep playing with toys!


#32 Jogumpie

Jogumpie

    Living through the great Gump hiatus...

  • 13586 posts

Posted 26 July 2012 - 05:40 AM

Did you make your own motor shield because nothing out there will control as many motors as you needed? I see there are standard motor shields available but it looks like the most you can control is 4 motors. But I think most of those shields can provide up to 2A per H bridge. Could I wire multiple motors up to the same bridge circuit if they were always going to run at the same speed? For instance a set of motors driving a lift.

I use IC's called 'L293D'. Each IC can drive two motors in both directions or four motors in one direction. Have a look at this page. I wrote a function with which I can drive these motors with ease. Two logic pins (one is PWM, meaning that I can determine the output voltage within the code) decide the speed and polarity. After Balrog I will completely revamp my Universal K'NEX Coaster System, with lots of added debugging tools, which I really missed during Balrog's assembly and testing. So the whole L293D configuration will be done in another way, too.

I am a software engineer but it has been over 25 years since I programmed anything as simple as a microcontroller. Your code is nicely organized and has some nice safety features built in. Did you develop that login incrementally because of issues you had in early versions or did you just try to cover all the bases when you first wrote it?

Actually I had most of the code written all in one day and there were only a few extra safety features that I added later, but still before the Balrog assembly. I only adjusted the timing constants in the initialization process during Balrog tests. In the end some problems arose, so I thought they were code-related. I had a lot of trouble trying to debug the shit out of Balrog, but it turned out to be hardware-related (motor plugs didn't stay in the motors properly). The code appeared to be good after all. But like I said before, I will completely revamp the system, so the code will be completely different, too.

Also do you have any pictures of your servo controlled brakes either here or in the Balrog thread?

I decided not to use servo controlled brakes. Integrating servos into K'NEX appeared to be a tough job and the combination with magnetic brakes sucked too. Perhaps in a later project.


SSCoasters Administrator
The SSCoasters Forum Rules
DD_signature.jpg
YoutubeButton.pngFacebookButton.png


#33 ForgotToGrowUp

ForgotToGrowUp

    Lead Engineer

  • 1732 posts

Posted 26 July 2012 - 08:46 AM

Yes I saw that and found that there are several commercial shields available using that same L239D chip. They seem to include some extra logic to prevent votage spikes from the motors coming back in to the circuit and "pull down" resistors to prevent power from getting to the motor during start up. Here is a common one Adafruit Motor/Stepper/Servo Shield for Arduino kit [v1.0] ID: 81 - $19.50 : Adafruit Industries, Unique & fun DIY electronics and kits There are cheaper ones using the same chips available from China and Hong Kong on eBay. Reading this View topic - Method for stacking two Motor Shields to control 4 steppers • adafruit industries • Customer Support Forums, DIY Electronics, Open Source Hardware, Arduino it looks like you can stack the motor shields the only draw back is that the motors being controlled by the same pins will all run at the same speed, but you can drive 4 independent sets of motors with all the motors in a set running the same speed.

I think the only issue with simply wiring more than one motor to the output of the L293D chips is drawing too much current and overheating the chip. But I read elsewhere just putting a heat sink on the chip will work if you are going to be pushing it close to it's design limit (600ma). You can also stack L293Ds by simply soldering the pins on stacked chips together. The article said a stack of 2 is almost 2 times the current capacity, 3 stackcked aboutr 2.5 times... after 3 there is diminishing returns. So another option is instead of stacking shields you can use a single shield and get a couple extra chips to stack on the ones already there.

If I decide to go this route I'd rather just by components than build them. They are so cheap and I don't have tons of spare time.

I'm also on the fence about going with a Mega vs. an Uno. If I use the premade shields I think I am only going to have access to 4 of the PWM outputs that are common to the Uno and Mega the Uno probably can do just about anything I would want to do.

Thanks for sharing your design. All very cool.

Comet Recreation still underway.

Proof you never grow up if you keep playing with toys!


#34 APerfectCureMT

APerfectCureMT

    Newbie

  • Pip
  • 5 posts

Posted 29 December 2012 - 11:47 AM

great job! I recieved a electronics award in highschool...its so much fun!

  • dylpickled likes this

#35 I Love Ball Machines

I Love Ball Machines

    Newbie

  • PipPipPip
  • 39 posts

Posted 27 November 2017 - 09:41 PM

Can you use this to power 15 individual flat rides?  I am back at it again building funfair rides with my knex.   I would be willing to buy a complete system in a suitcase for my knex carnival rides.








Also tagged with one or more of these keywords: contest, nolimits, roller coaster simulator