Skip to content

Commit

Permalink
Small PWM value (tank), source code optimalization
Browse files Browse the repository at this point in the history
  • Loading branch information
pgillich committed Oct 30, 2016
1 parent 7d5ad7c commit 1ea9d78
Show file tree
Hide file tree
Showing 8 changed files with 392 additions and 364 deletions.
19 changes: 17 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ Supported Scratch commands:
- [x] `digital read pin` (`digitalRead`): NodeMCU command(s): `gpio.read`
- [x] `analog read pin` (`analogRead`): NodeMCU command(s): `adc.read` or custom sensor command
- [x] ![Stop](doc/stop-sign-small.png) (`reset_all`): Reset state machine, NodeMCU command(s): `gpio.write`, `pwm.setduty`
- [x] (`poll`): return cached values of `digitalRead`, `analogRead`
- [x] `poll`: return cached values of `digitalRead`, `analogRead`
- [ ] Simplified Block commands

Bridge Features:
Expand All @@ -141,6 +141,7 @@ Controller Features:
- [x] `tankWrite`: transforms a joystick XY value pair ([-100,+100], [-100,+100]) to A-B pins of H-bridge for 2 DC motor
- [x] `getName`: returns Bridge name
- [ ] Too small PWM value is overwritten to 0 (for DC motors)
- [x] Too small PWM value is overwritten to 0 (for tank)
- [x] WiFi station and AP mode
- [x] MAC-based configuration
- [x] Configuration for more networks
Expand All @@ -155,10 +156,23 @@ Controller Features:
- [ ] DHT sensor support
- [ ] BMP180 sensor support

## Device and Sensor Extensions

### HC-SR04

Original source from: [node_hcsr04](https://github.com/sza2/node_hcsr04). Main change: replacing tmr.delay to tmr.alert. Optimized for [WeMos D1 mini](http://www.wemos.cc/Products/d1_mini.html). Sensor pins:
- ECHO: D8 (GPIO15) pulled down by 10k (R2) on WeMos D1 mini. R1 between ECHO and D8 as voltage divider: 4k7, see more:
[HC-SR04 Ultrasonic Range Sensor on the Raspberry Pi](http://www.modmypi.com/blog/hc-sr04-ultrasonic-range-sensor-on-the-raspberry-pi)
- TRIG: D0 (GPIO16). Can only be used as gpio read/write. No support for open-drain/interrupt/pwm/i2c/ow.
- VCC: 5V
- GND: G

Trig time: min. 10 us. Max echo time: 38 ms. Usage: `dofile("hcsr.lua") device=hcsr.init() device.start()`, automatically called by `init.lua`, if `devices["hcsr"]` in `config.lua` is set properly.

# Installation and Configuration

## Getting Repository
Clone or download and extract repository from GitHub. Please read [LICENSE](LICENSE).
Clone or download and extract repository from GitHub. Please read [LICENSE](LICENSE), TOC is created by [gh-md-toc](https://github.com/ekalinin/github-markdown-toc).

## Wiring
[WeMos D1 mini](http://www.wemos.cc/Products/d1_mini.html) system has some additional resistors and dedicated pins for shields. These constraints determine a logical pinout:
Expand Down Expand Up @@ -280,6 +294,7 @@ Blocks for full functionality looks too complex for young children. Simplified b
* Only one Controller is supported.
* Pin groups must be named for group operations (for example: `analogPairWrite`, `tankWrite`).
* Waiting for next command (`W`) is not supported.

With this limitations, each student can handle own named Controller.

### First steps
Expand Down
1 change: 1 addition & 0 deletions lua/.gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.lua linguist-language=Lua
240 changes: 240 additions & 0 deletions lua/command.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,240 @@
-- This file is part of ESP4S2. ESP4S2 is a bridge between MIT Scratch 2 and ESP8266 Lua.
-- Copyright (C) 2016 pgillich, under GPLv3 license.

function change2mode(pin,mode,oldMode)
if mode~=oldMode then
if oldMode==MODE_PWM then
pwmStop(pin)
end

if mode==MODE_INPUT then
gpioMode(pin, gpio.INPUT)
elseif mode==MODE_OUTPUT then
gpioMode(pin, gpio.OUTPUT)
elseif mode==MODE_PWM then
pwmStart(pin)
else
print("ERR: unknown mode, "..tostring(mode))
end
end
end

function change2value(pin,mode,val,oldVal)
if mode==MODE_OUTPUT then
gpioWrite(pin,val)
elseif mode==MODE_PWM then
pwmSetduty(pin,val)
else
print("ERR: unknown mode, "..tostring(mode))
end
end

function pinMode(pin,mode)
local resp=""
if type(PINS_state[pin])~=nil and type(PIN_MODES[mode])~=nil then
print(" pinMode("..tostring(pin)..","..tostring(mode)..")")
change2mode(pin,mode,PINS_state[pin]["m"])
PINS_state[pin]["m"]=mode
end
return resp
end

function digitalWrite(pin,val)
local resp=""
if type(PINS_state[pin])~=nil and PINS_state[pin]["m"]==MODE_OUTPUT then
if val==0 or val==1 then
print(" digitalWrite("..tostring(pin)..","..tostring(val)..")")
change2value(pin, PINS_state[pin]["m"], val, PINS_state[pin]["v"])
PINS_state[pin]["v"]=val
end
else
print("ERR: invalid digitalWrite("..tostring(pin)..","..tostring(val)..")")
end
return resp
end

function analogWrite(pin,val)
local resp=""
if type(PINS_state[pin])~=nil and PINS_state[pin]["m"]==MODE_PWM then
if val>=0 and val<=100 then
print(" analogWrite("..tostring(pin)..","..tostring(val)..")")
change2value(pin, PINS_state[pin]["m"], val, PINS_state[pin]["v"])
PINS_state[pin]["v"]=val
end
else
print("ERR: invalid analogWrite("..tostring(pin)..","..tostring(val)..")")
end
return resp
end

function analogPairWrite(pin1,pin2,val)
local resp=""
if val>0 then
resp=resp..analogWrite(pin1,val)
resp=resp..analogWrite(pin2,0)
elseif val<0 then
resp=resp..analogWrite(pin1,0)
resp=resp..analogWrite(pin2,0-val)
else
resp=resp..analogWrite(pin1,0)
resp=resp..analogWrite(pin2,0)
end
return resp
end

function limitVmin(v,v_min)
if 0<v and v<v_min then
return 0
elseif -v_min<v and v<0 then
return 0
end
return v
end

function tankWrite(pin1,pin2,pin3,pin4,x,y)
x=x+(config.tank.x_corr or 0)
y=y+(config.tank.y_corr or 0)
local resp=""
local idx=""
if y>=0 then
idx=idx.."T"
else
idx=idx.."B"
end
if x>=0 then
idx=idx.."R"
else
idx=idx.."L"
end
local T=TANK_CONST[idx.."A"]
local v=(T.d*x*y+T.a*x+T.b*y+T.c)/100
v=limitVmin(v,config.tank.v_min or 0)
resp=resp..analogPairWrite(pin1,pin2,v)
T=TANK_CONST[idx.."B"]
v=(T.d*x*y+T.a*x+T.b*y+T.c)/100
v=limitVmin(v,config.tank.v_min or 0)
resp=resp..analogPairWrite(pin3,pin4,v)
return resp
end

function resetAll()
local resp=""
for pin,mv in pairs(PINS_state) do
local m=mv["m"]
local v=mv["v"]
if type(m)~=nil then
if m==MODE_OUTPUT then
resp=resp..digitalWrite(pin,0)
elseif m==MODE_PWM then
resp=resp..analogWrite(pin,0)
end
end
end
return resp
end

function getName()
return "name "..config.name
end

function getValue(pin)
if type(PINS_state[pin])~=nil then
if pin==0 and PINS_state[pin]["m"]==MODE_ANALOG then
return adcRead(pin)
elseif PINS_state[pin]["m"]==MODE_ANALOG then
readDevices()
return PINS_state[pin]["v"]
elseif PINS_state[pin]["m"]==MODE_INPUT then
return gpioRead(pin)
end
end
return -1
end

function poll()
local data=""
readDevices()
for pin,mv in pairs(PINS_state) do
local m=mv["m"]
local v=mv["v"]
if type(m)~=nil and (m==MODE_INPUT or m==MODE_ANALOG) then
if string.len(data)>0 then
data=data.."\n"
end
data=data..tostring(pin).." "..tostring(v)
end
end
return data
end

function csplit(str,sep)
local ret={}
local n=1
for w in str:gmatch("([^"..sep.."]*)") do
ret[n]=ret[n] or w
if w=="" then n=n+1 end
end
return ret
end

function exeCmd(st)
local resp=""
print("> "..st)
local command=csplit(st," ")
if #command>1 then
if config.name==command[1] then
table.remove(command,1)
else
for m,cfg in pairs(MAC_config[WIFI_CFG_NAME]) do
if cfg.name==command[1] then
return resp
end
end
end
end
if #command==1 then
local cmd=command[1]
if cmd=="reset_all" then
resp=resetAll()
elseif cmd=="getName" then
resp=getName()
elseif cmd=="poll" then
resp=poll()
end
elseif #command==2 then
local cmd=command[1]
local pin=tonumber(command[2])
if cmd=="digitalRead" then
resp=tostring(pin).." "..tostring(getValue(pin))
elseif cmd=="analogRead" then
resp=tostring(pin).." "..tostring(getValue(pin))
end
elseif #command==3 then
local cmd=command[1]
local pin=tonumber(command[2])
local val=tonumber(command[3])
if cmd=="pinMode" then
resp=pinMode(pin,val)
elseif cmd=="digitalWrite" then
resp=digitalWrite(pin,val)
elseif cmd=="analogWrite" then
resp=analogWrite(pin,val)
end
elseif #command==4 then
local cmd=command[1]
local pin1=tonumber(command[2])
local pin2=tonumber(command[3])
local val=tonumber(command[4])
if cmd=="analogPairWrite" then
resp=analogPairWrite(pin1,pin2,val)
end
elseif #command==7 then
local cmd=command[1]
if cmd=="tankWrite" then
resp=tankWrite(tonumber(command[2]),tonumber(command[3]),tonumber(command[4]),tonumber(command[5]),tonumber(command[6]),tonumber(command[7]))
end
else
print("ERR: unknown command")
end
return resp
end
40 changes: 40 additions & 0 deletions lua/command_const.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
MODE_UNAVAILABLE=-1
MODE_INPUT=0
MODE_OUTPUT=1
MODE_ANALOG=2
MODE_PWM=3
MODE_SERVO=4

PIN_MODES={
[MODE_UNAVAILABLE]="UNAVAILABLE",
[MODE_INPUT]="INPUT",
[MODE_OUTPUT]="OUTPUT",
[MODE_ANALOG]="ANALOG",
[MODE_PWM]="PWM",
[MODE_SERVO]="SERVO"
}

PINS_state={
[0]={m=-1,v=-1},
[1]={m=-1,v=-1},
[2]={m=-1,v=-1},
[3]={m=-1,v=-1},
[4]={m=-1,v=-1},
[5]={m=-1,v=-1},
[6]={m=-1,v=-1},
[7]={m=-1,v=-1},
[8]={m=-1,v=-1},
[11]={m=-1,v=-1},
[12]={m=-1,v=-1},
}

TANK_CONST={
["TLA"]={a=-100,b=100,c=0,d=1},
["TLB"]={a=100,b=100,c=0,d=0},
["TRA"]={a=-100,b=100,c=0,d=0},
["TRB"]={a=100,b=100,c=0,d=-1},
["BLA"]={a=-100,b=100,c=0,d=0},
["BLB"]={a=100,b=100,c=0,d=1},
["BRA"]={a=-100,b=100,c=0,d=-1},
["BRB"]={a=100,b=100,c=0,d=0}
}
14 changes: 9 additions & 5 deletions lua/config.lua.example
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
WIFI_CFG_NAME="Home"
WIFI_CFG_NAME="Demo"

ROBOREMO_PORT=9876

Expand All @@ -10,15 +10,17 @@ MAC_config={
static_ip=false,
net_type=net.UDP,
listen={port=ROBOREMO_PORT},
devices={["hcsr"]={["absorber"]=2,["tmr_ms"]=500}}
devices={["hcsr"]={["absorber"]=2,["tmr_ms"]=500}},
tank={},
},
["18fe34d40583"]={name="tank-chassis",
wifiMode=wifi.STATION,
ip="192.168.10.103",
static_ip=false,
net_type=net.UDP,
listen={port=ROBOREMO_PORT},
devices={}
devices={},
tank={},
}
},
["Demo"]={
Expand All @@ -29,7 +31,8 @@ MAC_config={
netmask="255.255.255.0",
net_type=net.UDP,
listen={port=ROBOREMO_PORT},
devices={}
devices={},
tank={},
},
["18fe34d40583"]={name="tank-chassis",
wifiMode=wifi.SOFTAP,
Expand All @@ -38,7 +41,8 @@ MAC_config={
netmask="255.255.255.0",
net_type=net.UDP,
listen={port=ROBOREMO_PORT},
devices={}
devices={},
tank={x_corr=-100,y_corr=-100,v_min=40},
}
}
}
Loading

0 comments on commit 1ea9d78

Please sign in to comment.