Two different problems, starting with simple temperature regulator

I'm working on a project that will extrude recycled pellets, and I have 2 problems with it:

  1. I need to make a simple temperature regulator that will turn on and off the heater, and I just want to use something simple. So far, my idea is to use a delay_until( temperature_sensor == 250 C) sort of function (if that's even a function), but I will take any other function that works.

  2. This is less important, but this idea is to make a settings menu that controls the temperature of the extruder, and that will automatically stop and sound an alarm when the pellets run out via an ir
    sensor, if that's even possible, because I heard that an Arduino can't multitask.

Any answers accepted!!

This is a fairly easy project to deliver... even for a relative beginner.

Well it can't do 2 things at exactly the same time, but it can easily manage to do things so fast that you would think it was. Micro-controllers are incredibly fast... so the technique is to loop quickly around all the things that need to be done, so that they appear to all be done at once.

First place to start is to get a really clear idea about how everything should work. A clear set of requirements is key.
Then start looking for suitable hardware components. e.g. a temperature sensor that can handle 250C.
Then get each one working individually. There are lots of tutorials available.
Then bring it all together.

There are lot of great examples out there, and lots of people on this forum that will help.

If this is for an industrial process my approach would be to get this working first

we need to know more about your experience with arduino, and also the hardware you will be using. - so what the heater is and how you will turn the heater on & off.

Well right now I'm simulating it on Tinkercad so I have no real hardware, but I'm using a 5v relay to control the heater and motor, with 3 buttons. Here is (so far) my code:


//This is written in C++
//
//#include <EEPROM.h>
#include <Adafruit_LiquidCrystal.h>

 //#define buttonhome 11 
 #define buttonstart 10
 #define buttonsettings 9
 #define buttonminus 8
 #define thermistorPin A0
 #define heaterSwitch 3
 #define motorSwitch 2
 #define pinTemp A0

Adafruit_LiquidCrystal lcd_1(0);

  int startPressed = digitalRead(buttonstart);
  int setPressed = digitalRead(buttonsettings);
  int minPressed = digitalRead(buttonminus);
  float sensorInput;
  float temp;
  

void setup()
{
  pinMode(buttonminus, INPUT);
  pinMode(buttonsettings, INPUT);
  pinMode(buttonstart, INPUT);
  pinMode(heaterSwitch, OUTPUT);
  digitalWrite(heaterSwitch, HIGH);
  pinMode(motorSwitch, OUTPUT);
  digitalWrite(motorSwitch, HIGH);
  lcd_1.begin(16, 2);
  Serial.begin(9600);
  
  /*
  buttonStart = digitalRead(8);
  buttonSettings = digitalRead(9);
  buttonMinus = digitalRead(10);
  /*/
  int heaterThresh = 240;
  /*int buttonStart = 0;
  int buttonSettings = 0;
  int buttonMinus = 0;
  /*/
  
  lcd_1.setCursor(0, 0);
  lcd_1.print("Arduino Extruder");
  lcd_1.setCursor(0, 1);
  lcd_1.print("          V1.0.2");
  delay(2500); // Wait for 2500 millisecond(s)
  lcd_1.scrollDisplayLeft();
  delay(90); // Wait for 90 millisecond(s)
  lcd_1.scrollDisplayLeft();
  delay(90); // Wait for 90 millisecond(s)
  lcd_1.scrollDisplayLeft();
  delay(90); // Wait for 90 millisecond(s)
  lcd_1.scrollDisplayLeft();
  delay(90); // Wait for 90 millisecond(s)
  lcd_1.scrollDisplayLeft();
  delay(90); // Wait for 90 millisecond(s)
  lcd_1.scrollDisplayLeft();
  delay(90); // Wait for 90 millisecond(s)
  lcd_1.scrollDisplayLeft();
  delay(90); // Wait for 90 millisecond(s)
  lcd_1.scrollDisplayLeft();
  delay(90); // Wait for 90 millisecond(s)
  lcd_1.scrollDisplayLeft();
  delay(90); // Wait for 90 millisecond(s)
  lcd_1.scrollDisplayLeft();
  delay(90); // Wait for 90 millisecond(s)
  lcd_1.scrollDisplayLeft();
  delay(90); // Wait for 90 millisecond(s)
  lcd_1.scrollDisplayLeft();
  delay(90); // Wait for 90 millisecond(s)
  lcd_1.scrollDisplayLeft();
  delay(90); // Wait for 90 millisecond(s)
  lcd_1.scrollDisplayLeft();
  delay(90); // Wait for 90 millisecond(s)
  lcd_1.scrollDisplayLeft();
  delay(90); // Wait for 90 millisecond(s)
  lcd_1.scrollDisplayLeft();
  delay(90); // Wait for 90 millisecond(s)
  lcd_1.clear();
 // delay(750); // Wait for 750 millisecond(s)
}

void loop()
{
    
    lcd_1.setCursor(3, 0);
    lcd_1.print("Select Mode");
    lcd_1.setCursor(0, 1);
    lcd_1.print("Start");
    lcd_1.setCursor(6, 1);
    lcd_1.print("DEPRECATED");
    
  int startPressed = digitalRead(buttonstart);
  int setPressed = digitalRead(buttonsettings);
  int minPressed = digitalRead(buttonminus);
  	if(startPressed == HIGH){
		Serial.println("Start");
    } else if (setPressed == HIGH){
      Serial.println("Settings");
    } else if (minPressed == HIGH){
      Serial.println("-");
    }
  Serial.println(pinTemp);
  

  
  if (startPressed == HIGH) {
    
    startScreen();
    
    /*
    int temp = analogRead(pinTemp);
    lcd_1.clear();
    /*lcd_1.print("15");
    delay(1000); // Wait for 1000 millisecond(s)
    lcd_1.setCursor(0, 0);
    lcd_1.print("14");
    delay(1000); // Wait for 1000 millisecond(s)
    lcd_1.setCursor(0, 0);
    lcd_1.print("13");
    delay(1000); // Wait for 1000 millisecond(s)
    lcd_1.setCursor(0, 0);
    lcd_1.print("12");
    delay(1000); // Wait for 1000 millisecond(s)
    lcd_1.setCursor(0, 0);
    lcd_1.print("11");
    delay(1000); // Wait for 1000 millisecond(s)
    lcd_1.setCursor(0, 0);
    lcd_1.print("10");
    delay(1000); // Wait for 1000 millisecond(s)
    lcd_1.clear();
    lcd_1.print("9");
    delay(1000); // Wait for 1000 millisecond(s)
    lcd_1.setCursor(0, 0);
    lcd_1.print("8");
    delay(1000); // Wait for 1000 millisecond(s)
    lcd_1.setCursor(0, 0);
    lcd_1.print("7");
    delay(1000); // Wait for 1000 millisecond(s)
    lcd_1.setCursor(0, 0);
    lcd_1.print("6");
    delay(1000); // Wait for 1000 millisecond(s)
    /*
    lcd_1.setCursor(0, 0);
    lcd_1.print("5");
    delay(1000); // Wait for 1000 millisecond(s)
    lcd_1.setCursor(0, 0);
    lcd_1.print("4");
    delay(1000); // Wait for 1000 millisecond(s)
    lcd_1.setCursor(0, 0);
    lcd_1.print("3");
    delay(1000); // Wait for 1000 millisecond(s)
    lcd_1.setCursor(0, 0);
    lcd_1.print("2");
    delay(1000); // Wait for 1000 millisecond(s)
    lcd_1.setCursor(0, 0);
    lcd_1.print("1");
    delay(1000); // Wait for 1000 millisecond(s)
    lcd_1.setCursor(0, 0);
    lcd_1.print("Starting...");
    digitalWrite(2, HIGH);
    delay(2750); // Wait for 2750 millisecond(s)
   /*/// lcd_1.clear();
  } else if (setPressed == HIGH) {
   setScreen();
  }
}

void startScreen() {

    //int heater = digital(heaterSwitch);
    //int motor = digitalRead(motorSwitch);
    lcd_1.clear();
    lcd_1.setCursor(0, 0);
    lcd_1.print("5");
    delay(1000); // Wait for 1000 millisecond(s)
    lcd_1.setCursor(0, 0);
    lcd_1.print("4");
    delay(1000); // Wait for 1000 millisecond(s)
    lcd_1.setCursor(0, 0);
    lcd_1.print("3");
    delay(1000); // Wait for 1000 millisecond(s)
    lcd_1.setCursor(0, 0);
    lcd_1.print("2");
    delay(1000); // Wait for 1000 millisecond(s)
    lcd_1.setCursor(0, 0);
    lcd_1.print("1");
    delay(1000); // Wait for 1000 millisecond(s)
    lcd_1.setCursor(0, 0);
    lcd_1.print("Heating");
    lcd_1.setCursor(0, 1);
    lcd_1.print("Please Wait...");
    digitalWrite(heaterSwitch, LOW);
    delay(1500); // Wait for 2750 millisecond(s)
    heatScreen1();
}


void setScreen() {
  lcd_1.clear();
  lcd_1.setCursor(0,0);
  lcd_1.print("The Setting option will come soon            ");
  delay(500);
  lcd_1.scrollDisplayLeft();
  delay(120);
  lcd_1.scrollDisplayLeft();
  delay(120);
  lcd_1.scrollDisplayLeft();
  delay(120);
  lcd_1.scrollDisplayLeft();
  delay(120);
    lcd_1.scrollDisplayLeft();
  delay(120);
    lcd_1.scrollDisplayLeft();
  delay(120);
    lcd_1.scrollDisplayLeft();
  delay(120);
    lcd_1.scrollDisplayLeft();
  delay(120);
    lcd_1.scrollDisplayLeft();
  delay(120);
    lcd_1.scrollDisplayLeft();
  delay(120);
    lcd_1.scrollDisplayLeft();
  delay(120);
      lcd_1.scrollDisplayLeft();
  delay(120);
    lcd_1.scrollDisplayLeft();
  delay(120);
    lcd_1.scrollDisplayLeft();
  delay(120);
    lcd_1.scrollDisplayLeft();
  delay(120);
    lcd_1.scrollDisplayLeft();
  delay(120);
    lcd_1.scrollDisplayLeft();
  delay(120);
      lcd_1.scrollDisplayLeft();
  delay(120);
    lcd_1.scrollDisplayLeft();
  delay(120);
    lcd_1.scrollDisplayLeft();
  delay(120);
    lcd_1.scrollDisplayLeft();
  delay(120);
    lcd_1.scrollDisplayLeft();
  delay(120);
    lcd_1.scrollDisplayLeft();
  delay(120);
    lcd_1.scrollDisplayLeft();

  
  // lcd_1.setCursor(0,1);
  //lcd_1.print("come in future updates");
  //delay(4000);
  lcd_1.clear();
  loop();
}

void heatScreen1() {
    sensorInput = analogRead(A0);
    temp = sensorInput / 1024;
    temp = temp * 5;
    temp = temp - 0.5;
    temp = temp * 100;
    lcd_1.setCursor(0, 0);
    lcd_1.print("Heating");
    lcd_1.setCursor(0, 1);
    lcd_1.print("Please Wait...");
    digitalWrite(heaterSwitch, LOW);
    delay(1500); // Wait for 2750 millisecond(s)
  //  digitalWrite(heaterSwitch, HIGH);
   // heatScreen();
  if (temp >= 120){
    heatScreen();
  }else {
    heatScreen1();
  }
  
}


void heatScreen() {
  int startPressed = digitalRead(buttonstart);
  int setPressed = digitalRead(buttonsettings);
  int minPressed = digitalRead(buttonminus);
    sensorInput = analogRead(A0);
    temp = sensorInput / 1024;
    temp = temp * 5;
    temp = temp - 0.5;
    temp = temp * 100;
  digitalWrite(heaterSwitch, HIGH);
  lcd_1.clear();
  lcd_1.setCursor(0,0);
  lcd_1.print("Starting motor in");
    lcd_1.setCursor(8, 1);
    lcd_1.print("5");
    delay(1000); // Wait for 1000 millisecond(s)
    lcd_1.setCursor(8, 1);
    lcd_1.print("4");
    delay(1000); // Wait for 1000 millisecond(s)
    lcd_1.setCursor(8, 1);
    lcd_1.print("3");
    delay(1000); // Wait for 1000 millisecond(s)
    lcd_1.setCursor(8, 1);
    lcd_1.print("2");
    delay(1000); // Wait for 1000 millisecond(s)
    lcd_1.setCursor(8, 1);
    lcd_1.print("1");
    delay(1000); // Wait for 1000 millisecond(s)
    digitalWrite(motorSwitch, LOW);
    lcd_1.clear();
    heatScreen2();
  delay(200000);
  
  
}


void heatScreen2() {
    sensorInput = analogRead(A0);
    temp = sensorInput / 1024;
    temp = temp * 5;
    temp = temp - 0.5;
    temp = temp * 100;
    temp = temp + 0.15;
    lcd_1.setCursor(0,0);
    lcd_1.print("Temperature is");
    lcd_1.setCursor(0,1);
    lcd_1.print(temp);
    lcd_1.setCursor(5,1);
    lcd_1.print(" Degrees");
    heatScreen2();
  
}

All of the disabled lines were either earlier attempts of the button modes or disabled delays to make the simulation faster.

My advice would be it isnt going to work if you keep using delay().
Study this example

to see how to use millis()
then

1 Like

Hello vickerstaff

To get started read and study the IPO model. Take piece of paper and a pencil and design a software structure first. In the next step you can start with coding and testing the software modules.

Have a nice day and enjoy coding in C++.

All of that is possible with just single Arduino nano. Don't forget you need a keypad to enter the parameter values. I did all that several years ago for a drying oven to dry ICs shipped from overseas. Never needed to use it.

The thing you need to factor in is the initial heating time, not just the regulation. My oven took 15 minutes for initial heat because the heating element was inside a large piece of cast iron that smoothed out the heat variations.

Also look into using a SSR to control the heat element.

That expresses recursion, which has its place but not normally seen in the very small computer world.

You are possibly calling heatScreen2() from within heatScreen2(). Very quickly that will blow up and fail.

Same thing in heatScreen2() .

I have no idea what your intent is, I am looking through a tiny window. What did you mean for this to accomplish?

a7

I have no idea what your intent is, I am looking through a tiny window.

I was thinking that it could repeat over and over until the "if" variable was met, which would bring it to another separate function.

can you call loop() within a function?

1 Like

Good catch.

Looks like recursion to me.

Yet you name the very function you are in.

And this

Is also not a good idea.

When a function returns, it goes back where it was called from.

When loop() returns, it gets called again from, well never we mind, just trust that it gets called over and over and over and over.

You never need to call loop(), doing so is almost certainly an error.

You might a function from a function and so forth, but not in anything that goes in circles, ends up effectively balling itself.

Not usually. I'd say never and be lying, the good kind of lie.

a7

UPDATE: Got the settings menu working! (kinda)
I've got new code, this time including EEPROM. Here it is:


//This is written in C++
//
#include <EEPROM.h>
#include <Adafruit_LiquidCrystal.h>

 //#define buttonhome 11 
 #define buttonstart 10
 #define buttonsettings 9
 #define buttonminus 8
 #define thermistorPin A0
 #define heaterSwitch 3
 #define motorSwitch 2
 #define pinTemp A0

Adafruit_LiquidCrystal lcd_1(0);

  unsigned long previousMillis = 0;
  const long interval = 1000;

  int startPressed = digitalRead(buttonstart);
  int setPressed = digitalRead(buttonsettings);
  int minPressed = digitalRead(buttonminus);
  float sensorInput;
  float temp;
  int alarm = 60000;
  int failSafe = 0;
  int DHT = 120; //DHT Stands for Default Heater Temperature.
  //This was set so low becaus the temperature sensor on Tcad only goes to 125 C

void setup()
{
  pinMode(buttonminus, INPUT);
  pinMode(buttonsettings, INPUT);
  pinMode(buttonstart, INPUT);
  pinMode(heaterSwitch, OUTPUT);
  digitalWrite(heaterSwitch, HIGH);
  pinMode(motorSwitch, OUTPUT);
  digitalWrite(motorSwitch, HIGH);
  lcd_1.begin(16, 2);
  Serial.begin(9600);
  
  unsigned long previousMillis = 0;
  const long interval = 1000;
  int heaterThresh = 240;

  
  lcd_1.setCursor(0, 0);
  lcd_1.print("Arduino Extruder");
  lcd_1.setCursor(0, 1);
  lcd_1.print("          V1.0.4");
  delay(2500); // Wait for 2500 millisecond(s)
  lcd_1.scrollDisplayLeft();
  delay(90); // Wait for 90 millisecond(s)
  lcd_1.scrollDisplayLeft();
  delay(90); // Wait for 90 millisecond(s)
  lcd_1.scrollDisplayLeft();
  delay(90); // Wait for 90 millisecond(s)
  lcd_1.scrollDisplayLeft();
  delay(90); // Wait for 90 millisecond(s)
  lcd_1.scrollDisplayLeft();
  delay(90); // Wait for 90 millisecond(s)
  lcd_1.scrollDisplayLeft();
  delay(90); // Wait for 90 millisecond(s)
  lcd_1.scrollDisplayLeft();
  delay(90); // Wait for 90 millisecond(s)
  lcd_1.scrollDisplayLeft();
  delay(90); // Wait for 90 millisecond(s)
  lcd_1.scrollDisplayLeft();
  delay(90); // Wait for 90 millisecond(s)
  lcd_1.scrollDisplayLeft();
  delay(90); // Wait for 90 millisecond(s)
  lcd_1.scrollDisplayLeft();
  delay(90); // Wait for 90 millisecond(s)
  lcd_1.scrollDisplayLeft();
  delay(90); // Wait for 90 millisecond(s)
  lcd_1.scrollDisplayLeft();
  delay(90); // Wait for 90 millisecond(s)
  lcd_1.scrollDisplayLeft();
  delay(90); // Wait for 90 millisecond(s)
  lcd_1.scrollDisplayLeft();
  delay(90); // Wait for 90 millisecond(s)
  lcd_1.scrollDisplayLeft();
  delay(90); // Wait for 90 millisecond(s)
  lcd_1.clear();
 // delay(750); // Wait for 750 millisecond(s)
}

void loop()
{
    
    lcd_1.setCursor(3, 0);
    lcd_1.print("Select Mode");
    lcd_1.setCursor(0, 1);
    lcd_1.print("Start");
    lcd_1.setCursor(8, 1);
    lcd_1.print("Settings");
    
  int startPressed = digitalRead(buttonstart);
  int setPressed = digitalRead(buttonsettings);
  int minPressed = digitalRead(buttonminus);
  	if(startPressed == HIGH){
		Serial.println("Start");
    } else if (setPressed == HIGH){
      Serial.println("Settings");
    } else if (minPressed == HIGH){
      Serial.println("-");
    }
  Serial.println(pinTemp);
  

  delay(500);
  if (startPressed == HIGH) {
    
    startScreen();

  } else if (setPressed == HIGH) {
   lcd_1.clear();
   setScreen();
  } else if (minPressed == HIGH) {
    invalidScreen();
  }

}

void startScreen() {

    //int heater = digital(heaterSwitch);
    //int motor = digitalRead(motorSwitch);
    lcd_1.clear();
    lcd_1.setCursor(0, 0);
    lcd_1.print("5");
    delay(1000); // Wait for 1000 millisecond(s)
    lcd_1.setCursor(0, 0);
    lcd_1.print("4");
    delay(1000); // Wait for 1000 millisecond(s)
    lcd_1.setCursor(0, 0);
    lcd_1.print("3");
    delay(1000); // Wait for 1000 millisecond(s)
    lcd_1.setCursor(0, 0);
    lcd_1.print("2");
    delay(1000); // Wait for 1000 millisecond(s)
    lcd_1.setCursor(0, 0);
    lcd_1.print("1");
    delay(1000); // Wait for 1000 millisecond(s)
    lcd_1.setCursor(0, 0);
    lcd_1.print("Heating");
    lcd_1.setCursor(0, 1);
    lcd_1.print("Please Wait...");
    digitalWrite(heaterSwitch, LOW);
    delay(1500); // Wait for 2750 millisecond(s)
    heatScreen1();
}


void setScreen() {
  int startPressed = digitalRead(buttonstart);
  int setPressed = digitalRead(buttonsettings);
  int minPressed = digitalRead(buttonminus);
  
  //int DHT = 250;
  lcd_1.setCursor(0,0);
  lcd_1.print("Heater Temperature");
  if (minPressed == HIGH) {
     DHT = DHT - 1;  // decrement DHT
  } else if (setPressed == HIGH) {
    DHT = DHT + 1;  // increment DHT
  }
  lcd_1.setCursor(3,1);
  lcd_1.print(DHT);
  
  if (startPressed == HIGH) {
   EEPROM.write(0, DHT);
    lcd_1.clear();
    alarmSettings();
  } else {
    setScreen();
  }
}

void alarmSettings() {
  int startPressed = digitalRead(buttonstart);
  int setPressed = digitalRead(buttonsettings);
  int minPressed = digitalRead(buttonminus);
   lcd_1.setCursor(0,0);
   lcd_1.print("Alarm (minutes)");
  delay(500); //Delay to prevent incrementing while the settings button is pressed
   if (minPressed == HIGH) {
     alarm = alarm - 1;  // deincrement alarm
  } else if (setPressed == HIGH) {
     alarm = alarm + 1;  // increment alarm
  }
   lcd_1.setCursor(5,1);
   lcd_1.print(((alarm - 1000) / 60));
   
  if (startPressed == HIGH) {
    EEPROM.write(1, alarm);
    lcd_1.clear();
    loop();
  } else {
    alarmSettings();
  }
  
}

void invalidScreen() {
  lcd_1.setCursor(0,0);
  lcd_1.print("    Invalid     ");
  delay(1500);
  
  
}


void heatScreen() {
    sensorInput = analogRead(A0);
    temp = sensorInput / 1024;
    temp = temp * 5;
    temp = temp - 0.5;
    temp = temp * 100;
    lcd_1.setCursor(0, 0);
    lcd_1.print("Heating...");
    lcd_1.setCursor(6, 1);
    lcd_1.print("temp");
    digitalWrite(heaterSwitch, LOW);
    delay(1500); // Wait for 2750 millisecond(s)
  //  digitalWrite(heaterSwitch, HIGH);
   // heatScreen();
  if (temp >= 120){
    heatScreen1();
  } else {
    heatScreen();
  }
  
}


void heatScreen1() {
    lcd_1.clear();
    lcd_1.print("Starting motor in");
    lcd_1.setCursor(8, 1);
    lcd_1.print("5");
    delay(1000); // Wait for 1000 millisecond(s)
    lcd_1.setCursor(8, 1);
    lcd_1.print("4");
    delay(1000); // Wait for 1000 millisecond(s)
    lcd_1.setCursor(8, 1);
    lcd_1.print("3");
    delay(1000); // Wait for 1000 millisecond(s)
    lcd_1.setCursor(8, 1);
    lcd_1.print("2");
    delay(1000); // Wait for 1000 millisecond(s)
    lcd_1.setCursor(8, 1);
    lcd_1.print("1");
    delay(1000); // Wait for 1000 millisecond(s)
    digitalWrite(motorSwitch, LOW);
    heatScreen2();
}


void heatScreen2() {
    sensorInput = analogRead(A0);
    temp = sensorInput / 1024;
    temp = temp * 5;
    temp = temp - 0.5;
    temp = temp * 100;
    temp = temp + 0.15;
    lcd_1.setCursor(0,0);
    lcd_1.print("Temperature is");
    lcd_1.setCursor(0,1);
    lcd_1.print(temp);
    lcd_1.setCursor(5,1);
    lcd_1.print(" Degrees");
    delay(1000);
    failSafe = failSafe + 1;
    if (failSafe >= alarm) {
      alarmScreen();
    }else {}
    heatScreen2();
    
  
}
  
void alarmScreen()  {
  digitalWrite(heaterSwitch, HIGH);
  digitalWrite(motorSwitch, HIGH);
  lcd_1.clear();
  lcd_1.setCursor(2,0);
  lcd_1.print("Timer done!");
  
  delay(5000);
}
    

Also I added the timer!

can you call loop() within a function?

On Tinkercad you can (apparently).

You got a stray backslash in there, edit your code right in that post!

Then it compiles.

a7

1 Like

pinMode(motorSwitch, OUTPUT);

I did not notice that XD.
lol

OK, I have taken a rapid flight over your sketch and your latest codes still has the errors that have been pointed out in this thread.

Please reread it carefully.

At least:

You should never call loop() yourself.

You should not call heater2() from within heater2().

Or anything else that makes a circuit A - > B -> C -> A, uh-uh.

It will only end up badly or worse.

Please say what a user sees and you mean to present as things that would make the user press buttons for why, or how we can play with it. I didn't get anywhere just stabbing buttons.

TIA

a7

I give up. Now the simulator is so slow it's basically unusable.

Post the code that is too slow on the simulator.

You could also try a real simulator like

which, on a reasonable machine will do real time.

a7

1 Like

Wow. Just wow. This simulator has SO MANY MORE devices than Tinkercad!