- edited description
How to custom the i2c pins and UART2 for a new ESP32 board
@John Maloney Hi John,
I would like to add a new vm for a new board which is popular in China mainland.
It is built on ESP32-Wroom-32 with 8M flash.
- ESP-32 master
Processor: Tensilica LX6 dual-core processor (one core for high-speed connection; one core for independent application development)
Main frequency: up to 240MHz clock frequency
SRAM: 520KB
Flash: 8MB
Wi-Fi standard: FCC/CE/TELEC/KCC
Wi-Fi protocol: 802.11 b/g/n/d/e/i/k/r (802.11n, speed up to 150 Mbps), A-MPDU and A-MSDU aggregation, support 0.4us guard interval
Frequency range: 2.4~2.5GHz
Bluetooth protocol: Compliant with Bluetooth v4.2 BR/EDR and BLE standards
Bluetooth audio: CVSD and SBC audio Low power consumption: 10uA
- Power supply mode: Micro USB power supply
- Working voltage: 3.3V
- Maximum working current: 200mA
- Maximum load current: 1000mA
- Control onboard
Three-axis accelerometer MSA300, measuring range: ±2/4/8/16G
Geomagnetic sensor MMC5983MA, measurement range: ±8 Gauss; accuracy 0.4mGs, electronic compass error ±0.5°
light sensor
microphone
3 full-color ws2812 lamp beads
1.3-inch OLED display, supports 16*16 character display, resolution 128x64
passive buzzer
Support 2 physical buttons (A/B), 6 touch buttons
Support 1-way alligator clip interface, which can be easily connected to various resistive sensors
- Expansion interface
20-channel digital I/O, (including 12-channel PWM, 6-channel touch input)
5-channel 12bit analog input ADC, P0~P4
1 way external input alligator clip interface: EXT/GND
Support I2C, UART, SPI communication protocol
Here is the schematic and hardware.
I have tested it with ESP32 vm,it can work.
But the I2C is custom,it use gpio 23 for SDA and gpio 22 for SCL with built in OLED.
How clould I custom the I2C with a new vm for the board ?And how could I custom the serial2 port for the board?
Thanks.
Comments (18)
-
reporter -
reporter - edited description
-
reporter - edited description
- changed title to How to custom the i2c pins and UART2 for a new ESP32 board
-
reporter - edited description
-
repo owner Hi, Tom.
That board is supported by PlatformIO so you can get started by adding these lines:
[env:mpython] platform = espressif32 board = labplus_mpython board_build.partitions = noota_3g.csv lib_deps = WebSockets 256dpi/MQTT
to the platformio.ini file. Then build and install:
pio run -e mpython -t upload
The I2C pins should be correct; they are provided by PlatformIO's board definition.
This should give you a working MicroBlocks. You may want to write a small library for that board to access any special features (e.g. light sensor and microphone).
If this works for you, I can add the mpython entry to the platformio.ini file in the next pilot release.
-
repo owner - changed status to open
-
reporter @John Maloney
Thanks for your quick reply.
I could built the vm for labplus_mpython board according to your tips.
It works,but I can not access the OLED, Geomagnetic sensor,Three-axis accelerometer MSA300 now.
I would like to try to write libarys for the board to access any special features.
-
repo owner If the OLED has an SSD1306 controller, the OLED Graphics library might work.
I assume the geomagnetic sensor and three-axis accelerometer MSA300 are I2C sensors. By reading their datasheets you should be able to create a libraries for them using the I2C blocks in the Comm category. If you do create one or more libraries, you are welcome to submit for inclusion in MicroBlocks.
Good luck!
-
reporter @John Maloney
I noted that the board use 1.3 inch OLED, the datasheet is here.
I think it may be slightly different from the 0.96 inch oled. That is why I can not access it with MicroBlocks OLED block.
-
reporter @John Maloney
Hi John,
I can not use the OLED correctly with Adafruit_SSD1306 lib on Arduino IDE.
The OLED looks like this.
But it works with Adafruit_SH110X lib on Arduino IDE.
I can run this OLED demo with Adafruit_SH110X on the board.
-
repo owner I see. that board uses a different OLED controller chip (SH1106 vs. SSD1306).
From a quick look at the SH1106Wire.h, the SH1106 may not be too different from the SSD1306. By reading the datasheet for the SH1106, it might not take too much work to modify the OLED Graphics library that works with that display.
Another option would be to build TFT support for that display into the virtual machine. The easiest way to do that would be to use a driver that works with the Adafruit GFX graphics library, such as this one. However, I did a quick test and that library fails to compile due to a reference to an AVR header file. That might be easy to fix -- or not.
Unfortunately, it looks like either path will require some work.
-
repo owner If you want to experiment with SH1106 in MicroBlocks, the code below may be of interest. It is a project that builds up graphics operations in a step-by-step way for the SSD1306, starting with drawing individual pixels. Just copy the code into a file with a .ubp extension and open it in MicroBlocks. You will probably need to change the code in showBuffer to work with SH1106 but once you've gotten that working, everything else should work. Have fun! :-)
module main author unknown version 1 0 description '' variables oledBuffer penX penY penDirection sprites spec ' ' 'OLEDInit' 'OLEDInit' spec ' ' 'OLEDSendCmd' 'OLEDSendCmd _' 'str' '' spec ' ' 'clearBuffer' 'clearBuffer' spec ' ' 'showBuffer' 'showBuffer' spec ' ' 'drawPixel' 'drawPixel x _ y _ white _' 'num num bool' 0 0 true spec ' ' 'drawLine' 'draw line from _ _ to _ _ white _' 'num num num num bool' 0 0 127 63 true spec ' ' 'drawCircle' 'draw circle center _ _ radius _ white _' 'num num num bool' 64 32 10 true spec ' ' 'home' 'home' spec ' ' 'move' 'move _ pen down _' 'num bool' 10 true spec ' ' 'goTo' 'go to x _ y _ pen down _' 'num num bool' 30 30 true spec ' ' 'turnBy' 'turn _ degrees' 'num' 90 spec ' ' 'setDirection' 'point in direction _' 'num' 0 spec ' ' 'addSprite' 'addSprite' spec ' ' 'animateSprites' 'animateSprites' spec ' ' 'moveSprite' 'moveSprite _' 'num' 10 to OLEDInit { clearBuffer } to OLEDSendCmd cmdString { comment 'Input is a comma separated string of hex values.' for cmd ('[data:split]' cmdString ',') { '[sensors:i2cWrite]' 60 ('[data:makeList]' (hexToInt '80') (hexToInt cmd)) } } to addSprite { if (sprites == 0) {sprites = ('[data:makeList]')} local 'dx' (random -10 10) local 'dy' (random -10 10) if (dx == 0) { dx = 1 } if (dy == 0) { dy = 1 } local 'newSprite' ('[data:makeList]' (random 0 127) (random 0 63) dx dy) '[data:addLast]' newSprite sprites } to animateSprites { if (sprites == 0) {sprites = ('[data:makeList]')} oledBuffer = ('[data:newByteArray]' 1024) for sprite sprites { moveSprite sprite drawCircle (at 1 sprite) (at 2 sprite) 3 true } showBuffer } to clearBuffer { if (0 == oledBuffer) { oledBuffer = ('[data:newByteArray]' 1024) } else { atPut 'all' oledBuffer 0 } showBuffer } to drawCircle cx cy r pixOn { comment 'Draw a circle with radius r centered at cx,cy using Bresenham circle algorithm.' local 'x' (0 - r) local 'y' 0 local 'err' (2 - (2 * r)) repeatUntil (x >= 0) { drawPixel (cx - x) (cy + y) pixOn drawPixel (cx - y) (cy - x) pixOn drawPixel (cx + x) (cy - y) pixOn drawPixel (cx + y) (cy + x) pixOn r = err if (r <= y) { y += 1 err = (err + ((y * 2) + 1)) } if (or (r > x) (err > y)) { x += 1 err = (err + ((x * 2) + 1)) } } } to drawLine x0 y0 x1 y1 pixOn { comment 'Draws a line from x0,y0 to x1,y1 using the Bresenham Algorithm' if (0 == oledBuffer) { clearBuffer } local 'dx' (absoluteValue (x1 - x0)) local 'dy' (-1 * (absoluteValue (y1 - y0))) local 'err' (dx + dy) if (x0 < x1) { local 'sx' 1 } else { local 'sx' -1 } if (y0 < y1) { local 'sy' 1 } else { local 'sy' -1 } forever { drawPixel x0 y0 pixOn if (and (x0 == x1) (y0 == y1)) { return } local 'e2' (2 * err) if (e2 >= dy) { err += dy x0 += sx } if (e2 <= dx) { err += dx y0 += sy } } } to drawPixel x y pixOn { comment 'Set the value of pixel at x,y in GDBuffer. Use showBuffer to display it. Ranges: x: 0-127 y: 0-63 byteIndex: 1-1024 bitIndex: 0-7 ' comment 'Check ranges' if (or (x < 0) (x > 127)) { return } if (or (y < 0) (y > 63)) { return } local 'byteIndex' ((x + ((y / 8) * 128)) + 1) local 'bitIndex' (y % 8) local 'byte' (at byteIndex oledBuffer) if pixOn { byte = (byte | (1 << bitIndex)) } else { byte = (byte & ('~' (1 << bitIndex))) } atPut byteIndex oledBuffer byte } to goTo x y drawFlag { local 'startX' (penX >> 14) local 'startY' (penY >> 14) penX = (x << 14) penY = (y << 14) if drawFlag { drawLine startX startY x y true } } to home { goTo 64 32 'none' setDirection 0 } to move n drawFlag { comment 'Representation: penDirection is in hundreths of a degree (e.g. 4500 means 45 degrees) penX and penY are scaled by 16384 (2^14) The sine function takes an angle in hundreds of a degree and returns a number scaled by 16384. penX and penY are also scaled by 16384. Those numbers are shifted right by 14 bits to get pixel locations.' local 'startX' (penX >> 14) local 'startY' (penY >> 14) comment 'The cosine is just the sine shifted by 90 degrees.' penX += (n * ('[misc:sin]' (penDirection + 9000))) penY += (n * ('[misc:sin]' penDirection)) local 'endX' (penX >> 14) local 'endY' (penY >> 14) if drawFlag { drawLine startX startY endX endY true } } to moveSprite sprite { local 'x' (at 1 sprite) local 'y' (at 2 sprite) local 'dx' (at 3 sprite) local 'dy' (at 4 sprite) comment 'If touching left or right edge, make dx go towards center' if (x < 0) { dx = (absoluteValue dx) } if (x > 128) { dx = (0 - (absoluteValue dx)) } comment 'If touching top or bottom edge, make dy go towards center' if (y < 0) { dy = (absoluteValue dy) } if (y > 64) { dy = (0 - (absoluteValue dy)) } comment 'Update sprite position' x += dx y += dy atPut 1 sprite x atPut 2 sprite y atPut 3 sprite dx atPut 4 sprite dy } to setDirection a { penDirection = ((a * 100) % 36000) } to showBuffer { comment 'Send oledBuffer data to the display. Sends data in 32 byte chunks for speed. Each chunk starts with the command 0x40.' if (0 == oledBuffer) { clearBuffer } comment 'Horizontal mode.' OLEDSendCmd '20,00' comment 'Set the display buffer write destination to top-left.' OLEDSendCmd '22,00,07,21,00,7F' local 'buffer' ('[data:newByteArray]' 33) atPut 1 buffer (hexToInt '40') local 'start' 0 repeat 32 { for i 32 { atPut (i + 1) buffer (at (start + i) oledBuffer) } '[sensors:i2cWrite]' 60 buffer start += 32 } } to turnBy a { penDirection += (a * 100) penDirection = (penDirection % 36000) } script 83 58 { comment '1. Hardware' comment '2. Display buffer' comment '3: Pixels' comment '4. Lines and circles' comment '5. Turtle graphics' comment '6. Animation' } script 103 482 { comment '1. Hardware' } script 134 522 { OLEDInit } script 221 523 { OLEDSendCmd 'A5' } script 358 586 { comment 'normal mode' OLEDInit OLEDSendCmd 'A4' } script 179 589 { comment 'all pixels on' OLEDInit OLEDSendCmd 'A5' } script 103 915 { comment '2. Display buffer' } script 224 946 { showBuffer } script 319 946 (v oledBuffer) script 134 947 { clearBuffer } script 196 1019 { OLEDInit clearBuffer for i 128 { atPut i oledBuffer 255 } showBuffer } script 109 1408 { comment '3: Pixels' } script 148 1443 { drawPixel 0 0 true } script 193 1502 { OLEDInit drawPixel 0 0 true showBuffer } script 194 1602 { OLEDInit clearBuffer for i 64 { drawPixel i 0 true } showBuffer } script 128 1866 { comment '4. Lines and circles' } script 149 1899 { drawLine 0 0 127 63 true } script 342 1900 { drawCircle 64 32 10 true } script 174 1956 { OLEDInit clearBuffer drawLine 0 0 127 63 true drawCircle 64 32 30 true showBuffer } script 343 2073 { OLEDInit clearBuffer for i 30 { drawCircle 63 32 (2 * i) true showBuffer } } script 175 2167 { OLEDInit clearBuffer repeat 100 { drawLine (random 0 127) (random 0 63) (random 0 127) (random 0 63) true showBuffer } } script 73 2393 { comment '5. Turtle graphics' } script 159 2428 { move 10 true } script 333 2428 { goTo 30 30 true } script 98 2429 { home } script 261 2456 { setDirection 0 } script 133 2457 { turnBy 90 } script 190 2486 (v penY) script 134 2487 (v penX) script 249 2487 (v penDirection) script 179 2542 { OLEDInit clearBuffer home repeat 24 { repeat 4 { move 20 true turnBy 90 } turnBy 15 showBuffer } } script 58 2847 { comment '6. Animation' } script 90 2882 { animateSprites } script 208 2882 { moveSprite 10 } script 326 2882 { addSprite } script 92 2913 (v sprites) script 197 2933 { comment 'Start animation' OLEDInit repeat 10 { addSprite } clearBuffer forever { animateSprites } } script 387 2972 { comment 'Add ten more sprites' repeat 10 { addSprite } } script 365 3152 { comment 'A sprite is represenented by four numbers' return (at 1 sprites) } script 102 3154 { comment 'Report number of sprites' return (size sprites) }
-
reporter @John Maloney
Thanks for your help.
I will have a try.
-
reporter @John Maloney
Hi John,
I read the OLED datasheet of SSD1306 and sh1106.
I note that they use different addressing modes.
It has three addressing mode for SSD1306 OLED, they are Page addressing mode,Horizontal addressing mode and Vertical addressing mode.While SH1106 OLED uses Page addressing.
I know that OLED Graphics of MircroBlocks use Horizontal addressing mode.
Therefore I should change the addressing mode for SH1106 OLED, and I should change the code in showBuffer block to work with SH1106 which you gave me above?
Also, what is the SRAM of the SH1106 OLED? Is it 132 X 64 bit SRAM? Should I have to consider this factor when changing the code in showBuffer block?
Thanks.
-
repo owner I would start by setting one byte of the buffer to 255, then writing the buffer to the SH1106. Once that works, you'll be able to study the datasheet to understand the pixel layout. I think you will only to change the code in "drawPixel" to make it for the SH1106 layout. Once you have that, you will also have lines and circles.
Also, what is the SRAM of the SH1106 OLED? Is it 132 X 64 bit SRAM? Should I have to consider this factor when changing the code in showBuffer block?
I'm not sure why they have more RAM than pixels. I'm not sure if you need to consider this. I would experiment by getting "showBuffer" working.
The datasheet is complicated, but working with these displays is fun once you get something on the screen.
Good luck!
-
repo owner - changed status to resolved
Did you have success with this project? I am marking this resolved since the original question was answered, but feel free to continue to comment here about writing a MicroBlocks library for the SH1106.
-
reporter Hi @John Maloney Yue Shao have worked it out. Thanks for your help.
-
repo owner That's great! Congratulations to Yue Shao (and you) for solving a complex problem. Thanks for letting me know.
- Log in to comment