New PCBs

The PCBs arrived this week.  I really like the way my Logo came out.  20160415BarePCB

I do want to make an adjustment, make the arrows larger, they didn’t even show up on the silkscreen.

PCBLogo

To start testing, I put a jumper in bypassing the lithium cell charger. I then installed the ESP-12E, the SPI RAM, The Crystal, the USB Serial Bridge, the voltage regulator, and the USB connector. Just enough to power up, load a program and test the basics.

20160415assembledPCB

First test was to  connect to PC and run ESPlorer– it worked.

I got a message:


AT-based firmware detected.
AT+GMR
AT version:0.40.0.0(Aug 8 2015 14:45:58)
SDK version:1.3.0
Ai-Thinker Technology Co.,Ltd.
Build:1.3.0.2 Sep 11 2015 11:48:04

I then tried to install my test version of the software and it wouldn’t install.  I went back to ESPlorer and started playing with the DTR and RTS to see what would happen. It turns out I got DTR and RTS backwards. So I cut the traces and added a couple of jumpers. This is the kind of mistake I was hoping to catch in the design review.

It programmed great with the wires swapped. My code crashed, back to a “Hello World” version.

Turns out the internal memory chip installed on the ESP-12E does not run at the settings I had specified with esptool.py.  I found this out by setting it to 20MHz DIO mode which started working. I then switched it to QIO mode to see what happened. QIO worked, next I tried running at 40 MHz. That worked.

../esptool/esptool.py --port /dev/ttyUSB0 --baud 230400 write_flash -ff 40m -fm qio -fs 32m 0x00000 ../bin/eagle.flash.bin 0x40000 ../bin/eagle.irom0text.bin

I enabled HSPI Overlap mode by adding spiRamInit() to the end user_init(). Ran without crashing. When I started building for use, I discovered no SPI Master Read available.  I saw something that looked correct for slave read, so I borrowed a line from it and did a write followed by that line– it built. I uploaded the code, and it ran, still no testing of the SPI Ram.

I added the function calls to write “Hello World” to the SPI RAM. and read back and put out to the console. and I got garbage back to the console.  Not a surprise. Debugging with a logic analyzer next week.

Have you written code for the ESP8266. Have you worked with SPI before? I would love to Hear from you.

 

Hardware SPI test software (Firmware V00G)

The PCBs haven’t arrived yet.  So, I worked on the test code for the SPI ram.

Using the datasheet, I started setting up for SPI overlap mode.  On the ESP8266 there are two hardware SPI modules.  In overlap mode, they share the same pins.  This means that if you use the second SPI module you can directly work with the flash memory by using CS0 for the chip select.  I don’t see a lot of use for that other than for performance.  If you choose a different chip select, like I am using GPIO15. You are just sharing the pins with the processor. You have to make sure your code will run in RAM while using the second SPI.  ESP8266 documentation calls the second SPI HSPI.

From Microchips 23LC1024 datasheet, the sequence to write to the SPI RAM in sequential mode is:

Set CS low, write out the value 2 MSB First followed by the 24bit address to start writing at(in 3 bytes), followed by the data to be written(as many bytes as wanted up to the size of the RAM) followed by setting CS high.

A Sequential read has the following steps:

Set CS low, Write out the value 3 MSB first followed by the 24 bit address, then read in as many bytes as wanted. Then set CS high.

Side Note: MSB means Most Significant Bit.  Some protocols transfer in the opposite order or LSB first.  It is important to know this when setting up any serial communication. Data is clocked out on the falling edge of SCK and latched on the rising edge of SCK.  The inactive state of SCK is low.

To help out Espressif provides a guide called:

ESP8266 SPI Overlap & Display Application Guid

This guide describes the SPI Overlap mode API as well as gives a reference implementation using an LCD.  Unfortunately this document is missing a lot of useful information.  There is a post on Espressif’s forum describing it and showing an example.

To get started I have created two new files SPIRam.c and SPIRam.h.  This will make the code easier to locate and modify. To begin with I just want to write some data, and read it back and send it out on the serial connection. Basically a Hello World on the SPI RAM

I created 3 functions:

initSpiRam(); // Set up SPI and Overlap Mode
disableSpiRam(); // Shut down Overlap Mode
writeRam(char data[], int length);
readRam(char data[], int length);

I got it to build but I am unable to test it.

I still have to add a couple of commands over the serial port to tell it to write and tell it to read. I pushed a copy up to Github

I’d like to hear about the projects you are working on.  Please leave a comment below.

Debugging

I got the Sigma Delta putting out a waveform that I was looking for. But when I connected the power rail to the input of the inductor for voltage boost, the system stopped booting correctly.

I had several possible problems to look at.

GPIO16 is tied to reset on some ESP8266 modules allowing wake from deep sleep based on the RTC. I tried taking it back out of the code and I am still getting unexpected boot up activity. Doesn’t appear to be the problem, I may have to come back and have another look.

I haven’t built with the change of memory maps until last week. The bootloader may not be linking properly with my code or I may have made some mistakes pertinent to the linker. I removed the new files and recompiled without GPIO16 support and therefore a smaller memory map that fits without modification of the link files. I commented out most of the code and it still would not boot into my code. Code doesn’t appear to be the problem.

Finally, the boost circuit may draw very large amounts of current that will cause noise back into the rest of the system.  Power may not be stable enough for reliable operation. I disconnected the 5V from the boost circuit and got reliable boot.  I need the boost circuit to work, so I replaced the 10 ohm resistor with a 68 ohm resistor( Maximum current draw from USB would be 5v/68Ohms or 74mA). It wasn’t enough. So I tried 220 Ohms, then I tried 1KOhms.  This means the maximum current I can provide to VPP is significantly reduced.  I will add capacitance to the PCB on the 5V lines to allow for better noise immunity. The board is booting reliably.  The problems I had earlier with the CH340G were probably related to this problem as well.  I still needed to run the CH340G at 3.3V, So I am glad I changed that already.

The boost circuit is not able to create a voltage above 5v with the 1K resistor. Testing the ADC reading, I discovered I had R8 and R9 Cross labelled on the board. So I switched the labels on the layout.

The firmware is running again.  I can put a pulse stream out to the Voltage Boost circuit but the 1K limiting resistor is too large to work correctly.

 

Functional testing for layout V00B

For testing purposes, I chose to put the code that I can control over a serial terminal into the ESP-12E. I had to make a few modifications for the new design.  The version for the last design/layout is archived on GitHub, I can easily go back to it if I find a need.

On the new design, several pins are different than before.  I changed the sigma delta output from GPIO2 to GPIO4 so it can drive the voltage boost circuit. I set GPIO16 to output low to turn on the voltage boost circuit, and I set GPIO2 to output low so that the boosted voltage would be on the programming header.

I had to make adjustments to the build environment to build esp-ginx.  Apparently I managed to break the build environment for the SDK in the process.  For esp-ginx I had updated to the newest version of the compiler toolchain.  This removed some symbolic links, so I couldn’t compile at all.  I fixed the symbolic links, and I am able to compile now, however it compiles without any errors but doesn’t make a binary file. Turns out I was in the wrong folder to link properly. Next the calls to GPIO16 causing a failure to compile. I needed to bring in the files gpio16.h and gpio16.c into the project.  Then the project failed to link with the errors “undefined reference to `gpio16_output_conf'” and “undefined reference to `gpio16_output_set'”.  This turned out to be where I placed the file gpio16.c, once I put it in the user folder, that error went away. Then I got a new Error “`.irom0.text’ will not fit in region `irom0_0_seg'” which means I ran out of code space.

While I was looking at the makefiles I noticed a section for configuring the memory in the sdk base folder. SPI SIZE MAP = 4 or 6  both match the ESP-12E. Setting it to 4 and then 6 didn’t fix the problem. Setting BOOT = new and APP to 1 got it to compile and link without errors.

I installed the new code and I get the menu up on my terminal window.

The sigma Delta doesn’t seem to be outputting anything on any pin. This means more testing.

 

Javascript

Merry Christmas!

The PCBs came in today, they look great.  Of course I will need to make the modifications I mentioned last week.  I haven’t received the CH340G chips yet. I will wait until I receive them before I start building.

Rev00BPCBs

This week, I wanted to add  a slider to set the Sigma Delta output that drives the voltage booster to the web interface.  I didn’t know javascript at all so, I went to an online tutorial at Codecademy.com. This tutorial is very basic and even explains the basic concepts of programming in general.  I didn’t learn enough to set up a slider, I did learn enough to do some testing.

I quickly got the Sigma Delta output working in GPIO12 by copying the necessary code from the test project I was using. I then added a call to config_sigma_delta() from user_init() in user_main.c.  I also added a call to set_sigma_delta_duty() from my test code in cgi_relay.c.  Of course I added includes to sigma_delta.h in both of those files.  I then changed the Sigma Delta output from GPIO12 to GPIO4 to match the HV_pulse line used to run the switched coil.

Now if I hit the say Hello button, It changes the Sigma Delta output duty cycle. also, the Chart on the index.html page gives the current reading from the ADC once every 5 seconds.

ADCandSDelta

 

Web Server feature customization

I found out why my URLs without .html on the end weren’t being handled the same as the rest.  There is an array defined in app.c that maps URL paths to alternate paths.

URLsI haven’t found the code that uses this yet, but it seems pretty straight forward what this is used for.

In the function init_http_server in app.c I found several functions that I think I don’t want.  I put a // at the beginning of those lines so that the compiler treats those lines of code as comments.  This is called “commenting out”.  This is useful when removing code that you suspect has an error, or , as in this case, I suspect I can remove.

I don’t need the captive portal. I am happy if users can use the IP address to get to the web server.  Having a domain name and using the web server from within a local network complicates things.

I commented out the lines:

    http_server_bind_domain(INTERFACE_DOMAIN);
    http_server_enable_captive_portal();
and
    http_server_bind_urls((http_server_url *)&api_urls);

I compiled with these changes, “crossed my fingers”, and uploaded. And… I got a continuous stream of reboots with messages coming into the serial terminal program at 115,200.  this means it started the code that initializes the UART and failed some time after that.

Backing up, I uncommented the server_bind lines and again tested on my board. I am able to connect to the Access Point with my android phone. When I point my phone browser to 192.168.4.1, I get an empty page. When I point my desktop browser to the assigned network address, I also get a blank page from the server.  When I point either browser to smart.relay.com. they both load the initial webpage.

I decided to do a hello world cgi function trying to understand how things work.  To the api_urls I added an entry pointing to a new function called http_tst_api_hello.  I then added that function to the cgirelay.c and cgirelay.h files.  The new function will send “Hello World” out on the serial port using the DBG macro.  The new button shows up on the page, but doesn’t appear to do anything except cause a jump to the top of the page.

I don’t know Javascript, CSS and only a little bit of HTML, this part is going to be a challenge. I did finally get what I was trying to do.  Seems like a small step, but it took a lot of studying and tinkering.

I am not putting any of this code up on github, because I am only taking steps to learn how things work. When I start building in real functionality, then I will start putting this code on github.

Web Page Hello World

Serial Hello World

First web page

I have the web server up and running which is great.

While reviewing my design, I found a few mistakes in the layout.  These mistakes are easily fixed with either a jumper wire or solder bridge, so I can keep on testing when the new PCBs arrive.

The web server isn’t working as easily as I had hoped.  I made a copy of the cats web page in the project, added my banner photo from this site and added html links in each page to point to the new page. With my picture added, It wouldn’t compile.  I am sure there is enough room in ROM, so I just need to figure out some settings. I removed the picture from the project and it compiles. I added an entry in my hosts file to point to smart.relay.com. When I go to smart.relay.com on my network it seems to work most of the time.  Speed and reliability will need to be worked on.

My new page unfortunately comes up blank. If I add .html to the end of the url my page loads correctly.  I went through the pages and added the .html ending to each link.  I don’t understand why this is happening this way.

I opened and modified the eagle.app.v6.ld  I changed the irom_0_seg  line. I changed the len value from 0x51000 to 0x80000.  This allowed me to add the banner photo into the project.  I don’t know if this can cause problems.  Assuming the value was at 0x51000 for a reason gives me reason to be concerned about it.  It’s possible that I have allowed data to overlap which could cause major problems. I need to learn how the .ld linker files work.

FirstWebpage

Hello World Firmware V0A

I have finally created a “Hello World” project that works with the Espressif IOT API.

First, in the upper right hand side of this page is a link to the GitHub repository for this project firmware. The general rule for version systems is that you only commit if the code is runnable.  I hope to break the code up into small enough chunks that I won’t get a majorly broken version in the repository, however things happen. If I get stuck, I’ll commit broken code to the repository to keep it current with these blog postings.  GitHub maintains Versions, I’ll try to name each commit in a way that ties back to the current blog entry.  The current commit is the same as the post title, “Hello World Firmware V0A”

Things happened again,  I did a security update on my OS and the esptool.py firmware uploader stopped working altogether.  I did a quick search online and found that the pyserial library started failing with this update.  So I figured out how to roll back to the previous version of the OS kernel and I could get the firmware upload to work.

I copied the AT firmware project into the app directory and ran the gen_misc.sh script file to configure the libraries.  I had some problems with this and I feel I need to know more about how the makefile works.  The gen_misc.sh (gen_misc.bat for windows users) creates a file with the needed libraries for the project.  For GitHub I ended up moving the project to the folder named UProgrammer-Firmware in the same folder that the app folder was in.

I deleted the AT firmware files from the project directory, keeping the user_config.h file in the include folder. I then created a new user_main.c file that just set up the serial port to 115200 baud and sent the text “Hello World” out the serial port from the user_init() function.  This worked and I wanted to do something a little more in depth of the API functionality.  So I started a timer that calls my code called user_state() once every second.  I set up this function to send “Hello World” over the serial connection on the second call of it.  I also removed the sending “Hello World” from the user_init() function.  The function user_init() is called once during boot up of the processor.

I also added the commands to connect to my wifi network.  I verified this by using a utility to see what devices were connected to my network.  When I saw the name espressif for one of the devices, I knew it was connected.  I took one more step and added a new file called wifi.c and a new file wifi.h to the project.  To the file wifi.c, I copied a function from the API documentation that reports connection status changes to the serial connection.  I changed which UART is used so it would report back over the serial connection.  I put the prototype for the function in wifi.h.

Finally, I created a file called simple_serial.c and another file called simple_serial.h.  I plan on moving the initialization code into simple_serial.c to clean up the user_init() function.  I also plan on creating a simple text interface for configuring the connection details.

On the hardware side, I couldn’t re-solder the connector to the board because of too much damage so I cut a USB cable and used the A connector end with wires soldered to the board. I then used super glue to form a strain relief for the wires.

Boot Hello World

USB cable connection

Programming Tools

Things don’t always go as planned.  The firmware upload tools did not work.  The recommended one for Linux is a python script called esptool.py.  I hacked on it to get it working, I bypassed some error checking to get it to work.  I don’t like this but it works for now.  I have tools that proved that the USB Serial port driver was receiving the correct values but esptool.py was not.

Disabling the error checking allowed me to get pre-compiled bin files loaded onto a NodeMCU Devkit Version 0.9 and then onto my circuit.  I downloaded the AT command set firmware as well as the NodeMCU Lua firmware and tested them with ESPlorer.  With the AT command set I was able to connect to my local network, open a webserver port and see a connect attempt from a browser on my Phone.  With the Lua firmware, I was able to turn on an LED on the Devkit PCB(GPIO0) and send some interrogation commands to my circuit.

With both firmwares, the software defaulted to 9600 baud.  This worked fine for my testing.  I have not yet figured out how to get software I create into the ESP-12E. I will be starting with the IOT demo to get a “hello world” project working. A key point will be to get software of my own design working and uploaded into the circuit.  At this point it doesn’t have to have any real functionality.

I also want to figure out why esptool.py did not work, and how I can make it more robust.  If I can solve this problem, I will submit my fixes to the github repository in hopes that it will help others.

There are some things that I discovered that will change the design.  I found a USB to UART bridge that costs less than a Dollar US; the CH340G.  The programming software controls the DTR and RTS lines to automate the re-boot and flash buttons, so I can get rid of the flash pushbutton and minimize the Reset into a couple of pads I can touch with a screwdriver.  Also, on the layout, I didn’t notice that OSHpark doesn’t do plated slots.  The USB micro connector layout has slots.  OSHpark drilled single small holes in place of the slots.  I had to modify the connector to make it fit in the holes.  I will change the connector layout to round holes that will fit the shell pins of the connector to solve this issue in future runs of the PCB.  There is a flare at the end of the connector that keeps it from laying flat, I will move the flare past the edge of the PCB so the connector can lay flat against the PCB. For strength I want to add a pad under the shell that will also be soldered to the shell. I broke the connector off during my testing.

Rev0APartialBuild

 

Multiplexing Pins

If you need just a few more pins on your design, one option is multiplexing.  Some chip manufacturers add multiplexing into their microcontrollers to add versatility.  Often however you have to choose between pin functions that you will use in your design.  For Instance the SPI Pins are shared with the I2C interface.  This can be hard to set up to use both.  If I have a target system that is programmed over I2C, I can use the buffers to isolate the I2c devices from the SPI bus when accessing memory.


I need to be able to pull GPIO0 low for reprogramming the ESP8266 module.  I have already assigned GPIO0 as an output to control the signal direction of the voltage buffers.  During boot it is an input to switch into boot loader mode.  I can pull it low to reprogram the module and let it float the rest of the time.  I have attached a resistor to GPIO0 and a switch to ground to pull it low when I want to reprogram the module. The resistor needs to be small enough to reliably pull the pin low during boot, but not small enough to cause damage when the pin is driving a high output.  As a rule of thumb a 10K resistor should work well.  I will have to experiment with it when I have an actual module to work with.

A 10K resistor will limit current drawn off the pin to 330µA. 3.3V / 10,000Ω = 330µA

I am almost out of pins and may have to do some more multiplexing.

I have ordered some ESP-12E modules and hope to be testing/playing with them soon.  I will probably temporarily stop working on the design and do a couple of Hello World projects.

A developer will make a simple project to test key steps of the design.  In programming this is usually an attempt to put the words “Hello World” somewhere he can see it.  This is called a “Hello World” project. For hardware, this can be as simple as flashing a LED. In this design flashing an LED would prove I could reprogram the device, and have a basic understanding of the build toolchain.