The Donald Duck hypnotizing machine with IoT

Note – the full code is available on my GitHub page, so I will only illustrate portions of it here.

There is a classic story by Carl Barks, in which Donald Duck comes into possession of a hypnotizing gun. As I seem to remember it, the nephews collected cereal labels or something to get that gizmo, and while they played around with it, Donald got hypnotized with it. Inevitably he would confiscate the thing and use it for his not-so-clever purposes.

The phrase “PIM – you’re hypnotized” is a classic in Finland, everyone knows it. See the disc with the helix – it will be recreated in Blender and 3D printed. Image (c) Sanomaprint

Why I happened to remember this is that I taught myself remote control of an ESP32 and a motor, and had to figure out some method of using it. This system has a user interface on my web server, written in PHP, and the device goes over there twice a second to see what direction to spin the disc, and at what speed. I really cannot think of a simpler example for this, so let’s get started.

The evil contraption booting up

The L298H bridge

The L298H bridge is a self-contained device for running two motors, solenoids, or other such devices. You can also use a single Integrated Circuit, called L293D, if you wish, but this bridge is handy in the sense that it has connectors for all you want to hook up to it, unlike the L293D, which has to be soldered or embedded in a breadboard. You can see the L293D in action in this other 4 part blog post that drives a motor and a servo with an Android app and UDP protocol. It also has a very nice way of handling up to 12V of voltage, which is very useful for motor management – Arduinos and other such things can only deliver 5V and it’s not a good idea at all to drive motors directly.

The complete set looks like this:

Image courtesy of 4tronix, Inc.

The relevant parts are the VCC, GND and 5V connectors there. To the VCC connector, plug in 9V from battery or 12V from a power adapter. The 5V is output that goes into your ESP32 VIN pin. Make sure to share the ground connector among all devices you plug in here. The other two screw connectors are for Motor 1 and Motor 2. Plug in the wires here, it doesn’t matter which way initially, as you can always reverse the wires if the motors turn the wrong way from your point of view.

The eight pins above the power management connectors are where the magic happens. You will be leading in three wires per motor from ESP32. One is ENA, short for Enable motor A, then IN1, IN2, IN3, and IN4, and ENB at the other end. There are also two 5V pins if you find them handier than the screw connector. Enable is needed to govern the power management and speed of the motor. IN1 and IN2 refer to the rotation direction of the motor, if one is HIGH and the other LOW, it turns one way, and reversed, the other. With both LOW you can be sure the motor won’t run at all.

There are two LEDs in this system too. Their purpose is to indicate the state of the evil machine. When it is booting up, and the ESP32 is connecting to the Internet, the blue LED is on. When connection is made, the blue one is turned off and the green LED turned on.

Connection scheme

Connections for one motor. If two, hook up with a similar method. The Arduino Micro is merely a placeholder, as the Fritzing scheme tool does not have an ESP32 in it

This image may help you understand how it’s connected, but this picture and seeing the code will show you the details.

ESP32, L298H, motor, and LEDS in a repurposed box – hence the mess.

The battery is just out of the picture here. Its plus wire is led via the switch to the VCC connector of the L298H. Its ground is led to the GND connector. The ESP32 VIN pin is connected to the +5V pin of the bridge, and its ground is in the bridge ground. The LED grounds go to the other ground in the ESP32, and their positive pins into ESP32 pins 4 and 15, as shown in the code snippet below. The motor1pin1 and 2 go into the respective pins on the bridge.

// Motor A
int motor1Pin1 = 27;
int motor1Pin2 = 26;
int enable1Pin = 14;
int SpeedVariable = 0;
int mySwitch = 0;
int myBootLed = 4; //this led shows the machine is booting and connecting to Internet
int myNetLed = 15; //this led shows the machine is connected to Internet

int driveValue = 0; //speed

// Setting PWM properties
const int freq = 30000;
const int pwmChannel = 0;
const int resolution = 8;
int dutyCycle = 200;

The PWM (pulse width modulation) settings are related to the speed control. The driveValue is the speed at which the motor is to be turned. The actual speed control is done via changing the length of a pulse that is sent to the bridge via the ENA pin. The ESP32 has 16 PWM channels, so you can in theory run 16 LEDs or other devices that listen to such commands.

void setup() {
pinMode(motor1Pin1, OUTPUT);
pinMode(motor1Pin2, OUTPUT);
pinMode(enable1Pin, OUTPUT);
pinMode(myNetLed, OUTPUT);
pinMode(myBootLed, OUTPUT);
digitalWrite(myBootLed,HIGH);
// configure LED PWM functionalitites
ledcSetup(pwmChannel, freq, resolution);

// attach the channel to the GPIO to be controlled
ledcAttachPin(enable1Pin, pwmChannel);

Here the pins are set as output, and the enable1pin is set up to the power management. The actual turning of the motor is governed by a function called driveTrain (for historical purposes, this used to be a system for driving a LEGO train two ways):

void driveTrain(int mySpeed){
USE_SERIAL.println(mySpeed);
if (mySpeed < 0){ 
digitalWrite(motor1Pin1, HIGH); 
digitalWrite(motor1Pin2, LOW); 
driveValue = map(abs(mySpeed),10, 100, 210, 240);
ledcWrite(pwmChannel, abs(driveValue)); 
} 
else if (mySpeed > 0) {
digitalWrite(motor1Pin1, LOW);
digitalWrite(motor1Pin2, HIGH);
driveValue = map(abs(mySpeed),10, 100, 210, 240);
ledcWrite(pwmChannel, abs(driveValue));
}
else {
digitalWrite(motor1Pin1, LOW);
digitalWrite(motor1Pin2, LOW);
}
return;
}

Note the use of the sign of the speed value: if less than 0, let’s turn motor1pin1 high and the other low. If larger than 0, the other way round, and if exactly 0, set both low to ensure the motor doesn’t run. The actual speed is derived using the map() function. Given the value to map, its low and high values, and the new mapped low and high values, this function gives you the value needed to use in the ledcWrite() function, thus ready to be sent to the bridge.

The Web interface

The Web interface lives on my server. To use such an interface, your server must be able to run PHP, and since that is a feature on my hosting provider, it’s easy. You can find free PHP hosting platforms everywhere, but they have ads or other methods of making money.

This is how the user interface looks:

Three states of the user interface

The Github page has the source code for this simple interface. It saves the desired speed in a text file, which is then read by the ESp32 twice a second, or at whatever frequency you want.

Installation instructions

To get yourself this setup, do the following:

  • Go to my Github page
  • Use the Clone or Download button and download a ZIP file
  • Unzip it into a directory of your choice
  • Copy the files from the PHP folder onto your webserver, for example into a folder called speed
  • Edit the INO file so that it has your own WLAN data
  • Flash your ESP32 with the edited INO file.

Now when you go to http://<yourserver.com>/speed, you see the interface. Turn on your ESP32. After a while, the boot led goes off and the Internet led turns on. Now you can use the user interface to turn the motor in either direction, as illustrated in this video.

Be careful not to get hypnotized.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

This site uses Akismet to reduce spam. Learn how your comment data is processed.