Tuesday, 25 February 2025

Any movement yet?

Arduino choices

Since last time, I've been buying stuff. This is inevitable I'm afraid but on the upside I think I'm getting some direction finally.

There are some pretty powerful yet tiny microcontrollers around these days - almost too much of a choice at that. However, I'm much more comfortable with the Arduino IDE (aka C++) than Raspbery Pi (Python). I know, I know - you can actually run Arduino on RP and Python on Arduino but it's simpler to stick to one environment.

As for the actual micro itself, the original Arduinos were based on the ATmel ATMEGA family of processors but since then, a range of other micros have been used in the Arduino family, such as the 32 bit RA4M1 series from Renesas (used on the current Uno R4 etc) and the ESP32 family from Espressif. In the meantime, the form factor has shrunk massively (so to speak). So now you can get devices such as the Arduino Nano 32 bit ESP32 C3 Supermini that are little bigger than your thumbnail, yet are much more powerful than the original (and massive) 8 bit Arduino, while also implementing Bluetooth BLE and Wifi.

Here's an original form factor Uno R4 on the right (with a "terminal block shield" breakout board on top), next to an Arduino ESP32 in the "Nano" form factor, alongside an Arduino C3 in the "Supermini" ("half Nano"?) form factor.

The Supermini form factor is pretty small...

...small enough to hide behind your thumb

That thing is just 18mm x 22.5mm

Here it is alongside a small 10k pot. Even though the pot is tiny, it's not much smaller then the Arduino itself - and I am planning to use 3 of them.

Here's a Nano / Supermini alongside an Allegro A4988 stepepr motor driver board (the A4988 itself is hiding under the finned heatsink), then 3 pots and a small TFT display.

I can just about imagine the 2 PCBAs and 3 pots being integrated on a long, narrow motherboard with the display sitting on top. That would require a board of ~80mm long (plus some extra for connectors), with a width of ~20mm. With the display sitting on top of the pots, I'd have a height of around 12-13mm. The whole thing would then be housed in a 3D printed enclosure, ideally mounted on the torch head.

Alternatively, I could go for a "more square" footprint, with the pots alongside the PCBAs. That would look something like  ~50mm long and ~30mm wide. Given that this assembly would ideally be mountable (and demountable) on to the torch head, a long, thin form factor might not be ideal.

How about some software?

It's all very well getting all excited about Arduino hardware but at some point, I'm going to have to write some software to make this thing come to life. Last time I decided what functionality it would need:

  • Variable speed of forward motion
  • Variable spot welding frequency
  • Variable duty cycle (regardless of the frequency)*
* I may decide later that frequency and the on time should be set independently. There is no right or wrong and it's not a critical design decision, so this is how I will set out. I can always change that part of the code later.

So I will have 3 analogue inputs (aka potentiometers) and 2 distinct timer circuits. For the timers, it's not a good idea to use the "delay" function as it causes the whole program to pause. Instead, the method is to use the "millis" (milliseconds) or "micros" (microseconds) timers that count up from the time the micro wakes up.

For the motor drive, I need a variable frequency output to drive the STEP input of the A4988 driver. I don't expect to need to drive the motor backwards at any point, so (for now at least) I won't be driving the DIR(ection) input of the A4988. Rather than make my own hookey variable frequency source, there is a convenient library "AccelStepper" that does all the work, so I've used that. Sounds as if the originator is an experienced software engineer - but one that can't be arsed to write a manual for his work. Pity that - but luckily Mr Hackaday has stepped in to do the dirty work with his handy "AccelStepper - The Missing Manual". This was pretty helpful in getting things running.

This works as described. Here's what I've got today. It generates a variable spot welding frequency, variable duty cycle and variable forward speed. Some of the variable names are rather haphazard and need to be rationalised, so there is certainly work still to be done:

#include <Arduino.h>
#include <AccelStepper.h>

// constants to set pin numbers = 13 - use built in LED for test / dev
const int pwmPin =  13; // the number of the green LED pin
const int dutyCycleAnalogIn = A0;  // Analog input- PWM duty
const int periodAnalogIn = A1;  // Analog input - period (ms)
const int speedAnalogIn = A2;  // Analog input - speed (Hz)
const int maxPeriod = 5000;   // hard coded max on time
const int dirPin = 4;  // pin 4 used for DIR output
const int stepPin = 5;  // pin 5 used for STEP output

// Variables will change
int pwmState = HIGH; //ledState for PWM output
int pwmSensorValue = 0;  // value read from the pot
int periodSensorValue = 0;
int speedValue = 0;
long plot = 0;
// Define the stepper motor and the pins that is connected to:
AccelStepper stepper1(AccelStepper::DRIVER, stepPin, dirPin); // (Type of driver: with 2 pins, STEP, DIR)
// stepper1.AccelStepper::DRIVER, stepPin, dirPin);

long previousMillisPwm = 0;  //last time PWM output was updated
long previousMillisPeriod = 0;

// pwmPeriod is time between spots
long pwmPeriod = 2000; //interval between spots (milliseconds)

// must be long to prevent overflow
long pwmDuration = 2000; //interval for PWM output (milliseconds)
unsigned long currentMillis = 0; // initialise

void setup() {
  // Set maximum speed value for the stepper:
  stepper1.setMaxSpeed(1000);
  // set the pins to output mode
  Serial.begin(9600);
  pinMode(pwmPin, OUTPUT);
  digitalWrite(pwmPin, pwmState);
  currentMillis = millis();
}

void loop() {
  analogRead(0); // could be any channel

  periodSensorValue = analogRead(periodAnalogIn); // 0 - 1023 count
  // pwmPeriod = map(periodSensorValue, 0, 1023, 0, 3000); // map input to pwmPeriod - time between spots
  pwmPeriod = (maxPeriod * periodSensorValue / 1023); // map input to pwmPeriod - time between spots

  pwmSensorValue = analogRead(dutyCycleAnalogIn); // 0 - 1023 count
  pwmDuration = map(pwmSensorValue, 0, 1023, 0, pwmPeriod); // map input to pwmDuration - on time

  speedValue = analogRead(speedAnalogIn);
  // Define setSpeed() according to input A2
  stepper1.setSpeed(speedValue);
  // Step the motor with a constant speed previously set by setSpeed();
  stepper1.runSpeed();

  currentMillis = millis(); // capture the current time
  managePwm();
  managePeriod();
  serial_Plotter();  
  reportStatus();
}

void reportStatus() {
  Serial.print("Duty time is");
  Serial.print("\t");
  Serial.print(pwmDuration);
//  Serial.print(plot);
  Serial.print("\t");
  Serial.print("Period time is");
  Serial.print("\t");
  Serial.print(pwmPeriod);
  Serial.print("\t");
  Serial.print("Output");
  Serial.print("\t");
  Serial.print(plot);
  Serial.print("\t");
//  Serial.print(periodAnalogIn);
//  Serial.print("\t");
  Serial.print("Speed");
  Serial.print("\t");
  Serial.println(speedValue);
}

void serial_Plotter() {
  if(pwmState == HIGH) {
    plot=2000;
  } else {
    plot=0;
  }
}
void managePwm() {
  //check if it's time to change the PWM output yet
  if(currentMillis - previousMillisPwm > pwmDuration) {
    //store the time of this change
    pwmState = LOW;
    digitalWrite(pwmPin, pwmState);
  }
}

void managePeriod() {
  //check if it's time to reset the output yet
  if(currentMillis - previousMillisPeriod > pwmPeriod) {
    previousMillisPeriod = currentMillis;
    previousMillisPwm = currentMillis;
    pwmState = HIGH;
    digitalWrite(pwmPin, pwmState);
  }
}

Programming the ESP32-C3 Dev Bd:

To program this board, it's necessary to install the "ESP32" library, not just the "Arduino ESP Boards" library:


Also, the "AccelStepper" library:





Next, I want to implement a simple display to show the active settings....

No comments:

Post a Comment

Tiny OLED display for tiny Arduino ESP32C3

To get this little generic 128 x 32 pixel OLED display working with the ESP32C3 Dev board, need to load the correct library and also connec...