Chat GPT-4 Code First Impressions

I’ve been playing with Chat GPT for a few weeks now mostly just kicking the tires but I decided to throw it at some simple Arduino code requests at it:

write an arduino program that controls a stepper motor using an 8825 driver. The direction pin is 4 and the step pin is 5. A global variable of “StepCount” should be initially set to zero. A second global variable of “MaxSteps” should be set to “2000”

A function named “Movement” should allow for serial control with 3 parameters: “direction” (0 for “forward” and 1 for “backward”), “speed” in steps per second, and “steps” the number of steps. After each step if direction is forward and StepCount is less than than MaxSteps increment the “StepCount” by +1. If the Direction is “backward” and “StepCount” >0 increment the “StepCount” by -1.

Another function called “Reset” should allow for serial control and set the “StepCount” to 0.

I made 3 to 4 clarifications then asked chat GPT for a summary of what I tasked it with:

You are tasked with writing an Arduino program that controls a stepper motor using an 8825 driver. The program should have two global variables:

StepCount, initially set to zero.
MaxSteps, set to 2000.
The program should have two functions:

Movement: allows for serial control with three parameters:

direction (0 for “forward” and 1 for “backward”)
speed in steps per second
steps the number of steps to move
After each step, if the direction is “forward” and StepCount is less than MaxSteps, increment StepCount by 1. If the direction is “backward” and StepCount is greater than 0, increment StepCount by -1. When the movement command is done, the program should respond with “Movement Complete: X” (where X is the final value of StepCount) via the serial port.
Reset: allows for serial control and sets StepCount to 0. When the reset command is done, the program should respond with “Coordinates Reset” via the serial port.

When the program starts, it should send the message “Focuser Ready” via the serial port and list the available functions with sample usage.

If the program receives an unknown command, it should respond with “Unknown Command” via the serial port.

to which it responded with the very decent:

// Define the pin assignments for the stepper motor driver
#define dirPin 4
#define stepPin 5

// Define the global variables for step count and maximum steps
int StepCount = 0;
int MaxSteps = 2000;

// The Movement function allows for serial control of the stepper motor
void Movement(int direction, int speed, int steps) {
  // Set the direction pin
  digitalWrite(dirPin, direction);
  
  // Step the motor for the specified number of steps at the specified speed
  for (int i = 0; i < steps; i++) {
    digitalWrite(stepPin, HIGH);
    delayMicroseconds(500000 / speed);
    digitalWrite(stepPin, LOW);
    delayMicroseconds(500000 / speed);
    // Update the step count based on the direction of movement
    if (direction == 0 && StepCount < MaxSteps) {
      StepCount++;
    }
    else if (direction == 1 && StepCount > 0) {
      StepCount--;
    }
  }
  
  // Print the movement completion message with the current step count
  Serial.print("Movement Complete: ");
  Serial.println(StepCount);
}

// The Reset function allows for serial control to reset the step count to zero
void Reset() {
  StepCount = 0;
  Serial.println("Coordinates Reset.");
}

// The UnknownCommand function is called when an unknown command is received
void UnknownCommand() {
  Serial.println("Unknown Command");
}

// Set up the initial state of the stepper motor and send the "Focuser Ready" message
void setup() {
  pinMode(dirPin, OUTPUT);
  pinMode(stepPin, OUTPUT);
  Serial.begin(9600);
  // List available functions with sample usage
  Serial.println("Available functions:");
  Serial.println("  - Movement: M<direction>,<speed>,<steps> (e.g. M0,500,1000 to move forward at 500 steps per second for 1000 steps)");
  Serial.println("  - Reset: R (e.g. R to reset the step count to zero)");
}

// Main loop of the program
void loop() {
  // Check for serial input from the user
  if (Serial.available() > 0) {
    // Read the incoming command
    String command = Serial.readStringUntil('\n');
    // Parse the command string
    int firstComma = command.indexOf(',');
    int secondComma = command.indexOf(',', firstComma + 1);
    int direction = command.substring(0, firstComma).toInt();
    int speed = command.substring(firstComma + 1, secondComma).toInt();
    int steps = command.substring(secondComma + 1).toInt();
    // Call the appropriate function based on the command
    if (command.startsWith("M")) {
      Movement(direction, speed, steps);
    }
    else if (command.startsWith("R")) {
      Reset();
    }
    else {
      UnknownCommand();
    }
  }
}

The code has a few bugs in how it tracks the steps but pretty good for the rather vague directions I gave it. But it can go a number of steps at a specific speed in a specific direction with no code changes from me.

Now lets write a python client for the app:

write a python client that talks to the Arduino application via serial port. Create functions in python that call each of the Arduino functions with the appropriate parameters.

import serial
import time

# Connect to the Arduino via the serial port
ser = serial.Serial('/dev/ttyACM0', 9600, timeout=1)

# Wait for the Arduino to reset
time.sleep(2)

# Define a function to start the program on the Arduino
def start_program():
    ser.write(b'start\n')
    response = ser.readline().decode().rstrip()
    print(response)

# Define a function to move the motor on the Arduino
def move_motor(direction, speed, steps):
    command = f'move,{direction},{speed},{steps}\n'
    ser.write(command.encode())
    response = ser.readline().decode().rstrip()
    print(response)

# Define a function to reset the motor position on the Arduino
def reset_motor():
    ser.write(b'reset\n')
    response = ser.readline().decode().rstrip()
    print(response)

# Call the start_program function to start the program on the Arduino
start_program()

# Call the move_motor function to move the motor forward
move_motor(0, 100, 500)

# Call the move_motor function to move the motor backward
move_motor(1, 50, 200)

# Call the reset_motor function to reset the motor position
reset_motor()

# Close the serial connection
ser.close()

Not too shabby… other than the unneeded start function and having to define the COM port it just works.

5 Likes

Maybe time to vacuum all the forums into a pinecone database and then ask about cnc machine issues (for real this time).

Maybe I’ll do that after I finish using GPT to produce an online course on how to make money online by using GPT to produce courses.

2 Likes

I don’t know how serious you were about the pinecone database thing but it piqued my interests. I both don’t know anything about pinecone/gpt and believe you can do about anything based on all of your very cool projects.

In as much or as little detail as you want (but hopefully not zero), how would you go about doing this?

1 Like

I was joking, and I only understand at a very rough level after seeing one or two youtube videos.

The concept is, you split the content into fragments. For the sake of argument let’s pretend each post is one fragment. The fragments are sent to an API that translates text into vectors. The database stores pairs of (vector, fragment) covering all the content, i.e. many thousands of pairs.

Then when you get a question, you send the question to the same API to get a vector for the question. Then you query the database with the question vector to get some fragments that are most relevant to the question.

Then you assemble those fragments and the original question into a single piece of text that is “fragment, fragment, fragment, fragment, question”, and you submit that to the ChatGPT API.

Hopefully the fragments contain enough to answer to the question and the ChatGPT smarts can understand well enough to pick it out and answer the question with coherent English. Like a noob with Google (can be dangerous!)

The vectors encode something like semantic proximity, that is much, much better than keywords for example. They are called embeddings. The pinecone database does semantic search but really the magic is in the translation from fragments to vectors, and pinecone is just querying by vector proximity.

That is my ‘noob with Google’ answer and I could be wrong!

1 Like

Thanks for the overview. My remote IT team is rolling out new software that I’m (a process engineer) expected to train people on. It’d be really cool to somehow assemble all of the word documents, powerpoints, transcribed recorded sessions into a chatbot and say, “Here’s a quick overview, ask any questions to the bot” lol.

A lot of work though, maybe in a few years. Maybe chatgpt can tell me how though.

I’m using it a fair amount at work for rewriting documentation.

I feed it the bullet points and it gives me a pretty good draft document to work with. Not perfect but it gets me past the initial writers block of where to start and into editor mode of how to make this flow properly.

Also I’ve come to love the prompt “Summarize this in 2 paragraphs written for a 6th grader”

2 Likes

Which is still too long, and over the heads of most C-Suite occupants… Their assistants probably run everything through the “No more than five sentences, written for a five year old” filter.

1 Like

One new barely documented feature of GPT 4 is that you can point it to a url for source material which is nice. It still only takes the first few thousand characters of text though so you have to be careful.

1 Like