Schrittmotoren mit ESP32/ESP8266 in MicroPython - Teil 3 - AZ-Delivery
This post is also available as PDF document for download.

In the previous consequences we had the Structure and the basic function looked at by stepper motors and us with Driver ICS busy who lose a lot of programming work. Today, together with a time-of-flight sensor (TOF), we knit an application from it that scans the profile of a room, as the radar systems do at airplaces. According to the data sheet, the VL53L0X should have a range of up to two meters. Unfortunately, my copy only works within a radius up to approx. 1.6 meters. Nevertheless, the result is fascinating. In this new episode you will find out what a tof is and how to use it

Micropython on the ESP32 and ESP8266

today

The light radar

A TOF sensor measures the term of light impulses and calculates the distance to the object that reflects the light pulse. The wavelength of the emitted light is in the infrared area (IR) and cannot be perceived from the human eye. But with the camera of a cell phone, the emitted light can be tracked down.

Figure 1: The IR light cone of the VL53L0X

Figure 1: The IR light cone of the VL53L0X

In this way, the function of a normal IR remote control of TV sets, stereo systems etc. can also be checked.

I have used the VL53L0X a few times for the distance measurement, for example at the Theremin and when measuring the Take height of people. The sensor was mounted there. Today we attach it to the rotor axle of the stepper motor so that it can score an (almost) any angle area. After an angle step is carried out, we measure the distance to the nearest object. The ESP32 calculates this value so that it can be represented as a "beam" on an OLED display. A gabel sealing barrier, or an alternative a reed contact, serve as a final position sensor. The ESP32 can always put the rotor into a defined starting position after booting the system. That is today's program. We start with the hardware list immediately.

1 ESP32 Dev Kit C unpleasant or ESP32 NODEMCU Module WiFi Development Board or Nodemcu-ESP-32S kit
1 A4988 Step motor driver module with heat sink
or DRV8825 Step motor driver module with heat sink
1 Step motor Bipolar e.g. Pollin Order no. 310689 or 310690
1 0.96 inch OLED SSD1306 Display I2C 128 x 64 pixels
1 VL53L0X Time-of-Flight (TOF) Laser distance sensor
1 Ky-010 light barrier or Ky-021 Magnet switch mini magnet reed module sensor
1 LM2596S DC-DC power supply adapter step down module
20 mm 12mm Ø aluminum round to extend the rotor axis
17 mm 6mm Ø aluminum rod
65 mm 12mm Ø aluminum rod as a sensor carrier lever
30 mm 6mm Ø aluminum rod
1 4mm plywood plate 55mm x 140mm
1 Pertinax plate 20mm x 40mm x 1.5mm
1 Breadboard Kit - 3x Jumper Wire M2M/F2M/F2F + 3 Set MB102 Breadbord Compatible with Arduino and Raspberry Pi - 1x Set
1 Ultra -lexified tinned silicone cable switching loads kit
various Jumper cable
1 Pinning power supply 12V DC / 2A
optional Logic Analyzer

The Logic Analyzer is very useful when it comes to monitoring the logic lines, especially to solve problems in connection with the I2C bus.

Unfortunately, the ESP8266 modules are not suitable for this project. I found that a storage error was already reported when the micropython module was integrated for the VL53L0X. There was also a surprise for the ESP32, more on that.

The specified engines work at around 10.5V. So we have to use a 12V power supply and the current strength on the driver module A4988 or DRV8825 with the trimmer, as in the last episode described, set. Alternatively, two 1N4001 diodes could also be placed in +12V supply line in the passage direction. By deducting the forward voltage of twice 0.7V, approx. 10.5V remain for the engine.

If the ESP32 is also to be operated from this supply, we can use the Buck Converter module to regulate the 12V to 5V, before the output of the module is connected to the ESP32. The converter is not required if the ESP32 is supplied from the PC via the USB line.

Preparing the engine unit

Figure 3 shows the structure of the engine unit, which we first discuss.

The base plate is prepared so that it fits the engine. The dimensions in Figure 2 apply to the motors mentioned. We drill the fastening holes with 4mm to compensate for tolerances in the positioning. The plate is now screwed onto the engine block of the MineBEA T15317-01 with four screws M3 x 10.

With the MineBEA T15429-02, the pinion must be cut with a mini separator and blown out with a flat screwdriver.

Figure 2: Drilling for engine absorption

Figure 2: Drilling for engine absorption

Figure 3: VL53L0X installed on the engine shaft

Figure 3: VL53L0X installed on the engine shaft

The 20mm round rod (12mm Ø) is provided with a central 4mm bore. Then from the upper end to a length of 7mm with a 6mm drill, the 20mm round rod (6mm Ø) can later be glued in (2 component adhesive). From below we drill to a 6mm length to 5mm diameter. About the middle of the remaining 4mm bore I attached a hole with 2.5mm perpendicular to the axis and provided with a thread M3. Now I can put the extension on the engine axis and tighten. Now you can glue the 20mm round rod and have the glue hardened.

I drill the round rod for the levers 15mm from the end with 6mm in the middle. I send the left end with a 3.3mm hole in which a thread M4 inserts. The right end is drilled to a length from 40mm to 6mm and provided with a cross hole of 2.5mm. I move into a thread M3 into this.

I drill the 30mm round rod axially for a thread M4 with 3.3mm. The lever is glued to the extended axis (2 component glue as above). At the short end (left) I attach the pertinax plate with the VL53L0X and on the 30mm round rod I screw a small piece of sheet that has to fit between the cheeks of the fork bat.

Figure 4: Light barrier to start the starting position

Figure 4: Light barrier to start the starting position

In order for the lever to turn in all directions without disabilities, the connection pins must be removed from the board of the fork seal. Alternatively, cable pieces (30cm) are soldered directly, at the end of which the pen strip can be attached again. To adjust the piece of sheet metal on the lever, we assemble the module with a spacer (a strip of pertinax) on the base plate.

We also need a connection for the VL53L0x module, which we make from six cables of approx. 30 cm in length and complete with a socket and a pen strip.

The software

For flashing and the programming of the ESP32:

Thonny or

µpycraft

pack box To test the ESP8266 as a UDP client and server

SaleaeLogic analyzer software (64 bit) For Windows 8, 10, 11

Used firmware for an ESP32:

ESP32_Generic-20220117-V1.18.bin

Please only use this firmware because only the VL53L0X works correctly - for whatever reason!? It seems to be due to the I2C class.

The micropython programs for the project:

oled.py Display API

SSD1306.PY OLED hardware driver

stepper.py Micropython module

Vl53l0x.py Driver module

lightradar.py Operating software

Micropython - Language - Modules and Programs

To install Thonny you will find one here Detailed instructions (English version). There is also a description of how that Micropython firmware (As of 05.02.2022) on the ESP chip burned becomes.

Micropython is an interpreter language. The main difference to the Arduino IDE, where you always flash entire programs, is that you only have to flash the Micropython firmware once on the ESP32 so that the controller understands micropython instructions. You can use Thonny, µpycraft or ESPTOOL.PY. For Thonny I have the process here described.

As soon as the firmware has flashed, you can easily talk to your controller in a dialogue, test individual commands and see the answer immediately without having to compile and transmit an entire program beforehand. That is exactly what bothers me on the Arduino IDE. You simply save an enormous time if you can check simple tests of the syntax and hardware to trying out and refining functions and entire program parts via the command line before knitting a program from it. For this purpose, I always like to create small test programs. As a kind of macro, they summarize recurring commands. Whole applications then develop from such program fragments.

Autostart

If the program is to start autonomously by switching on the controller, copy the program text into a newly created blank tile. Save this file under boot.py in WorkSpace and upload it to the ESP chip. The program starts automatically the next time the reset or switching on.

Test programs

Programs from the current editor window in the Thonny-IDE are started manually via the F5 button. This can be done faster than the mouse click on the start button, or via the menu run. Only the modules used in the program must be in the flash of the ESP32.

In between, Arduino id again?

Should you later use the controller together with the Arduino IDE, just flash the program in the usual way. However, the ESP32/ESP8266 then forgot that it has ever spoken Micropython. Conversely, any espressif chip that contains a compiled program from the Arduino IDE or AT-Firmware or Lua or ... can be easily provided with the micropython firmware. The process is always like here described.

The light radar

In the operating program we work in two places Interrupts (IRQ = interrupt request = interruption requirement).

A timer-IRQ ensures the operation of the engine. An IRQ is triggered in more or less the same time intervals. The corresponding Interrupt service routine (ISR) manages its own counter, through the time of which the time duration between two step pulses is set.

In the start of the program, the motor axis is moved in a rapid rotation in the opposite direction. So that it is automatically stopped into the light barrier when the sheet is entered, we let the timer stop the timer through the ISR of a pin change IRQS and thus (temporarily) end the rotation. A pin-change IRQ occurs when a level change takes place at a GPIO input. This is exactly what the light barrier or the reed contact ensures.

Figure 5: Gabel sealing barrier - circuit

Figure 5: Gabel sealing barrier - circuit

Figure 6: Light barrier module

Figure 6: Light barrier module

An IR LED is located in one of the two cheeks of the light barrier. The photo transistor switches through when the light of the LED hits it. This leaves S on GND level. An opaque obstacle in the fork shadows the transistor, which blocks it. The resistance draws S on VCC potential.

Figure 7: Reed contact - circuit

Figure 7: Reed contact - circuit

Figure 8: Reed contact Mini - module

Figure 8: Reed contact Mini - module

In the case of the reed contact, two soft iron contacts are close to a protective atmosphere without touching, S is drawn by resistance to VCC. If you approach a small stick magnet, then the contacts through magnetic influencing will temporarily to magnet that attract each other and thus close the contact, S goes to GND potential. If you use this solution A tip for provision:

Please do not bend too much on the connection wires of the reed contact, they are quite stubborn. The implementations on the vitreous then quickly maintain and the component is broken.

The entire circuit shows Figure 9.

Figure 9: Lichtradar - circuit

Figure 9: Lichtradar - circuit

Figure 10: Structure of the light radar (with self-made power supply 12V-5V)

Figure 10: Structure of the light radar (with self-made power supply 12V-5V)

The program

The program lightradar.py Is "only" the conductor in this concert with its 18 lines. The musicians, i.e. methods, will play in the individual classes that we have to invite at the beginning. The boss himself brings a few interpreters, functions. And of course he has to determine the instruments, GPIO pins and data structures with which you are to be played.

We find the GPIO pins in the module machine, as well as the class Softi2c, which delivers the basics for the maintenance of the ESP32 with the VL53L0X and the OLED display. The function ensures short breaks sleep() from the module time. The function exit() from the module sys Allow us to end the game in an orderly manner after tidy.





The class OLED From the module OLED provides methods that make the control of the display easy and the class VL53L0X summarize the complex processes of the chat with the TOF sensor. The module from the website https://github.com/uceeatz/VL53L0X/blob/master/VL53L0X.py had to be adjusted for the ESP32 because it was written for Pycom Wipy boards. So please use My version. In this context, I remind you to flash the ESP32 with the 18-way revision of the firmware, because later versions cancel error messages when the VL53L0x starts.

I already have the musicians, forgiveness, methods in the DRV8825 class previous contribution described. They serve the engine control, which, as already indicated above, runs in the background through timer-IRQ control. The DRV8825 class inherits from the A4988 class, which does the main work. In DRV8825 only the method is set fashion() and the modus table Fashionable overwritten. The program also works with the A4988 without any problems and without changes if you adapt the import line in the following way:





The next lines distribute the GPIO pins:









I use an engine with 200 full steps per revolution.

I like to take the flash button on the ESP32 as a escape button. During the development, I enable a clean program exit. If you want to use another GPIO PIN, I have declared the PIN as an entrance to pullup as a precaution. This is not necessary for GPIO0 because it has an external sweater of 10kΩ and is initialized as an entrance.





We create an I2C bus object that we immediately hand over to the constructor of the display object. We use a display with 128 x 64 pixels.





The Bus object is also assigned the constructor of the VL53L0X class. The hardware addresses of the building blocks are already defined in the classes by default. You can over I2C.Scan() In Replica be called up. I always format input, the expenses in italics.





The VL53L0X is available below 41 = 0x29, the display below 60 = 0x3c. This first test signals the basic willingness of the two devices on the bus. Now we instantiate the VL53L0X object. I also stick to the example of https://github.com/uceeatz/VL53L0X/blob/master/main.py





With the call from start() Calibrates the VL53L0X. This is exactly where a timeout error occurs when one other firmware than ESP32_Generic-20220117-V1.18.bin has flashed. We read the first value, which is usually over 8000 to forget it again. That means we don't use it further.





Then we create an engine instance M. We hand over the numbers of the tax pins and the number of steps per revolution. The variable found will represent the state whether the start position of the rotor was found, i.e. it was hit or not. We haven't searched for it yet, so there is no notice, False.

The center of the lowest line in the display reflects the position of the engine in the room. Our application presses a polar coordinate system on the eye. The origin is the point just mentioned, the pole (0, 0). The distance r, measured under the angle J, delivers the polar coordinates of the PR (R, J) point. The conversion into the Cartesian coordinates of the display later takes over the function point().

The maximum radius rmax The minimum of half and height of the display is on the display. The maximum measurable distance Distmax Please prove the highest reliable value that your sensor can deliver. The proportional factor propane factor For the conversion of space into display coordinates, the quotient is rmax and Distmax (= rmax).

Figure 11: Raum and Display coordinates

Figure 11: Raum and Display coordinates

Let us declare a few functions that help us relieve the main loop and keep it clearly and legible. The most extensive routine is Gotostart(). It sends the rotor into the starting position using the light barrier. So that the possible change from found The variable is declared the local context of the function as globally. We already have them above False initialized. We switch on the engine, use the speed to 400 steps per second and set the eighth step mode. This causes a step angle of 360 / (200 • 8) = 0.225 °. Then we start the Timer-IRQ, which will ultimately ensure automatic rotation. Class A4988 provides all of these actions. Thanks to the inheritance, they are also available to the DRV8825 class, which we have imported.

If the level on the reference pin reference Now a logical 1 is currently delivering, the sheet on the rotor lever is already in the light barrier. We shoot the lever in micro-rides of 0.225 ° clockwise until the reference pin delivers a 0, then the light path is free and the starting position is reached exactly. The method relative() says with the handed over the argument of the ISR of the timer-end of how many steps to take. So we don't need to take care of the process itself, relative() is our subcontractor.





The logical level on the pin reference Is 0 if the IR light that can be switched through the LED can be switched through the transistor. The lever on the rotor then points in some unknown direction and would have to shade the photo transistor at some point. At that moment the rotation must be stopped. He takes care of this case Else-Branch.

We first make the reference pin interrupted for rising flanks. The ISR is through pinirq referenced. We will treat this function immediately. After the IRQ is sharpened, we set found on False And start a full revolution, which is 200 times 8 microsr in counter clocks. We are waiting for the ISR of the Pin Change IRQ of reference The variable found on True has set and do nothing during this time - passport.

Now it may be that the IRQ is only triggered when the tin nose is already a piece in the light barrier. So we gradually drive out of the light barrier as in the IF branch. The IRQ is no longer needed, so we put on the handler None. The routine will be left when the position hands have been set to 0.

The ISR of the pin change IRQ does not have to do much. So that the variable assignment of found After changing the value, the variable must again be declared globally. The Timer-IRQ is switched off, which means that the rotation stops. We set found on True And that's it. A general principle for ISRS is: you keep them as short as possible.





In order to minimize scattering at the distance measurement, we not only feel once, but also n-just. The function gives the mean value as the most likely value getdistance() back.





The function provides us with the polar coordinates of the measured space point, or rather the measured room area point() already converted to the pixel size of the display. We let it feel five times. We receive the jet length for the display by multiplication with the proportionality factor. The 0 ° direction in the display goes from the pole (63.63) to the left in order to correspond exactly to the space orientation. The sensor also looks to the left in the starting position. Therefore the difference is the difference from 180 ° and the rotor angle. We get the latter from the step position position and the step angle degperrev through multiplication. The values ​​for radius and angles give the function over that Tupel (R, W) back.





Last preparations. We head for the starting position, switch to half-step mode and enter the main loop.





We start every run by catching up a coordinate couple for the radius and angle as a starting shot for the inner While loop. The first angle is 180 ° and therefore larger or equally 0 °.





The memory is cleaned up. Then we draw a beam from the origin of our coordinate system to the measuring point. Alternatively, only this point could be entered, depending on which of the two lines, polar pixel or ray. Then it goes a half -step, i.e. 360 ° / (200 • 2) = 0.9 °, further.

A demolition is desired when the flash button is pressed. In this case, we stop the timer IRQ, switch off the engine and leave the program.

The inner While loop has ended when an angle is reached less than 0 °. In the display we now see the scanning of the sensor environment. That could look like this:

Figure 12: scanning of my work table by 180 degrees

Figure 12: scanning of my work table by 180 degrees

The distance towards 10 a.m. does not go beyond the detection limit, but the objects there do not form a smooth area. So there is not enough light back for a decent measurement. In this case, the VL53L0X returns values ​​over 8000. This leads to jet lengths beyond the screen edge.

In the main loop, the starting position is still on the renewed. Gotostart() leaves us the mode 8, so we put back on half-step mode, make a little nap and start the next round after the display has been extinguished.

For some time now, round colored TFT displays with 240x 240 pixels have been on the market. This motivates to build a radar with a recording angle of 360 °. Let's see, maybe one of the next episodes will be used.

Until then, lots of fun with tinkering and programming - and - stay tuned!

DisplaysEsp-32Projekte für anfängerSensoren

Deja un comentario

Todos los comentarios son moderados antes de ser publicados