Feed on
Posts
Comments

Recently through a customer I learned about a product called WireSprout, and it only works with the AC-powered OpenSprinkler but not the DC-powered version. Out of curiosity, I looked into why this is happening. So what is WireSprout? Simply speaking, it allows individually controlling 2 zones using a single zone wire. This is useful in situations where some of your zone wires are broken and it’s too much hassle to repair the broken wires. Let’s say you have 2 zones, but only 1 good zone wire. Using WireSprout, you to control both zones using the single good zone wire. This works on any sprinkler controller (well, as you will see later, as long as it’s an AC sprinkler controller). A single WireSprout pack contains a pair of two ‘sprouts’. Each sprout is a tiny little circuit wrapped in heat shrink tubing, and has 3 wires: 1 blue and 2 green wires. Below is the diagram that shows how to connect it to a sprinkler controller:

To be fair it’s not adding more zones — to control 2 zones you still need to take 2 zone ports on the sprinkler controller. Also it requires the Common (COM) wire to be a good (i.e. non-broken) wire. But what it helps with is to reduce the number of zone wires. Note that it can only go with a pair of 2 zones. For example, if you want to control 4 zones, you need another good zone wire and another pack of sprouts. It unfortunately cannot allow you to control 4 zones with a single good zone wire.

Each sprout is very small, so likely it only contains a few electronic components. Also, it’s very general — it can work with any AC sprinkler controller, so the circuit doesn’t rely on the knowledge of any specific controller. It also works only for 2 zones at a time. Finally according to the customer, it doesn’t work with DC-powered OpenSprinkler, only works with AC-powered version. So it must rely on the property of AC to work. I googled similar products, and after a bit of research, it became clear to me that the circuit is indeed extremely simple. Each sprout is essentially two diodes in series, where the two ends are the green wires, and the center (between the two diodes) is the blue wire. Below is what I believe each sprout contains internally:

So how does it work all together? Here is the diagram:

Because the output voltage is AC, it has positive and negative cycles. As you can see, on the positive cycle of the COM wire, if Zone 2 port is on, the two diodes circled green will turn on. So the current flows from COM to Solenoid 1 through the Common wire, then through the zone wire to Zone 2 port. The other two diodes are reverse biased therefore solenoid 2 cannot turn on even if Zone 1 port is on. Conversely, on the negative cycle of the COM wire, the situations with all diodes are flipped, so only Solenoid 2 can turn on (assuming Zone port 1 is on). In this particular arrangement, Zone port 1 controls Solenoid 2, and Zone port 2 controls Solenoid 1. If you want them to correspond to each other (i.e. 1 -> 1 and 2 -> 2), just horizontally flip one of the sprouts.

In short, the WireSprout works by leveraging the fact that AC waves have positive and negative cycles. By using diodes, it can cleverly block half of the AC waves, therefore Solenoid 1 can only turn on during the positive cycles, and Solenoid 2 can only turn on during the negative cycles, or vice versa. Thus these two zones can be individually controlled.

Now it’s obvious why the DC-powered OpenSprinkler can’t work with WireSprout: DC-powered OpenSprinkler outputs DC-only voltage, there are no positive or negative cycles — there is only positive voltage. Therefore WireSprout can’t leverage the negative cycles to disable one of the solenoids therefore it cannot achieve individual control of 2 solenoids using a single zone wire.

There is possibly a downside of this method: each solenoid only get half of the AC waves as opposed to the full wave normally. Would this cause any reliability issues? I am not sure, but it seems there hasn’t been any reported issue so far.

Finally, we can also explain why WireSprout always works in pairs of 2 and not more than that: if you want to control, say 4 solenoids with a single zone wire, that would require counting the parity of the AC waves, which would be much more complex and may require an active circuit.

Fun with ChatGPT

Unless if you’ve been living under a rock, you’ve probably heard of ChatGPT by now, if you haven’t given it a try yet. Over this past weekend, I’ve had some fun with it. Not only it’s amazingly good at writing text description, but it can write programming solutions too. Here are just a few things I asked it to do.

Ray: tell me about opensprinkler

ChatGPT: OpenSprinkler is an open-source, web-based sprinkler controller for watering gardens, lawns, and other outdoor areas. It allows users to automate their irrigation systems and customize watering schedules through a web interface or a smartphone app. The controller can be programmed to turn on and off sprinkler valves at specified times, and can also be integrated with weather data to adjust watering schedules based on local weather conditions. OpenSprinkler is designed to be easy to install and use, and is compatible with a wide range of sprinkler valve systems.

Ray: tell me more about opensprinkler

ChatGPT:

OpenSprinkler is a sprinkler controller that allows users to automate their irrigation systems and customize watering schedules through a web interface or a smartphone app. The controller is connected to a network and can be accessed remotely, allowing users to control their irrigation systems from anywhere with an internet connection.

In addition to being able to set custom watering schedules, OpenSprinkler also offers a number of advanced features that make it easy to optimize watering schedules and conserve water. For example, the controller can be programmed to turn on and off sprinkler valves based on local weather data, such as temperature, humidity, and precipitation. This helps ensure that plants are watered at the optimal times, while also minimizing water waste.

OpenSprinkler is compatible with a wide range of sprinkler valve systems, making it a versatile choice for homeowners and gardeners. It is also easy to install and use, with a user-friendly interface that makes it easy to set up and customize watering schedules.

Overall, OpenSprinkler is a useful tool for automating and optimizing irrigation systems, and can help homeowners and gardeners save time and resources by ensuring that their plants are watered efficiently.

Ray: tell me about opengarage

ChatGPT:

OpenGarage is an open-source, WiFi-enabled garage door opener that allows users to remotely control their garage doors using a web interface or smartphone app. It consists of a microcontroller board with an embedded web server and a relay, which is used to activate the garage door opener.

Users can access the OpenGarage controller through a web interface or smartphone app to open and close the garage door, as well as set custom schedules and receive notifications when the garage door is opened or closed. The controller can also be integrated with other smart home devices, such as home security systems or smart lights, allowing users to automate their garage door functions and create custom scenes.

OpenGarage is designed to be easy to install and use, with a user-friendly interface and a range of customization options. It is also open-source, which means that the software is freely available for users to modify and customize to meet their specific needs.

Overall, OpenGarage is a useful tool for automating and controlling garage doors, and can help users save time and effort by allowing them to remotely access their garages from anywhere with an internet connection.

Ray: what’s unique about opengarage

OpenGarage is an open-source, WiFi-enabled garage door opener that offers a number of unique features and benefits compared to other garage door openers on the market. Some of the key features and benefits of OpenGarage include:

  1. Open-source: One of the key features of OpenGarage is that it is open-source, which means that the software is freely available for users to modify and customize to meet their specific needs. This allows users to easily add custom features or modify the controller to work with specific garage door systems.
  2. Remote access: OpenGarage can be accessed remotely through a web interface or smartphone app, which allows users to control their garage doors from anywhere with an internet connection.
  3. Customization: OpenGarage offers a wide range of customization options, including the ability to set custom schedules, receive notifications when the garage door is opened or closed, and integrate with other smart home devices. This makes it easy for users to automate their garage door functions and create custom scenes.
  4. Compatibility: OpenGarage is compatible with a wide range of garage door systems, making it a versatile choice for homeowners.
  5. User-friendly interface: OpenGarage has a user-friendly interface that makes it easy to set up and customize garage door functions, even for users who are not technically proficient.

Overall, OpenGarage is a powerful and flexible garage door opener that offers a wide range of features and customization options to help users automate and control their garage doors.


As you can see from above, it’s really quite good at generating text descriptions. What’s more incredible is its ability to generate programming code. For example:

Ray: write a jquery program with three buttons, when the first button is clicked, draw a circle, when the second button is clicked, draw a square, when the third button is clicked, draw a face

In this case, the chat engine stopped a few times, and I had to type ‘continue’ to let it finish the program. But after it’s done, it generated a proper Javascript program, when you run it, it pops up the following interface. The circle and square are both drawn perfectly, the face is a bit of a failure, but it’s amusing to see it even produced comments in the code to document how the code draws a face.

I was pretty mind-blown by its capability. As a text generation engine, it’s clearly not just memorizing things, because if you ask it the same question again it will give you a somewhat different answer. I’ve also tried a number of other things, as listed below. Some are more successful than the others.

  • tell me about opensprinkler, in Shakespeare style
  • write instructions to create an IFTTT applet for OpenSprinkler
  • write an Arduino program for ESP8266 to connect to opensprinkler.com
  • write an Arduino program for ENC28J60
  • write a C++ program that uses a circular queue to implement a log

If you want to make changes or correct any mistakes, you can have a conversation with it. Such as ‘change the variable x to y’; ‘rewrite the second paragraph to use less words’, ‘your circular queue implementation is wrong, blah blah blah’.

To a University Professor like me, this is going to have a profound impact on how classes are to be taught, how homework is to be assigned, and how cheating cases are to be detected in the future. I mean, not only it can produce essays, but it can generated reasonably complex program code. A lot of the introductory level programming tasks can be easily solved by it. Well, at least for now, I am glad we can leverage this incredible tool for ourselves to write text descriptions, instructions, and sample programs. Have fun with it!

Today we’ve officially released OpenSprinkler firmware 2.2.0(1). As you may have noticed on this forum post, this firmware is a major revision from the previous firmware 2.1.9. Most of the new features are thanks to Valeriy Soltan’s excellent work almost 2 years ago (I know, time flies during the pandemic), including support for sequential groups, setting a date range for each program, support for pausing and resuming stations, shifting zones forward, more flexible master on/off adjustment times etc. In addition, we’ve added a device name parameter, which is included in all IFTTT notifications; and a new weather adjustment method called ‘Monthly’ adjustment is added to set a manual watering percentage per month. For OpenSprinkler 3.x only — one major step forward is the support of OpenThings Cloud (OTC) token, which allows remote access via the OTC cloud server. This eliminates the need for settings up port forwarding, which has been a pain for manual users. OTC has been enabled for our OpenGarage product for a while, and it seems to be working pretty well, so this is a good time to enable OTC for OpenSprinkler as well. A major benefit of OTC is that the same web interface / UI is available both locally and remotely, and OTC server serves as a real-time ‘relay’ between the firmware and user, it doesn’t actually store any date on the cloud server. Another step forward for OpenSprinkler 3.x is upgrading ESP8266 core to version 3.0.2 (the latest ESP8266 core for Arduino). In important benefit of this is that the WiFi and wired Ethernet are unified, through the lwip library available in this core version. As a result, wired Ethernet and WiFi use exactly the same interface functions, so all WiFi features (including OTA update) are also supported by wired Ethernet. Moreover, this allows OTC to be supported by both WiFi and wired Ethernet as well.

We’ve release a test version of firmware 2.2.0 a month ago and since then have been working on fixing bugs both in the firmware and the UI. At this point, the firmware is ready to be released to the public, and we are really excited. The full list of new features can be found in the Github release notes. As usual, firmware update instructions can be found on our support website at support.opensprinkler.com Since this firmware is very new, bugs and issues are probably inevitable. If you encounter any problem, please be patient and file a support ticket at support.opensprinkler.com We will try to handle them as quickly as we can.

We are happy to announce that OpenGarage firmware 1.2.0 is now officially available. The main change of this firmware is on cloud connection options for remote access: it now supports both Blynk and OpenThings Cloud (OTC) connections. Previous firmwares have only supported Blynk. The motivation for this change is the fact that the Blynk team is officially ending the Blynk legacy app and legacy server; in the meantime we have developed our own cloud proxy called OpenThingsFramework. So it’s the right time for us to push out our own cloud framework.

What are the technical differences? With Blynk, data is stored on the cloud server, which serves as a ‘cache’ between the application and firmware. In contrast, OpenThingsFramework is a proxy — it does not store data on the cloud server, instead, when a request comes from the application, it’s forwarded directly to the firmware, which sends responds back. This is implemented using WebSocket and persistent TCP connection. There are pros and cons of each approach. For example, Blynk has a faster response time, since the data is ‘cached’ on the cloud server; however, the firmware design is more complicated as the built-in web interface of OpenGarage cannot be easily replicated using Blynk. Also, some users may have privacy concerns over data stored on the cloud server. With OpenThingsFramework, data is never stored on the cloud server; and its proxy nature allows the same built-in web interface to be remotely accessible. This significantly simplifies the firmware design: only a small number of changes are needed in firmware code to allow remote access. On the other hand, the response speed can be slow, since the server does not ‘cache’ any data.

Both Blynk and OTC options are supported by our OpenGarage mobile app, as well as a simple OpenGarage web app that I wrote. To users, the practical differences are as follows: push notification is only available with Blynk, and you must have the Blynk legacy app installed on your phone. This legacy app is no longer available in the app store (since the Blynk team has discontinued it). However, if you are Android user, you can still find and install this app manually. That said, you can always use IFTTT for push notification, which is independent of either Blynk or OTC. If you need the ability to remotely access the full built-in user interface of OpenGarage, including changing settings and viewing log data, only OTC supports it. Otherwise, if you just need the ability to check door status and car status, and trigger door actions remotely, you can go with either of them. Please note that as the official Blynk server is going offline soon, if you want to use Blynk, we recommend you to create your Blynk token on our own server at openthings.io. The support article here explains how to create and use Blynk and OTC tokens respectively. I’ve also created a new OpenGarage video that gives you a quick walk-through of the steps. The section starting at 7:25 is about cloud tokens:

If you decide to upgrade to firmware 1.2.0, please note that it requires ESP8266 WiFi chip that has 4MB flash. Most OpenGarage units sold in recent years have 4MB flash, the only exceptions are the early versions (v1.0, 1.1 and 1.2 I believe). Also, as this firmware has changed the flash memory layout, it will trigger a factory reset so it will lose all settings and WiFi configuration. You will need to reconfigure WiFi after the firmware update. Finally, you can choose to use either Blynk or OTC, but you can’t use both of them at the same time.

That’s all. Thanks!

This post documents some of the tips and tricks I learned while integrating ESP8266 into my own circuit designs. Some of them help reduce the components needed thus minimizing the cost, while others have to do with selecting and using GPIO pins. For breadboard prototyping, you can certainly use one of the popular ESP8266 development boards, like NodeMCU, WeMos etc. But what I want to cover in this post is to integrate a ESP8266 module (such as ESP-12F) into the circuit design, without using the development boards.

In the past several years, I’ve gradually transitioned all my gadgets from using the classic ATmega chips (including ATmega328 and ATmega1284) to ESP8266. There are a lot of advantages of ESP8266: it has built-in WiFi, it’s Arduino compatible, it has a lot more RAM and flash memory space than the classic ATmega chips, and it’s really cheap. In fact, due to the ongoing chip shortage, the ATmega chips have become more expensive and difficult to source, while ESP8266 is still widely available at a very cheap price. ESP8266 certainly has some downsides as well: it has a relatively small number of GPIO pins, particularly, it has only one analog pin, which limits its applications; also it can be tricky to use in low-power applications driven by battery power. Nonetheless, as most of my gadgets are powered by USB (+5V), ESP8266 is a perfect choice for me.


Power Circuit

The operating voltage range of ESP8266 is 2.5~3.6V, with 3.3V being the most common. If the input voltage is 5V (from USB), a common method is to use a 3.3V linear voltage regulator, such as AMS1117-3.3. At first, I thought that pretty much any jellybean 3.3V regulator would be sufficient. However, it turns out that ESP8266 can draw a fairly large amount of surge current instantaneously, so some cheap regulators I’ve tried, such as XC6206-3.3V, does not work reliably at all, even though on paper it claims to handle a maximum current of 250mA.

Now, from 5V to 3.3V there is a 1.7V voltage drop, which is about 2 diode drops. Realizing this, I found that a very cheap and quite reliable method to provide power to ESP8266 is to simply use two 1N4148 diodes in series. Under the typical current draw of ESP8266, each diode drops about 0.75~0.85V; with two of them in series, the voltage comes out to be almost exactly 3.3V. Also, as diodes can handle instantaneous current surge quite well, this method works quite reliably, compared to some of the weak voltage regulators.

On the output of the two diodes, you do need a 100~220uF to provide a sufficient buffer. However, since the voltage is low (~3.3V), the capacitor isn’t necessarily large in physical size. A 100uF electrolytic or tantalum capacitor rated at 6.3V or 10V should work just fine. The schematic below shows this simple power circuit.

Two diodes in series provide the required voltage drop

Note the assumption is that the input voltage is from a +5V USB power source, which can provide a minimum of 500mA stable output current. This is indeed the most common case for me. If the input voltage is much higher than 5V, you will still need a voltage regulator. In fact, if the input voltage is significantly higher than 5V, you likely will need a switching regulator for efficiency reasons.

I’ve also had several cases where the gadget need to be powered from USB as well as a lithium battery. The above diode-based power circuit can be easily extended to support dual power sources, as shown below.

Diode D3 both provides voltage drop and blocks reverse current

Here JST is a lithium battery connector. Diode D3 provides the necessary voltage drop: a standard single-cell lithium battery gives 3.7~4.2V, so after D3 it becomes 3~3.5V, which is within the operating voltage of ESP8266. D3 also blocks reverse current in case both USB and lithium battery are plugged in at the same time. This way, at any given time, only one of the two sources will be automatically selected to provide current to ESP8266.

This circuit can also be extended to support charging of lithium battery through USB, such as by using the popular TP4054 battery charger. The input of the charger is 5V from USB, and output is pin 2 of the JST connector. This way, the lithium battery can be connected at all times, and it will be charged whenever USB is plugged in.


Auto-Reset Circuit

A very convenient feature of ESP8266 development boards is the auto-reset circuit: when programming ESP8266, the auto-reset circuit triggers the bootloading sequence automatically before sketch uploading starts, thus there is no need to press any button to manually enter the bootloading mode. This is accomplished by toggling pins on the USB-serial chip with appropriate timing sequence, to simulate a reset while GPIO0 is being held low.

Using CH340 (a very popular, low-cost USB-serial chip) as example: the typical auto-reset circuit such as used on NodeMCU, is as follows:

The auto-reset circuit on NodeMCU

Here the DTR and RTS pins on CH340 are connected to the auto-reset circuit involving two resistors and two NPN transistors. My understanding is that the two transistors are essentially level-shifting circuits, because in the schematic here, CH340 operates at 5V, while ESP8266 operates at 3.3V.

However, CH340 can operate perfectly fine under 3.3V. So if we power CH340 and ESP8266 both with 3.3V, then there is no need to use the level shifting circuits, saving two resistors and two transistors. Below is my simplified auto-reset circuit:

Simplified auto-reset circuit, without level shifting

Note that this circuit uses the CH340C variant of the CH340 chip (there are several variants: G, C, B, T, etc.) because it has built-in 12MHz oscillator, thus there is no need to connect an external crystal oscillator. Also, note that the V3 pin is connected to 3.3V, this is required if it’s CH340 is powered by 3.3V. The TXD, RXD, RTS, and DTR pins on CH340 are connected to RX, TX, RST (Reset) and GPIO0 pins on ESP8266 respectively. No more NPN transistors for level shifting.


GPIO10 comes handy when you really need one more GPIO

If you are familiar with ESP8266, you are probably aware of the typical set of available GPIO pins. These are:

  • GPIO0: the bootloading indicator pin, usually pulled high, can be used as a button if needed.
  • GPIO1/3: the default TX/RX pins, generally connected to the USB-serial chip as above.
  • GPIO2: connected to the built-in LED on ESP12-F, active low. Must be pulled high at booting.
  • GPIO4/5: the default I2C pins. I generally use them for connecting to I2C components like SSD1306 OLED display, real-time clock etc.
  • GPIO12/13/14: general-purpose IO pins that are good for anything; support interrupts and internal pull-ups. These are also the hardware SPI’s MISO, MOSI, and SCK pins, so you will need them if you have SPI components like Ethernet modules, external SD card etc.
  • GPIO15: must be pulled low at booting. Because this pin is guaranteed to be low at booting, it’s suitable for connecting to output components like a relay, a buzzer, an LED etc. which should be inactive at booting. This is also the hardware SPI’s CS pin, but you don’t have to use it as CS — you can use any GPIO pins as CS pin for SPI.
  • GPIO16: this is a restricted pin that does not support interrupt, and has internal pull-down resistor instead of pull-up as the other GPIOs. Other that these restrictions, it can be used as either input or output, but it does have glitches at booting, as detailed below.

As you can see, the number of GPIO pins is quite limited, and those that are truly flexible (i.e. no restrictions and no HIGH/LOW requirements at booting) is even more scarce. What if you just need one more pin? After searching around, I discovered that GPIO10 is another all-around good GPIO pin that you can use. This pin is often not discussed because it’s connected to the internal SPI flash and thus can be problematic to use as GPIO. However, it turns out that this pin is totally usable as long as you make sure the flash mode of ESP8266 is dio (i..e NO qio or qout mode: they will cause GPIO10 to be unusable). Other than that, you can use GPIO10 as input or output, it supports interrupt and internal pull-up.

Some of the forums also mention GPIO9: unfortunately this doesn’t seem to be usable at all. I’ve tried and it always gets my ESP8266 stuck so I gave up.

If you need a lot more GPIO pins, check out my previous post about IO expander chips — it talks about different IO expander options and their pros and cons.


Using a GPIO pin to indicate hardware revision

Occasionally I make changes to a circuit, which often involves re-assigning GPIO pins for different components. For example, in the initial version of a circuit, I assigned GPIO15 to a buzzer; then in a later revision, I ended up removing the buzzer and re-assigning GPIO15 to the CS pin of an Ethernet module. With these different hardware revisions, it’s necessary to also make firmware changes. But I don’t want to maintain so many different versions of the code. Instead, I want the same firmware to automatically detect which hardware revision it is. A common trick I’ve used is to dedicate a spare GPIO pin for this purpose. The way this works is that all GPIO pins on ESP8266 have internal pull-ups (except GPIO16, which has an internal pull-down and not up). The resistance on these pull-ups (or down) is about 40 to 60 Kohm. So assuming nothing is connected to a pin, if you turn on the internal pull-up, it should read HIGH right after booting up. To indicate a different hardware revision, you can connect the pin with a resistor to ground (the resistor value can be anywhere between 1~10 K). This way, the pin will read a LOW even as internal pull-up is enabled. This can be used as an indicator for a different hardware revision.

Of course the downside of this method is that it sacrifices a GPIO pin. But some pins, like GPIO16, has some restrictions that make them less useful than other pins, so why not dedicate it as a revision indicator 🙂


Getting Rid of CH340

So in the above I’ve just talked about how to simplify the auto-reset circuit to save two resistors and NPN transistors. Now, if I am planning to stay with OTA (over-the-air) firmware update, that is, update firmware through WiFi only and not through USB, then I can even get rid of the CH340 USB-serial chip, saving one entire chip from the circuit design! But wait a minute, I still have to program the initial firmware, so I still need a way to use an external USB-serial adapter to do so!

This can be done by one of several common approaches: for example, you can solder a pin header to the circuit to allow plugging in an external USB-serial adapter; if you don’t even want pin headers, you can get rid of them by using a programmer with pogo pins that, when pressed down, can make temporary contact with the circuit. Along that line, I’ve also made dedicated 3D-printed programming assemblies like in the pictures shown below:

Left: a USB-serial programmer with pogo pins; Right: a 3D-printed assembly with pogo pins.

After experimenting with various methods, my favorite one at the moment is to use a card-edge connector that can directly plug into the circuit board. This is basically like the pin-header approach but without having to solder anything. Specifically, I made a custom programmer with CH340 and a 2×3 card edge connector. Then on the circuit board containing ESP8266, I make a matching section, using cutouts and SMD pads, to plug into the connector of the programmer. Standard PCB thickness is 1.6mm, which is perfect for the card edge connector. This idea is very similar to those circuits you may have seen that directly plug into a USB port, or those business-card USB gadgets.

Left: on the top is a custom USB-serial programmer with CH340 and 2×3 card edge connector; on the bottom is a circuit board with ESP8266 and matching PCB cutout for plugging into the connector. Right: after the programmer is plugged in.

What, you may ask, motivates this level of cost-cutting? Well, the ongoing chip shortage has made many parts more expensive and/or difficult to source, so saving a part is not only saving the cost, but also reducing the likelihood that I can’t finish the project because I am short of a 50-cent part. To me, the card edge connector is quite reliable, and there is no problem with pin alignment or accidentally bent pins which I encountered when using the pogo pins.


Choosing the right GPIO pins for the components

Not only ESP8266 has a small number of GPIO pins, but some of them have ‘quirks’ or ‘glitches’ at power-up that you must be aware of when choosing pins for various peripheral components. There are several online articles that discuss ESP8266’s pin statuses at booting, such as:

As an example, GPIO16 has ‘glitches’ during booting which make it turn briefly HIGH (i.e. it outputs HIGH instead of is being pulled up HIGH, so no pull-down resistor can keep it LOW during booting). If this is connected to a relay, it can briefly turn the relay on, which may be undesirable. As another example, GPIO15 must be kept low during booting (otherwise booting fails), but if you use it as CS (chip select) of an SPI component, pulling it low also activates the CS pin, which can cause some random data to be sent to the SPI component. Most likely this is harmless, but if the SPI device is, say, a shift register, this may end up setting the shift register briefly in random states until the setup code kicks in to clear out the shift register values.


As a concluding remark: ESP8266 has served me really well in the past several years. Although the lack of GPIO pins and the ‘quirks’ on various pins are major drawbacks, sometimes I feel these restrictions turn the circuit design into a ‘constraint satisfaction’ problem, which can be an interesting puzzle to solve than a total annoyance. On the other hand, ESP8266’s bigger sister ESP32 has become a lot more popular as well: it has abundant GPIO pins, many of which have ADC support too, and it has many variants to choose from, some with both built-in WiFi and Bluetooth. I will probably gradually transition to use ESP32 in the future. Some of the methods discussed in this post are likely applicable to ESP32 as well.

Older Posts »