Commit 711a537c authored by markusgritsch's avatar markusgritsch
Browse files

Merge pull request #1 from nodemcu/dev

Dev
parents 378398d4 0f6046d8
/*
u8g_virtual_screen.c
Universal 8bit Graphics Library
Copyright (c) 2012, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "u8g.h"
struct _u8g_vs_t
{
u8g_uint_t x;
u8g_uint_t y;
u8g_t *u8g;
};
typedef struct _u8g_vs_t u8g_vs_t;
#define U8g_VS_MAX 4
uint8_t u8g_vs_cnt = 0;
u8g_vs_t u8g_vs_list[U8g_VS_MAX];
uint8_t u8g_vs_current;
u8g_uint_t u8g_vs_width;
u8g_uint_t u8g_vs_height;
uint8_t u8g_dev_vs_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg)
{
switch(msg)
{
default:
{
uint8_t i;
for( i = 0; i < u8g_vs_cnt; i++ )
{
u8g_call_dev_fn(u8g_vs_list[i].u8g, u8g_vs_list[i].u8g->dev, msg, arg);
}
}
return 1;
case U8G_DEV_MSG_PAGE_FIRST:
u8g_vs_current = 0;
if ( u8g_vs_cnt != 0 )
return u8g_call_dev_fn(u8g_vs_list[u8g_vs_current].u8g, u8g_vs_list[u8g_vs_current].u8g->dev, msg, arg);
return 0;
case U8G_DEV_MSG_PAGE_NEXT:
{
uint8_t ret = 0;
if ( u8g_vs_cnt != 0 )
ret = u8g_call_dev_fn(u8g_vs_list[u8g_vs_current].u8g, u8g_vs_list[u8g_vs_current].u8g->dev, msg, arg);
if ( ret != 0 )
return ret;
u8g_vs_current++; /* next device */
if ( u8g_vs_current >= u8g_vs_cnt ) /* reached end? */
return 0;
return u8g_call_dev_fn(u8g_vs_list[u8g_vs_current].u8g, u8g_vs_list[u8g_vs_current].u8g->dev, U8G_DEV_MSG_PAGE_FIRST, arg);
}
return 0;
case U8G_DEV_MSG_GET_WIDTH:
*((u8g_uint_t *)arg) = u8g_vs_width;
break;
case U8G_DEV_MSG_GET_HEIGHT:
*((u8g_uint_t *)arg) = u8g_vs_height;
break;
case U8G_DEV_MSG_GET_PAGE_BOX:
if ( u8g_vs_current < u8g_vs_cnt )
{
u8g_call_dev_fn(u8g_vs_list[u8g_vs_current].u8g, u8g_vs_list[u8g_vs_current].u8g->dev, msg, arg);
((u8g_box_t *)arg)->x0 += u8g_vs_list[u8g_vs_current].x;
((u8g_box_t *)arg)->x1 += u8g_vs_list[u8g_vs_current].x;
((u8g_box_t *)arg)->y0 += u8g_vs_list[u8g_vs_current].y;
((u8g_box_t *)arg)->y1 += u8g_vs_list[u8g_vs_current].y;
}
else
{
((u8g_box_t *)arg)->x0 = 0;
((u8g_box_t *)arg)->x1 = 0;
((u8g_box_t *)arg)->y0 = 0;
((u8g_box_t *)arg)->y1 = 0;
}
return 1;
case U8G_DEV_MSG_SET_PIXEL:
case U8G_DEV_MSG_SET_8PIXEL:
if ( u8g_vs_current < u8g_vs_cnt )
{
((u8g_dev_arg_pixel_t *)arg)->x -= u8g_vs_list[u8g_vs_current].x;
((u8g_dev_arg_pixel_t *)arg)->y -= u8g_vs_list[u8g_vs_current].y;
return u8g_call_dev_fn(u8g_vs_list[u8g_vs_current].u8g, u8g_vs_list[u8g_vs_current].u8g->dev, msg, arg);
}
break;
}
return 1;
}
u8g_dev_t u8g_dev_vs = { u8g_dev_vs_fn, NULL, NULL };
void u8g_SetVirtualScreenDimension(u8g_t *vs_u8g, u8g_uint_t width, u8g_uint_t height)
{
if ( vs_u8g->dev != &u8g_dev_vs )
return; /* abort if there is no a virtual screen device */
u8g_vs_width = width;
u8g_vs_height = height;
}
uint8_t u8g_AddToVirtualScreen(u8g_t *vs_u8g, u8g_uint_t x, u8g_uint_t y, u8g_t *child_u8g)
{
if ( vs_u8g->dev != &u8g_dev_vs )
return 0; /* abort if there is no a virtual screen device */
if ( u8g_vs_cnt >= U8g_VS_MAX )
return 0; /* maximum number of child u8g's reached */
u8g_vs_list[u8g_vs_cnt].u8g = child_u8g;
u8g_vs_list[u8g_vs_cnt].x = x;
u8g_vs_list[u8g_vs_cnt].y = y;
u8g_vs_cnt++;
return 1;
}
...@@ -5,7 +5,7 @@ MEMORY ...@@ -5,7 +5,7 @@ MEMORY
dport0_0_seg : org = 0x3FF00000, len = 0x10 dport0_0_seg : org = 0x3FF00000, len = 0x10
dram0_0_seg : org = 0x3FFE8000, len = 0x14000 dram0_0_seg : org = 0x3FFE8000, len = 0x14000
iram1_0_seg : org = 0x40100000, len = 0x8000 iram1_0_seg : org = 0x40100000, len = 0x8000
irom0_0_seg : org = 0x40210000, len = 0x54000 irom0_0_seg : org = 0x40210000, len = 0x55000
} }
PHDRS PHDRS
...@@ -72,6 +72,10 @@ SECTIONS ...@@ -72,6 +72,10 @@ SECTIONS
*(.irom0.literal .irom.literal .irom.text.literal .irom0.text .irom.text) *(.irom0.literal .irom.literal .irom.text.literal .irom0.text .irom.text)
*(.literal.* .text.*) *(.literal.* .text.*)
*(.rodata2.text) *(.rodata2.text)
/* put font and progmem data into irom0 */
*(.u8g_progmem.*)
_irom0_text_end = ABSOLUTE(.); _irom0_text_end = ABSOLUTE(.);
_flash_used_end = ABSOLUTE(.); _flash_used_end = ABSOLUTE(.);
} >irom0_0_seg :irom0_0_phdr } >irom0_0_seg :irom0_0_phdr
......
---
-- @description Shows how to read 8 GPIO pins/buttons via I2C with the MCP23008 I/O expander.
-- Tested on NodeMCU 0.9.5 build 20150213.
-- @circuit
-- Connect GPIO0 of the ESP8266-01 module to the SCL pin of the MCP23008.
-- Connect GPIO2 of the ESP8266-01 module to the SDA pin of the MCP23008.
-- Use 3.3V for VCC.
-- Connect switches or buttons to the GPIOs of the MCP23008 and GND.
-- Connect two 4.7k pull-up resistors on SDA and SCL
-- We will enable the internal pull up resistors for the GPIOS of the MCP23008.
-- @author Miguel (AllAboutEE)
-- GitHub: https://github.com/AllAboutEE
-- YouTube: https://www.youtube.com/user/AllAboutEE
-- Website: http://AllAboutEE.com
---------------------------------------------------------------------------------------------
require ("mcp23008")
-- ESP-01 GPIO Mapping as per GPIO Table in https://github.com/nodemcu/nodemcu-firmware
gpio0, gpio2 = 3, 4
-- Setup the MCP23008
mcp23008.begin(0x0,gpio2,gpio0,i2c.SLOW)
mcp23008.writeIODIR(0xff)
mcp23008.writeGPPU(0xff)
---
-- @name showButtons
-- @description Shows the state of each GPIO pin
-- @return void
---------------------------------------------------------
function showButtons()
local gpio = mcp23008.readGPIO() -- read the GPIO/buttons states
-- get/extract the state of one pin at a time
for pin=0,7 do
local pinState = bit.band(bit.rshift(gpio,pin),0x1) -- extract one pin state
-- change to string state (HIGH, LOW) instead of 1 or 0 respectively
if(pinState == mcp23008.HIGH) then
pinState = "HIGH"
else
pinState = "LOW"
end
print("Pin ".. pin .. ": ".. pinState)
end
print("\r\n")
end
tmr.alarm(0,2000,1,showButtons) -- run showButtons() every 2 seconds
---
-- @description Shows control of 8 GPIO pins/LEDs via I2C with the MCP23008 I/O expander.
-- Tested on odeMCU 0.9.5 build 20150213.
-- @date March 02, 2015
-- @circuit Connect 8 LEDs withs resistors to the GPIO pins of the MCP23008.
-- Connect GPIO0 of the ESP8266-01 module to the SCL pin of the MCP23008.
-- Connect GPIO2 of the ESP8266-01 module to the SDA pin of the MCP23008.
-- Connect two 4.7k pull-up resistors on SDA and SCL
-- Use 3.3V for VCC.
-- @author Miguel (AllAboutEE)
-- GitHub: https://github.com/AllAboutEE
-- Working Example Video: https://www.youtube.com/watch?v=KphAJMZZed0
-- Website: http://AllAboutEE.com
---------------------------------------------------------------------------------------------
require ("mcp23008")
-- ESP-01 GPIO Mapping as per GPIO Table in https://github.com/nodemcu/nodemcu-firmware
gpio0, gpio2 = 3, 4
-- Setup MCP23008
mcp23008.begin(0x0,gpio2,gpio0,i2c.SLOW)
mcp23008.writeIODIR(0x00) -- make all GPIO pins as outputs
mcp23008.writeGPIO(0x00) -- make all GIPO pins off/low
---
-- @name count()
-- @description Reads the value from the GPIO register, increases the read value by 1
-- and writes it back so the LEDs will display a binary count up to 255 or 0xFF in hex.
local function count()
local gpio = 0x00
gpio = mcp23008.readGPIO()
if(gpio<0xff) then
mcp23008.writeGPIO(gpio+1)
else
mcp23008.writeGPIO(0x00)
end
end
-- Run count() every 100ms
tmr.alarm(0,100,1,count)
...@@ -29,11 +29,11 @@ function startServer() ...@@ -29,11 +29,11 @@ function startServer()
print("===Now, logon and input LUA.====") print("===Now, logon and input LUA.====")
end end
tmr.alarm(1000, 1, function() tmr.alarm(1, 1000, 1, function()
if wifi.sta.getip()=="0.0.0.0" then if wifi.sta.getip()=="0.0.0.0" then
print("Connect AP, Waiting...") print("Connect AP, Waiting...")
else else
startServer() startServer()
tmr.stop() tmr.stop(1)
end end
end) end)
-- setup I2c and connect display
function init_i2c_display()
sda = 5
scl = 6
sla = 0x3c
i2c.setup(0, sda, scl, i2c.SLOW)
disp = u8g.ssd1306_128x64_i2c(sla)
end
-- graphic test components
function prepare()
disp:setFont(u8g.font_6x10)
disp:setFontRefHeightExtendedText()
disp:setDefaultForegroundColor()
disp:setFontPosTop()
end
function box_frame(a)
disp:drawStr(0, 0, "drawBox")
disp:drawBox(5, 10, 20, 10)
disp:drawBox(10+a, 15, 30, 7)
disp:drawStr(0, 30, "drawFrame")
disp:drawFrame(5, 10+30, 20, 10)
disp:drawFrame(10+a, 15+30, 30, 7)
end
function disc_circle(a)
disp:drawStr(0, 0, "drawDisc")
disp:drawDisc(10, 18, 9)
disp:drawDisc(24+a, 16, 7)
disp:drawStr(0, 30, "drawCircle")
disp:drawCircle(10, 18+30, 9)
disp:drawCircle(24+a, 16+30, 7)
end
function r_frame(a)
disp:drawStr(0, 0, "drawRFrame/Box")
disp:drawRFrame(5, 10, 40, 30, a+1)
disp:drawRBox(50, 10, 25, 40, a+1)
end
function stringtest(a)
disp:drawStr(30+a, 31, " 0")
disp:drawStr90(30, 31+a, " 90")
disp:drawStr180(30-a, 31, " 180")
disp:drawStr270(30, 31-a, " 270")
end
function line(a)
disp:drawStr(0, 0, "drawLine")
disp:drawLine(7+a, 10, 40, 55)
disp:drawLine(7+a*2, 10, 60, 55)
disp:drawLine(7+a*3, 10, 80, 55)
disp:drawLine(7+a*4, 10, 100, 55)
end
function triangle(a)
local offset = a
disp:drawStr(0, 0, "drawTriangle")
disp:drawTriangle(14,7, 45,30, 10,40)
disp:drawTriangle(14+offset,7-offset, 45+offset,30-offset, 57+offset,10-offset)
disp:drawTriangle(57+offset*2,10, 45+offset*2,30, 86+offset*2,53)
disp:drawTriangle(10+offset,40+offset, 45+offset,30+offset, 86+offset,53+offset)
end
function ascii_1()
local x, y, s
disp:drawStr(0, 0, "ASCII page 1")
for y = 0, 5, 1 do
for x = 0, 15, 1 do
s = y*16 + x + 32
disp:drawStr(x*7, y*10+10, string.char(s))
end
end
end
function ascii_2()
local x, y, s
disp:drawStr(0, 0, "ASCII page 2")
for y = 0, 5, 1 do
for x = 0, 15, 1 do
s = y*16 + x + 160
disp:drawStr(x*7, y*10+10, string.char(s))
end
end
end
function extra_page(a)
disp:drawStr(0, 12, "setScale2x2")
disp:setScale2x2()
disp:drawStr(0, 6+a, "setScale2x2")
disp:undoScale()
end
-- the draw() routine
function draw(draw_state)
local component = bit.rshift(draw_state, 3)
prepare()
if (component == 0) then
box_frame(bit.band(draw_state, 7))
elseif (component == 1) then
disc_circle(bit.band(draw_state, 7))
elseif (component == 2) then
r_frame(bit.band(draw_state, 7))
elseif (component == 3) then
stringtest(bit.band(draw_state, 7))
elseif (component == 4) then
line(bit.band(draw_state, 7))
elseif (component == 5) then
triangle(bit.band(draw_state, 7))
elseif (component == 6) then
ascii_1()
elseif (component == 7) then
ascii_2()
elseif (component == 8) then
extra_page(bit.band(draw_state, 7))
end
end
function graphics_test()
init_i2c_display()
print("--- Starting Graphics Test ---")
-- cycle through all components
local draw_state
for draw_state = 0, 7 + 8*8, 1 do
disp:firstPage()
repeat
draw(draw_state)
until disp:nextPage() == false
--print(node.heap())
-- re-trigger Watchdog!
tmr.wdclr()
end
print("--- Graphics Test done ---")
end
graphics_test()
-- setup I2c and connect display
function init_i2c_display()
sda = 5
scl = 6
sla = 0x3c
i2c.setup(0, sda, scl, i2c.SLOW)
disp = u8g.ssd1306_128x64_i2c(sla)
end
-- the draw() routine
function draw()
disp:setFont(u8g.font_6x10)
disp:drawStr( 0+0, 20+0, "Hello!")
disp:drawStr( 0+2, 20+16, "Hello!")
disp:drawBox(0, 0, 3, 3)
disp:drawBox(disp:getWidth()-6, 0, 6, 6)
disp:drawBox(disp:getWidth()-9, disp:getHeight()-9, 9, 9)
disp:drawBox(0, disp:getHeight()-12, 12, 12)
end
function rotate()
if (next_rotation < tmr.now() / 1000) then
if (dir == 0) then
disp:undoRotation()
elseif (dir == 1) then
disp:setRot90()
elseif (dir == 2) then
disp:setRot180()
elseif (dir == 3) then
disp:setRot270()
end
dir = dir + 1
dir = bit.band(dir, 3)
next_rotation = tmr.now() / 1000 + 1000
end
end
function rotation_test()
init_i2c_display()
print("--- Starting Rotation Test ---")
dir = 0
next_rotation = 0
local loopcnt
for loopcnt = 1, 100, 1 do
rotate()
disp:firstPage()
repeat
draw(draw_state)
until disp:nextPage() == false
tmr.wdclr()
end
print("--- Rotation Test done ---")
end
rotation_test()
...@@ -62,17 +62,17 @@ function M.read(pin) ...@@ -62,17 +62,17 @@ function M.read(pin)
--DHT data acquired, process. --DHT data acquired, process.
for i = 1, 16, 1 do for i = 1, 16, 1 do
if (bitStream[i] > 4) then if (bitStream[i] > 3) then
humidity = humidity + 2 ^ (16 - i) humidity = humidity + 2 ^ (16 - i)
end end
end end
for i = 1, 16, 1 do for i = 1, 16, 1 do
if (bitStream[i + 16] > 4) then if (bitStream[i + 16] > 3) then
temperature = temperature + 2 ^ (16 - i) temperature = temperature + 2 ^ (16 - i)
end end
end end
for i = 1, 8, 1 do for i = 1, 8, 1 do
if (bitStream[i + 32] > 4) then if (bitStream[i + 32] > 3) then
checksum = checksum + 2 ^ (8 - i) checksum = checksum + 2 ^ (8 - i)
end end
end end
......
---
-- @description Expands the ESP8266's GPIO to 8 more I/O pins via I2C with the MCP23008 I/O Expander
-- MCP23008 Datasheet: http://ww1.microchip.com/downloads/en/DeviceDoc/21919e.pdf
-- Tested on NodeMCU 0.9.5 build 20150213.
-- @date March 02, 2015
-- @author Miguel
-- GitHub: https://github.com/AllAboutEE
-- YouTube: https://www.youtube.com/user/AllAboutEE
-- Website: http://AllAboutEE.com
--------------------------------------------------------------------------------
local moduleName = ...
local M = {}
_G[moduleName] = M
-- Constant device address.
local MCP23008_ADDRESS = 0x20
-- Registers' address as defined in the MCP23008's datashseet
local MCP23008_IODIR = 0x00
local MCP23008_IPOL = 0x01
local MCP23008_GPINTEN = 0x02
local MCP23008_DEFVAL = 0x03
local MCP23008_INTCON = 0x04
local MCP23008_IOCON = 0x05
local MCP23008_GPPU = 0x06
local MCP23008_INTF = 0x07
local MCP23008_INTCAP = 0x08
local MCP23008_GPIO = 0x09
local MCP23008_OLAT = 0x0A
-- Default value for i2c communication
local id = 0
-- pin modes for I/O direction
M.INPUT = 1
M.OUTPUT = 0
-- pin states for I/O i.e. on/off
M.HIGH = 1
M.LOW = 0
-- Weak pull-up resistor state
M.ENABLE = 1
M.DISABLE = 0
---
-- @name write
-- @description Writes one byte to a register
-- @param registerAddress The register where we'll write data
-- @param data The data to write to the register
-- @return void
----------------------------------------------------------
local function write(registerAddress, data)
i2c.start(id)
i2c.address(id,MCP23008_ADDRESS,i2c.TRANSMITTER) -- send MCP's address and write bit
i2c.write(id,registerAddress)
i2c.write(id,data)
i2c.stop(id)
end
---
-- @name read
-- @description Reads the value of a regsiter
-- @param registerAddress The reigster address from which to read
-- @return The byte stored in the register
----------------------------------------------------------
local function read(registerAddress)
-- Tell the MCP which register you want to read from
i2c.start(id)
i2c.address(id,MCP23008_ADDRESS,i2c.TRANSMITTER) -- send MCP's address and write bit
i2c.write(id,registerAddress)
i2c.stop(id)
i2c.start(id)
-- Read the data form the register
i2c.address(id,MCP23008_ADDRESS,i2c.RECEIVER) -- send the MCP's address and read bit
local data = 0x00
data = i2c.read(id,1) -- we expect only one byte of data
i2c.stop(id)
return string.byte(data) -- i2c.read returns a string so we convert to it's int value
end
---
--! @name begin
--! @description Sets the MCP23008 device address's last three bits.
-- Note: The address is defined as binary 0100[A2][A1][A0] where
-- A2, A1, and A0 are defined by the connection of the pins,
-- e.g. if the pins are connected all to GND then the paramter address
-- will need to be 0x0.
-- @param address The 3 least significant bits (LSB) of the address
-- @param pinSDA The pin to use for SDA
-- @param pinSCL The pin to use for SCL
-- @param speed The speed of the I2C signal
-- @return void
---------------------------------------------------------------------------
function M.begin(address,pinSDA,pinSCL,speed)
MCP23008_ADDRESS = bit.bor(MCP23008_ADDRESS,address)
i2c.setup(id,pinSDA,pinSCL,speed)
end
---
-- @name writeGPIO
-- @description Writes a byte of data to the GPIO register
-- @param dataByte The byte of data to write
-- @return void
----------------------------------------------------------
function M.writeGPIO(dataByte)
write(MCP23008_GPIO,dataByte)
end
---
-- @name readGPIO
-- @description reads a byte of data from the GPIO register
-- @return One byte of data
----------------------------------------------------------
function M.readGPIO()
return read(MCP23008_GPIO)
end
---
-- @name writeIODIR
-- @description Writes one byte of data to the IODIR register
-- @param dataByte The byte of data to write
-- @return void
----------------------------------------------------------
function M.writeIODIR(dataByte)
write(MCP23008_IODIR,dataByte)
end
---
-- @name readIODIR
-- @description Reads a byte from the IODIR register
-- @return The byte of data in IODIR
----------------------------------------------------------
function M.readIODIR()
return read(MCP23008_IODIR)
end
---
-- @name writeGPPU The byte to write to the GPPU
-- @description Writes a byte of data to the
-- PULL-UP RESISTOR CONFIGURATION (GPPU)REGISTER
-- @param databyte the value to write to the GPPU register.
-- each bit in this byte is assigned to an individual GPIO pin
-- @return void
----------------------------------------------------------------
function M.writeGPPU(dataByte)
write(MCP23008_GPPU,dataByte)
end
---
-- @name readGPPU
-- @description Reads the GPPU (Pull-UP resistors register) byte
-- @return The GPPU byte i.e. state of all internal pull-up resistors
-------------------------------------------------------------------
function M.readGPPU()
return read(MCP23008_GPPU)
end
return M
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment