Hi, This is my first question on here but not my first arduino project, but definitely my most ambitious!
I am making an Avengers themed bed for my son with a sliding door driven my a stepper motor. A keypad to enter a password on and an oled screen to display some images and also text.
My problem is the screen stays on the last image called. The code seams to skip the display.clearDisplay() command, even without a delay the image or text stays until another screen is displayed. The clearDisplay works as the next screen is not written over current screen but I want the screen to revert to clear/blank most of the time.
Day 3 was a Sunday, which meant a lot of time spent with the kids. In the end, I only managed to work on roughing out the mechanical design a little more, which led to following questions and remarks:
This specific voltage only applies to Arduinos though and the stepper driver boards might have different threshold values. In the end, it is always a janky, hacky solution. To make sure my logical levels would register as intended, I used the level shifter module.
After setting up the breadboard and attaching both the 4 AA battery pack as well as the USB connection, I loaded the minimal example of my goto stepper motor control library: StepperDriver v1.3.1 by author Laurentiu Badea. The example I loaded is called BasicStepperDriver and can be found under File -> Expamples -> StepperDriver. After changing the standard number of the DIR and STEP pins to my 5 and 4, I uploaded the code to the board and the stepper motor started turning as expected.
Afterwards, I tried the SilentStepStick driver. It is supposed to be a drop-in replacement for the A4988 stepper drivers, but in the end, I could not get it to work reliably, the motor was just jittering back and forth, eben after explicitly grounding some pins to set up a microstepping factor as per the instructions ( ). Since the A4988 was running plenty well and also silently enough for my needs, I decided not to go down the rabbit hole and just call it quits with the other driver. I removed the SilentStepStick from the board and rewired everything to run with the A4988 driver.
I then decided to get the actual motor of choice running, a slightly smaller, unipolar, 6-lead stepper motor (probably salvaged from a flatbed scanner or similar). As noted before, the additional 2 wires an unipolar 6-leaded motor has over a 4-leaded bipolar one are center taps of the motor windings. From my experience, these can be left out and ignored and the motor can just be hooked up like any other 4-leaded bipolar stepper. I did this for testing using flying spaghetti wires first, connecting the winding end points to the motor winding terminals on the stepper driver board. It all went well, it just went a little far:
The initial code in the MWE was set up for a motor of 200 steps per revolution and the motor was programmed to tun 360. After attaching the new motor, the same code actually made the motor turn four full rotations, meaning that the number of steps the library expected was set up 4 times too high. The actual number of steps in this motor (and this configuration) is 50 steps steps per revolution, giving it an angle per step of 7.2. After changing the motor steps variable in the code to 50, the stepper motor did turn 360 only, as intended:
The motion was rather choppy, to be expected going by the rather coarse angle per step. It also went pretty slow though, so I then upped the RPM variable in code which tells the library how fast to turn the motor in revolutions per minute. I set it to 150 from the previous value of 30, making the motor appear to move much smoother (and faster, obviously).
After testing the motor properly, I then replaced the flying spaghetti wires on the breadboard by some properly lengthened ones to keep a neat prototyping environment for now. The motor would later be connected by a crimped on connector, but that would have to wait until full system integration, when I would know how long my cables would have to be etc.:
When it came to connecting the I2C lines for data communication, I was lost for a moment: On the D1 Mini pinout diagram as provided by the manufacturer, there are no pins carrying the usual I2C names SCL and SDA at all:
In the end, testing it and changing the stepper driver code to use pins 2 and 0 worked fine though, so I stuck with it for now, keeping in mind that there is a certain weirdness there. After connecting the stepper driver to 2 and 0 I then went ahead an connected the display to D1 and D2 (5 and 4), so to the I2C bus:
After tidying up the breadboard, I decided to whip up a MWE using both the StepperDriver as well as the Adafruit SSD1306 library together. Sometimes the weirdest things happen when you start to cross streams, so to say, and I did not want to be caught by this later. I started by using the display example code, stripping away all the test graphics functions (as I would only display text if needed) and writing a little extra function displaying mockup temperature values:
I then decided to also try integrating the code for the WiFi function. Since the D1 Mini would not query the API often at all, later (only once every 10 minutes), there should not be any problem running the WiFi API querying code together with the rest. I decided I would display the actual temperatures returned by the API for testing:
It needed a bit of shuffling of variable declarations and some type casts to make everything work together, but in the end I got it working. The board will initialize, create a WiFi connection, parse the weather data after receiving it through the API and then display the parsed values on the display, intermittently also moving the motor and changing the display content:
Tuesday, again: change of plans. With the prototype pretty much finished ona breadboard, this day, I decided to first flesh out the program a little more to use the display to indicate connection status as well (as this makes debugging a little easier). First, I rearranged the code to have the display initialize first, so it could immediately be used for startup sequence debug info. Then I implemented a function to print WiFi connection info to the display instead (or rather: additionally to) of the Serial console:
As I had read before (an interesting piece of code history, btw), there was a problem with an off-by-one error in certain areas of the symbol table (cp437) used by the Adafruit GFX library. At some point in time, that off-by-one error was introduced accidentally and never really fixed to not break compatibility with a lot of code that had already been written:
All LEDs are connected to power and GND separately in this test case, only the data line is carried from LED to LED (using the green, diagonal jumpers underneath). An article by Adafruit regarding best practices when using NeoPixel LEDs (which are not identical, but very similar) mentioned explicitly to remember that the data line on LEDs powered by 5V had to be 5V, too, so if a lower supply voltage was used on the microcontroller, a level shifter would have to be used for the data lines. That made sense to me and I suspected it would be the very same for my SK6812 LEDs. My level shifter on the breadboard still had two more channels available, so no problem. I wired up pin D5 (14 in Arduino terms) to a channel of the level shifter and wired its output to the data input of the first of the three daisy-chained LEDs:
Before powering up the circuit, I looked for libraries fpr the SK6812 LED, which it seems there were a number of. I decided to try the NeoPixelBus library by author Makuna, which in comparison to the other options (especially using an ESP8266) sounded like the most advanced and feature-rich one. I installed the NeoPixelBus library v2.7.0 directly from the Arduino IDE library manager:
I then opened the NeoPixelTest example sketch provided by the library. From the comments in there, it shows all kinds of connections that can be made and also how to connect the LEDs to the I2S bus, when using an ESP8266. Reading through the example code, there was stated multiple times that on ESP8266 microcontrollers, no pin could be chosen for the LED connection, but that pin GPIO3 would be used in any case which had hardware DMA support. The D1 Mini pinout states that pin RX on the breakout board was IO3, which I assumed meant GPIO3 in ESP8266 terms. I double checked using another website, which stated the same, here with explicitly mentioning GPIO3, too:
I changed over my wiring to use pin RX instead of the formerly chose D5 for connecting to the level shifter and LED chain. Then, I changed the code to reflect the number of LEDs I use and the fact that I use RGBW LEDs instead of RGB LEDs (with a separate white channel). After uploading the code to the board, the LEDs came to life:
While the code was programmed to light the LEDs up in order red-green-blue, in my case, the LEDs lit up in order green-red-blue. Going by the comments in the example code, this is to be expected and can happen when the LEDs used use a different color ordering in the data sent than standard RGB. This can easily be fixed by setting up the color order when initializing the NeoPixelBus library by changing the initializer NeoPixelBus strip(PixelCount, PixelPin);. Here, the NeoRgbFeature can be changed to NeoRgbwFeature when an RGBW LED is used and also the color order can be changed to NeoGrbFeature or NeoGrbwFeature, respectively. After making that change and reuploading to the board, the pixels now lit up in the expected order red-green-blue:
After break and reboot, I had to go through the code in detail again, as my latest version of the code changes had not been saved when the computer crashed. I made sure that again the NeoPixelBus library was using the NeoEsp8266Uart1800KbpsMethod method (so GPIO2, or D4 was used for the LEDs) and the stepper motor driver pins were set up to use D6 and D5 (or 12 and 14 in Arduino terms). After setting it up cleanly like that, everything (WiFi + Display + Motor + LED) worked together just fine and the board was programmable still. Something before must have gone terribly wrong, but here we were now. As always, I made the breadboard neat again by flattening down my spaghetti wiring and went on:
7fc3f7cf58