Skip to main content

Chat Generative Pre-trained Transformer (ChatGPT) is a chatbot by OpenAI.

The project is to create a train control to allow trolleys approaching from opposite directions to pass via a siding.

The hardware consists an Arduino with a Relay shield to provide the outputs and opto isolators to provide the inputs.

The switch controls are wired together so that there are only two relay outputs required to create the two conditions (sw1, sw2). There is one relay output to control power (pwr) to the center rail insulated section to stop the first trolley until the second trolley passes and then allows the first trolley to proceed. There are three insulated outer rail sections for inputs to control the Arduino logic (inp1, inp2, inp3).

Track diagrams are shown below:  



TOONERVILLE

It took several tries to determine the correct wording for the logic input for ChatGPT to get the correct Arduino code. The final logic describing the ChatGPT input is as follows:

create an Arduino sketch
comment TOONERVILLE TROLLEY PASSING SIDING ver 1.5
comment David Nissen  Oct 31,2023
comment This sketch generated by ChatGPT
three inputs with pullup on pins 4, 5, 6, inp1, inp2, inp3
three outputs on pins 7,8,9, sw1, sw2, pwr
initial all outputs low

comment CONDITION 1 (INPUT 1 FIRST)
if inp1 low
comment 0.5 second output to throw switches to position 1
sw1 high for 0.5 sec then low
comment Wait for input 3
wait for inp3 low
comment 0.5 second output to throw switches to position 2
sw2 high for 0.5 sec then low
comment Wait for 2 seconds then turn on power for 5 seconds
delay 2 sec
pwr high for 5 sec then low
comment Wait for 10 seconds before restarting the process
delay 10 sec

comment CONDITION 2 (INPUT 2 FIRST)
if inp2 low
comment 0.5 second output to throw switches to position 2
sw2 high for 0.5 sec then low
comment Wait for input 3
wait for inp3 low
comment 0.5 second output to throw switches to position 1
sw1 high for 0.5 sec then low
comment Wait for 2 seconds then turn on power for 5 seconds
delay 2 sec
pwr high for 5 sec then low
comment Wait for 10 seconds before restarting the process
delay 10 sec



Chat GPT created the following output Arduino Sketch:

Here's an Arduino sketch based on your requirements. This sketch controls three inputs with pull-up resistors on pins 4, 5, and 6, and three outputs on pins 7, 8, and 9. The outputs are used to control switches (sw1 and sw2) and power (pwr).

// TOONERVILLE TROLLEY PASSING SIDING ver 1.5
// David Nissen Oct 31, 2023
// This sketch generated by ChatGPT

int inp1 = 4;
int inp2 = 5;
int inp3 = 6;
int sw1 = 7;
int sw2 = 8;
int pwr = 9;

void setup() {
  pinMode(inp1, INPUT_PULLUP);
  pinMode(inp2, INPUT_PULLUP);
  pinMode(inp3, INPUT_PULLUP);
  pinMode(sw1, OUTPUT);
  pinMode(sw2, OUTPUT);
  pinMode(pwr, OUTPUT);

  // Initial state: All outputs low
  digitalWrite(sw1, LOW);
  digitalWrite(sw2, LOW);
  digitalWrite(pwr, LOW);
}

void loop() {
  // CONDITION 1 (INPUT 1 FIRST)
  if (digitalRead(inp1) == LOW) {
    // 0.5 second output to throw switches to position 1
    digitalWrite(sw1, HIGH);
    delay(500);
    digitalWrite(sw1, LOW);
    
    // Wait for input 3
    while (digitalRead(inp3) == HIGH) {
      // Wait until inp3 goes low
    }
    
    // 0.5 second output to throw switches to position 2
    digitalWrite(sw2, HIGH);
    delay(500);
    digitalWrite(sw2, LOW);
    
    // Wait for 2 seconds
    delay(2000);
    
    // Turn on power for 5 seconds
    digitalWrite(pwr, HIGH);
    delay(5000);
    digitalWrite(pwr, LOW);
    
    // Wait for 10 seconds before restarting the process
    delay(10000);
  }

  // CONDITION 2 (INPUT 2 FIRST)
  if (digitalRead(inp2) == LOW) {
    // 0.5 second output to throw switches to position 2
    digitalWrite(sw2, HIGH);
    delay(500);
    digitalWrite(sw2, LOW);
    
    // Wait for input 3
    while (digitalRead(inp3) == HIGH) {
      // Wait until inp3 goes low
    }
    
    // 0.5 second output to throw switches to position 1
    digitalWrite(sw1, HIGH);
    delay(500);
    digitalWrite(sw1, LOW);
    
    // Wait for 2 seconds
    delay(2000);
    
    // Turn on power for 5 seconds
    digitalWrite(pwr, HIGH);
    delay(5000);
    digitalWrite(pwr, LOW);
    
    // Wait for 10 seconds before restarting the process
    delay(10000);
  }
}


This sketch first sets up the pins and initializes them as specified. Then, it continuously checks the conditions for either INPUT 1 FIRST or INPUT 2 FIRST and performs the required actions accordingly. It uses delays for timing as you described.AI

Attachments

Images (1)
  • TOONERVILLE
Original Post

Replies sorted oldest to newest

The project is now in the second phase which is testing the Arduino with a relay shield and the optical isolators on the floor. The third phase will be to mount all parts on a board.

Marx switches were used as they have no dead spot to stop the trolleys which have only one power pickup. O to O27 adapter pins were  made to allow O gauge track to connect to the Marx switches. 1/4 inch plywood was placed under the switches to compensate for the height difference. Insolated outside rails were made for the three input signals.

Results of the test is demonstrated below.

The final track plan will have a Toonerville turntable at each end of the track.



Attachments

Videos (1)
Toonerville Trolley Passing Siding
Files (1)
@BillYo414 posted:

I've been resisting learning ChatGPT because I think it's going to fizzle out. The hype definitely calmed down a bit. But I didn't know it could do this! Great work!

Did you teach yourself on how to write the prompts?

I think the challenge for more complicated applications will be trying to write the description accurate and clear enough for ChatGPT to come up with a workable result.

I'd like to see a sample of the query and the code generated for a more complex problem.

I think this may be a harbinger of things to come, but I don't think it's here yet.  For decades people have been announcing that within ten years programmers will be obsolete.  I remember in the 1970's people were telling me that I should be considering what I'd do when all the electrical engineering and computer programming was done by machine.  There may actually be a possibility that I see some of that come true in my lifetime!   OTOH, I managed to eke out a living in software and electrical engineering for my entire career, and I still tinker with it.

As a 60 yo programmer,,, I'm counting on chat taking a least 5 years to grow up. Right now chat is like getting a new puppy and using it is proving to yourself that you can teach the puppy to do new tricks. Right now chat doesn't know if its 'solutions' actually work. When it starts running simulations that's when its intelligence will ramp up much faster.

Prompt: Build a ping pong table-sized o-gauge train layout using Fastrack

Solution: Building a model train layout can be a fun and rewarding project. Since you mentioned using O-Gauge Fastrack, let's design a basic ping pong table-sized O-Gauge train layout. The dimensions of a ping pong table are approximately 9 feet by 5 feet, so we'll design the layout to fit within these dimensions.

**Materials:**
1. O-Gauge Fastrack pieces (straight tracks, curves, switches, etc.)
2. O-Gauge trains and rolling stock
3. O-Gauge transformer
4. Buildings, scenery, and accessories (optional)
5. Plywood or foam board for the base
6. Screws or adhesive for securing the track

**Layout Design:**

*Note: The following is a basic design. Feel free to modify it based on your preferences.*

1. **Baseboard Preparation:**
- Start with a 9ft x 5ft plywood or foam board as your base.
- Ensure that the base is sturdy and level.

2. **Main Loop:**
- Create an outer loop using O-Gauge Fastrack curves and straights. This will be your main line.
- Add a siding or passing loop to allow for multiple trains or operations.

3. **Sidings and Switches:**
- Incorporate a couple of sidings or spurs for parking trains or displaying rolling stock.
- Use O-Gauge Fastrack switches to create interesting configurations.

4. **Elevations and Bridges:**
- Experiment with elevations to add visual interest. You can use foam risers to create hills or inclines.
- Consider adding a bridge or overpass to create a more dynamic layout.

5. **Station and Buildings:**
- Place a station or depot along the main line for a central point of interest.
- Add buildings, such as a small town or industrial structures, to enhance the scenery.

6. **Landscaping and Scenery:**
- Use model scenery materials to create a realistic environment. This can include grass, trees, rocks, and roads.
- Consider adding a water feature, like a pond or river, using realistic materials.

7. **Electrical Wiring:**
- Ensure proper electrical wiring for the track. Connect the Fastrack pieces according to the manufacturer's instructions.
- Use a transformer to power the layout, and consider adding accessories such as lights or animated features.

8. **Test Run:**
- Before finalizing the layout, test the track with a train to ensure smooth operation.
- Check for any areas where derailments or electrical issues may occur and make adjustments as needed.

Remember that this is a basic layout, and you can customize it based on your preferences, available space, and the specific Fastrack pieces you have. Feel free to add more complexity, such as additional loops, industries, or a more detailed landscape, as you become more experienced.

A layout built by AI... underwhelming. It knows a ping-pong table is 5x9.

I'd rather visit OGR and get actual intelligence and mess up that advice while I'm learning to build a layout.

I think it's a great tool and I'm glad @David Nissen posted this because it didn't occur to me to use it in this way. I was tinkering with it and I'm fascinated that it would choose to give an explanation to the sentence "Write an Arduino Sketch to turn an LED on and off every second." It seems to me that it should just return the code and move on. It did the same thing for you, @Stephen Sharpe. That's interesting to me.

Either way, I have a lot of hopes and dreams for my layout that Arduino could help resolve so this is very exciting stuff! I just have to wonder if the years I've spent developing a CAD model of a steel mill were a waste haha could AI have created that model in minutes and given it to me to polish up and 3D print?

I tried something simple, worked better than I thought it would.  Since I use the Microchip PIC family, I went for something using one of the processors I work with.

I gave ChatGPT a single line request:

User:

pic12f1501 c code to simulate a strobe light

ChatGPT:

Creating a simulation of a strobe light using a PIC12F1501 microcontroller involves writing code in C that toggles the output pin at a specific frequency to simulate the flashing effect. Below is a simple example code for a strobe light simulation using the XC8 compiler for the PIC12F1501 microcontroller. This code assumes you have a basic understanding of programming PIC microcontrollers and have set up your development environment.

#include <xc.h>


// Configuration bits
#pragma config FOSC = INTOSC // Internal oscillator
#pragma config WDTE = OFF // Watchdog Timer disabled
#pragma config PWRTE = OFF // Power-up Timer disabled
#pragma config MCLRE = OFF // MCLR pin function is digital input

#define _XTAL_FREQ 4000000 // Internal oscillator frequency (4 MHz)

void delay_ms(unsigned int milliseconds);

void main(void) {
TRISIO = 0b00000000; // Set all pins as output

while (1) {
GPIO = 0xFF; // Turn on the strobe light (all pins high)
delay_ms(50); // Delay for 50 milliseconds
GPIO = 0x00; // Turn off the strobe light (all pins low)
delay_ms(50); // Delay for 50 milliseconds
}

return 0;
}

void delay_ms(unsigned int milliseconds) {
while (milliseconds--) {
__delay_ms(1);
}
}

This code configures the PIC12F1501 to use its internal oscillator, sets all GPIO pins as outputs, and then enters an infinite loop where it alternately turns on and off the strobe light with a delay of 50 milliseconds between each state.

Make sure to adapt the code according to your specific requirements, such as changing the frequency or duty cycle of the strobe light. Additionally, adjust the configuration bits based on your hardware setup and compiler settings.

Then I added a bit to the request.

User:

pic12f1501 c code to simulate a strobe light with slow turn-on and turn-off

ChatGPT:

Certainly! Below is a simple example of PIC12F1501 C code to simulate a strobe light with slow turn-on and turn-off. This code uses the XC8 compiler for PIC microcontrollers.

#include <xc.h>

// PIC12F1501 Configuration Bit settings
#pragma config FOSC = INTOSCIO // Oscillator Selection bits (Internal oscillator, port function on RA4/OSC2/CLKOUT pin, I/O function on RA5/OSC1/CLKIN)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = OFF // MCLR Pin Function Select bit (MCLR/VPP pin function is digital input, MCLR internally tied to VDD)
#pragma config CP = OFF // Code Protection bit (Program memory code protection is disabled)
#pragma config BOREN = ON // Brown-out Reset Selection bits (BOR enabled)
#pragma config CLKOUTEN = OFF // Clock Out Enable bit (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)

#define _XTAL_FREQ 4000000 // Set the internal oscillator frequency to 4 MHz

void delay_ms(unsigned int milliseconds);

void main(void) {
// Set internal oscillator frequency to 4 MHz
OSCCONbits.IRCF = 0b1101;

// Configure RA0 as an output
TRISA0 = 0;

// Strobe light loop
while (1) {
// Turn on the strobe light gradually
for (int i = 0; i < 255; i++) {
RA0 = 1; // Turn on the strobe light
delay_ms(5); // Delay for a smooth turn-on
}

// Turn off the strobe light gradually
for (int i = 255; i > 0; i--) {
RA0 = 0; // Turn off the strobe light
delay_ms(5); // Delay for a smooth turn-off
}
}

return 0;
}

// Function to generate a delay in milliseconds
void delay_ms(unsigned int milliseconds) {
for (unsigned int i = 0; i < milliseconds; i++) {
__delay_ms(1);
}
}

This code configures the PIC12F1501 to use its internal oscillator with a frequency of 4 MHz. It gradually turns on and off the strobe light by adjusting the duty cycle. The delay_ms function provides a delay in milliseconds for a smooth turn-on and turn-off effect.

Please note that you may need to adjust the delay times and other parameters based on your specific requirements and the characteristics of the LED or strobe light you are using.

Something to get used to with these current AI tools is learning how to a conversation with it (ChatGPT or Google Bard). We are used to each request having to be fully qualified and that isn't the case here.

Taking John's example above, the first message could be what he wrote:
pic12f1501 c code to simulate a strobe light
while the second prompt could have been:
add a slow on and off to the strobe light application
It "understands" your request is about the last thing you told it and you don't have to tell it everything again.

The tools should remember context and doing it in this manner will have the response return what is different. As an example, for the 2nd prompt, besides the enhanced code, the response started with:
Here's the modified code with slow fade-in and fade-out:
and then after the code:

This code adds a fade-in and fade-out effect by gradually adjusting the LED brightness over multiple steps (FADE_STEPS) before reaching full brightness and then dimming down again. This creates a smoother transition and less jarring strobe effect.

Adjustments:

  • FADE_STEPS: Increase this value for slower fade, decrease for faster.
  • on_time & off_time: Adjust based on desired overall strobe speed.


In this approach, it provides some info on the latest change.

My own experience around programming was so-so. I asked it to generate a PHP program to read a CSV file of ISBN-10 values, convert ISBN-10 to ISBN-13, and out the both values in a new CSV file. It did a good job on the over structure and handling of reading/looping/writing , but in the critical part, it blew it and wrote bad conversion code, though the comments about the code were accurate.

Like Stephen, I'm a 60 yr old programmer, though very little programming and a lot more management now. Programming will still exist but it might be understanding how to leverage these tools. I can go back to the late 80s with tools that were going to eliminate coding/programmers. My experience was that they made good programmers generate good code faster, while at the same time having bad programmers generate bad code faster. 

So far I believe that ChatGPT has saved me much time over just coding. In the past I spent time debugging the code such as unmatched parenthesis missing semicolons, misspelled variables, and many other coding errors.

When I run the Arduino IDE verify on ChatGPT code I get no errors. Debugging just consists of checking to see if the logic is correct and that the input to ChatGPT was understood.

Examples of misunderstood input was when I wanted a 1/2 sec pulse to turn a switch, I described it as:
    sw2 high for 0.5 sec
what I got was sw2 high for 1/2 sec and then the output stayed high.
    sw2 high for 0.5 sec then low
then gave me the desired results.

Perhaps ChatGPT would have understood the word pulse.

Arduino has many libraries that can be used such as adding software serial ports, reading and writing to the internal EPROM, reading an encoder using interrupts (must faster) and many others, ChatGPT is aware of these libraries and can include them without me having to do research and learning how to implement them saving much time.

I intend to keep testing ChatGPT to create code as I believe it will improve in the future as it learns.

Since ChatGPT is a learning program I can envision something like the following input:
    
    TMCC commands consist of three bytes
    The first byte is FE
    Increase train 1 speed second byte is C8
    Increase train 1 speed third byte is C6
    Decrease train 1 speed second byte is C8
    Decrease train 1 speed third byte is C4

after learning will become:

    Increase train 1 speed for each CW encoder click
    Decrease train 1 speed for each CCW encoder click

This will require further testing as I don't know how the learning process works.

So far I believe that ChatGPT has saved me much time over just coding. In the past I spent time debugging the code such as unmatched parenthesis missing semicolons, misspelled variables, and many other coding errors.

When I run the Arduino IDE verify on ChatGPT code I get no errors. Debugging just consists of checking to see if the logic is correct and that the input to ChatGPT was understood.

My recent coding has been using MPLAB-X for PIC processors, most of the syntax stuff is well sniffed out by the IDE, so I spend minimal time hunting that down.

Since ChatGPT is a learning program I can envision something like the following input:
    
    TMCC commands consist of three bytes
    The first byte is FE
    Increase train 1 speed second byte is C8
    Increase train 1 speed third byte is C6
    Decrease train 1 speed second byte is C8
    Decrease train 1 speed third byte is C4

after learning will become:

    Increase train 1 speed for each CW encoder click
    Decrease train 1 speed for each CCW encoder click

This will require further testing as I don't know how the learning process works.

It would be interesting if it could generate code for the internal TMCC and/or Legacy code.  The TMCC serial data inside the locomotive is a single byte, the framing and addressing is all omitted since it's assumed that the serial data inside is for the current engine.  I wonder if it could deal with that, that would be pretty useful.

I have several projects that use an Arduino to receive serial commands from the TMCC. This is not an issue to tie several inputs together fron several projects. But several projects send serial data back to the base 1. You can't tie several serial outputs together to send data to the base 1.

I have been thinking about making a bidirectional multiport device to solve this problem. It seemed like a good candidate for a more complex test for ChatGPT. Following is the results.

================================================================
    Input to ChatGPT
================================================================

create an Arduino sketch
use SoftSerial to create 3 serial ports on pins (2,3),(4,5),(6,7) at 9600 baud
data will consist of repeating 3 byte commands
the first byte of each command must be FE
input commands from each port will be output as 3 byte commands to each of the other ports

================================================================
    Output from ChatGPT
================================================================

Certainly! Here's an example Arduino sketch that utilizes the SoftSerial library to create three serial ports on pins (2,3), (4,5), and (6,7) at a baud rate of 9600. It will read incoming 3-byte commands from each port and forward them to the other ports:

---------------- Begin of Sketch ----------------------

#include <SoftwareSerial.h>

SoftwareSerial port1(2, 3); // RX, TX for port 1
SoftwareSerial port2(4, 5); // RX, TX for port 2
SoftwareSerial port3(6, 7); // RX, TX for port 3

void setup() {
  Serial.begin(9600); // For debugging purposes
  port1.begin(9600);
  port2.begin(9600);
  port3.begin(9600);
}

void loop() {
  // Check for available data on each port
  if (port1.available() >= 3) {
    forwardData(port1, port2, port3);
  }
  if (port2.available() >= 3) {
    forwardData(port2, port1, port3);
  }
  if (port3.available() >= 3) {
    forwardData(port3, port1, port2);
  }
}

void forwardData(SoftwareSerial &fromPort, SoftwareSerial &toPort1, SoftwareSerial &toPort2) {
  // Read the incoming 3-byte command
  byte command[3];
  for (int i = 0; i < 3; i++) {
    command[i] = fromPort.read();
  }

  // Check if the first byte is FE
  if (command[0] == 0xFE) {
    // Send the command to other ports
    toPort1.write(command, 3);
    toPort2.write(command, 3);
    // For debugging purposes, print received command
    Serial.print("Received: ");
    for (int i = 0; i < 3; i++) {
      Serial.print(command[i], HEX);
      Serial.print(" ");
    }
    Serial.println();
  }
}

---------------- End of Sketch ----------------------

This code sets up three instances of SoftwareSerial for the three serial ports. The loop() function continuously checks for available data on each port and, if a 3-byte command starting with 0xFE is received, it forwards it to the other two ports.

Please note that using SoftwareSerial for multiple ports simultaneously might have some limitations, such as potential timing issues and data loss at higher baud rates or intensive data traffic. If you encounter such problems, using hardware serial ports or alternative communication methods might be necessary.

================================================================
    End of Output from ChatGPT
================================================================

I normally leave the hardware serial port open for loading the sketches without having to disconnect another hardware port user. ChatGPT initialized the port and added debugging code to print to the serial monitor. ChatGPT also created a "forwardData" function. I found it to be much easier to describe the input to ChatGPT than I think it would be to write the code.

Now I'll have to setup a breadboard and test to see if I described the logic so that ChatGPT would understand me.

Add Reply

Post
×
×
×
×
Link copied to your clipboard.
×
×