Published on

Chat GPT Writes Perfect Arduino Code!

  • avatar
    Tinker Assist


In their own words, "OpenAI is an AI research and deployment company. Our mission is to ensure that artificial general intelligence benefits all of humanity." Recently, OpenAI released ChatGPT, which is a large language model (LLM) that can be interacted with via natural language prompts.

Anyone can interact with the model on an online, chat-like interface on the company's website, and millions of people have been pushing the model to it's limits. Most notably, developers have been assessing how effective ChatGPT is as a developer. The model has proven itself in many programming tasks - let's see how it handles the trivial task of arduino programming!

ChatGPT Prompt

I decided to give ChatGPT the task of writing an arduino program that flashes the onboard LED at an adjustable period and duty cycle. And I wanted to be able to set the period and duty cycles via the serial port.

"Write arduino code that flashes an LED at a certain period and duty cycle. The code will read in two comma-seperated values over serial. The first value is between 0 and 100 and will be used as the duty cycle. The second value is between 1 and 5 seconds and will be the period."

ChatGPT dialogue - inital prompt

Additional ChatGPT Prompts to Fine-Tune the Code

While I was impressed with this start, I noticed prior to running that this was not perfect. With the provided loop function, the program would only work if we had a continuous input stream to our serial port. Thus, I made the following request, and got a positive response.

Second ChatGPT Prompt

"Can you rewrite the code above to continue flashing the LED even if the serial port has no new data?"\

ChatGPT dialogue - second prompt

Diff between initial response and refined response

ChatGPT code diff - second prompt

As we can see, the digitalWrite and delay function calls were brought out of the if statement, along with the delay length variables. Additionally, the duty cycle and period variables were initialized at the beginning of the file. I wanted the sequence to start as one second on, one second off, so I made the following request.

Third ChatGPT Prompt

"Can you rewrite the above code to initialize the duty cycle to 50% and the period to 2 seconds"

ChatGPT dialogue - third prompt

Diff between last response and new response

ChatGPT code diff - third prompt

Again, well executed by the model. I noticed at this time that my initial bounds of 1-5 second period and 10-100 duty cycle was not being enforced by this code. Thus, I made the below request, which rendered a response I was initially pleased with.

Fourth ChatGPT Prompt

"Change the code above to print an error over serial if the duty cycle is not between 10 and 100, or if the period is not between 1 and 5 seconds"

ChatGPT dialogue - fourth prompt

Diff between last response and new response

ChatGPT code diff - fourth prompt

I thought my previous request was addressed with this response, so I plugged in my arduino and flashed the code. However, I quickly realized that the bounds I set for duty cycle and period were not truly being honored. The values could still be set outside of the bounds I outlined, even though the arduino would output an "error". I prompted the model with my problem and it made the appropriate fix.

Fifth ChatGPT Prompt

"The above code throws an error, but the values for input and period still get set to out of bounds values. Adapt the above code to only update the input and period if the input values are within the specified range"

ChatGPT dialogue - fifth prompt

Diff between last response and new response

ChatGPT code diff - fifth prompt

I was pretty happy with what I had received by this point. While the model did not give me precisely what I wanted in the beginning, a few requests later, I was able to extract just what I wanted. Not only that, but my request was honored with concise, well-formatted, readable code.

I encourage others to coax a similar task solution out of ChatGPT. I imagine these models will rapidly improve over the coming years, and it will be interesting to compare/contrast the effort taken to extract a simple solution among model iterations.

Final Code

const int LED = 13;  // The pin where the LED is connected
int dutyCycle = 50;  // Default duty cycle set to 50%
int period = 2000;   // Default period set to 2 seconds in milliseconds

void setup() {
  pinMode(LED, OUTPUT);  // Set the LED pin as output
  Serial.begin(9600);    // Start serial communication

void loop() {
  if (Serial.available() > 0) {  // Check if there's data available to read
    String input = Serial.readStringUntil(',');  // Read the first value as a string
    int newDutyCycle = input.toInt();  // Convert the string to an integer

    input = Serial.readStringUntil('\n');  // Read the second value as a string
    int newPeriod = input.toInt() * 1000;  // Convert the string to an integer and multiply by 1000 to get milliseconds

    if (newDutyCycle >= 10 && newDutyCycle <= 100) {  // Check if the new duty cycle is within range
      dutyCycle = newDutyCycle;
    } else {
      Serial.println("Error: Duty cycle must be between 10 and 100");

    if (newPeriod >= 1000 && newPeriod <= 5000) {  // Check if the new period is within range
      period = newPeriod;
    } else {
      Serial.println("Error: Period must be between 1 and 5 seconds");

  int onTime = (dutyCycle / 100.0) * period;  // Calculate the on time based on the duty cycle
  int offTime = period - onTime;  // Calculate the off time based on the duty cycle

  digitalWrite(LED, HIGH);  // Turn the LED on
  delay(onTime);             // Wait for the on time
  digitalWrite(LED, LOW);   // Turn the LED off
  delay(offTime);            // Wait for the off time