diff --git a/examples/tutorial/ConvertXPM.sh b/examples/tutorial/ConvertXPM.sh new file mode 100644 index 0000000..b65416c --- /dev/null +++ b/examples/tutorial/ConvertXPM.sh @@ -0,0 +1 @@ +mogrify -format png -rotate 270 -scale 200% *.xpm diff --git a/examples/tutorial/pbLuaAdvancedMotors.lua b/examples/tutorial/pbLuaAdvancedMotors.lua new file mode 100644 index 0000000..ae4d896 --- /dev/null +++ b/examples/tutorial/pbLuaAdvancedMotors.lua @@ -0,0 +1,56 @@ +-- This is the example code file for the webpage at: +-- +-- www.hempeldesigngroup.com/lego/pbLua/tutorial/pbLuaAdvancedMotors.html + +--codeExampleStart 1 ----------------------------------------------------------- +-- Read tachos until the orange button is pressed +function TachoRead(port) + + repeat + if 4 == nxt.ButtonRead() then + nxt.OutputResetTacho(port,1,0,0) + elseif 2 == nxt.ButtonRead() then + nxt.OutputResetTacho(port,0,0,1) + elseif 1 == nxt.ButtonRead() then + nxt.OutputResetTacho(port,0,1,0) + end + + print( nxt.TimerRead(), nxt.OutputGetStatus(port) ) + + t = nxt.TimerRead() + while t+100 > nxt.TimerRead() do + -- nothing + end + until( 8 == nxt.ButtonRead() ) +end + +-- And using the function with a motor plugged into port A... +TachoRead(1) +--codeExampleEnd 1 + +--codeExampleStart 2 ----------------------------------------------------------- +-- Turn Motor 1 exactly 180 degrees at half speed +port = 1 +nxt.OutputSetRegulation(port,1,1) +nxt.OutputSetSpeed(port,0x20,50,180) +--codeExampleEnd 2 + +--codeExampleStart 3 ----------------------------------------------------------- +-- Turn Motor 1 exactly 180 degrees - and wait until done +port = 1 +function move(degrees) + nxt.OutputSetRegulation(port,1,1) + + _,tacho = nxt.OutputGetStatus(port) + nxt.OutputSetSpeed(port,0x20,nxt.sign(degrees)*50,nxt.abs(degrees)) + + repeat + _,curtacho = nxt.OutputGetStatus(port) + until 4 > nxt.abs( curtacho - (tacho + degrees) ) +end +--codeExampleEnd 3 + +--codeExampleStart n ----------------------------------------------------------- +--codeExampleEnd n + + diff --git a/examples/tutorial/pbLuaBasicMotors.lua b/examples/tutorial/pbLuaBasicMotors.lua new file mode 100644 index 0000000..44b1053 --- /dev/null +++ b/examples/tutorial/pbLuaBasicMotors.lua @@ -0,0 +1,248 @@ +-- This is the example code file for the webpage at: +-- +-- www.hempeldesigngroup.com/lego/pbLua/tutorial/pbLuaBasicMotors.html + +--codeExampleStart 1 ----------------------------------------------------------- +-- Read motor port until the orange button is pressed +function MotorRead(port) + + repeat + print( nxt.TimerRead(), nxt.OutputGetStatus(port) ) + until( 8 == nxt.ButtonRead() ) +end + +-- And using the function with a motor plugged into port A... +MotorRead(1) +--codeExampleEnd 1 + +--codeExampleStart 2 ----------------------------------------------------------- +-- Read motor port until the orange button is pressed +-- Left arrow decreases speed +-- Right arrow increases speed +function MotorSpeed(port) + local speed = 0 + + repeat + if 4 == nxt.ButtonRead() then + if speed >= -95 then + speed = speed - 5 + nxt.OutputSetSpeed( port, 32, speed ) + end + end + + if 2 == nxt.ButtonRead() then + if speed <= 95 then + speed = speed + 5 + nxt.OutputSetSpeed( port, 32, speed ) + end + end + + print( nxt.TimerRead(), nxt.OutputGetStatus(port) ) + until( 8 == nxt.ButtonRead() ) + + -- Remember to turn the motor off! + nxt.OutputSetSpeed( port, 0, 0 ) +end + +-- And using the function with a motor plugged into port A... +MotorSpeed(1) +--codeExampleEnd 2 + +--codeExampleStart 3 ----------------------------------------------------------- +-- Read motor port until the orange button is pressed +-- Left arrow decreases speed +-- Right arrow increases speed +function MotorSpeed(port) + local speed = 0 + local oldButton = 0 + local newButton = 0 + + repeat + newButton = nxt.ButtonRead() + + if 0 == oldButton then + -- Only check buttons if no buttons are pressed! + + if 4 == newButton then + if speed >= -95 then + speed = speed - 5 + nxt.OutputSetSpeed( port, 32, speed ) + end + end + + if 2 == newButton then + if speed <= 95 then + speed = speed + 5 + nxt.OutputSetSpeed( port, 32, speed ) + end + end + end + + oldButton = newButton + + print( nxt.TimerRead(), nxt.OutputGetStatus(port) ) + + until( 8 == newButton ) + + -- Remember to turn the motor off! + nxt.OutputSetSpeed( port, 0, 0 ) +end +-- And using the function with a motor plugged into port A... +MotorSpeed(1) +--codeExampleEnd 3 + +--codeExampleStart 4 ----------------------------------------------------------- +-- Read motor port until the orange button is pressed +-- Left arrow decreases speed +-- Right arrow increases speed + +function MotorSpeed(port, state, mode ) + local speed = 0 + local oldButton = 0 + local newButton = 0 + + nxt.OutputSetRegulation( port, state, mode ) + + repeat + newButton = nxt.ButtonRead() + + if 0 == oldButton then + if 4 == newButton then + if speed >= -95 then + speed = speed - 5 + nxt.OutputSetSpeed( port, 32, speed ) + end + end + + if 2 == newButton then + if speed <= 95 then + speed = speed + 5 + nxt.OutputSetSpeed( port, 32, speed ) + end + end + end + + oldButton = newButton + + print( nxt.TimerRead(), nxt.OutputGetStatus(port), nxt.HeapInfo() ) + until( 8 == newButton ) + + -- Remember to turn the motor off! + nxt.OutputSetSpeed( port, 0, 0 ) +end + +-- Now try it out with regulation in float mode... +MotorSpeed( 1, 1, 0 ) + +-- Now try it out with regulation in brake mode... +MotorSpeed( 1, 1, 1 ) + +-- And with no regulation at all... +MotorSpeed( 1, 0, 0 ) +--codeExampleEnd 4 + +--codeExampleStart 5 ----------------------------------------------------------- +-- Line Follower! +function LineFollow(target,delay,n) + local port = 1 + + nxt.InputSetType(port,5) + + nxt.OutputSetRegulation(1,1,1) + nxt.OutputSetRegulation(3,1,1) + + local idx = 1 + local speed = 0; + + -- initialize the raw array to "grey" + local raw = {} + for i=1,n do + raw[i] = target + end + + repeat + t = nxt.TimerRead() + while t+delay > nxt.TimerRead() do + -- nothing + end + + -- get a new raw reading + raw[(idx%n)+1] = nxt.InputGetStatus(port) + + -- calculate the average + local sum = 0 + for i=1,n do + sum = sum + raw[n] + end + + local avg = sum/n + + print( avg ) + + if avg > target then + speed = 20 + ((avg - target)/2) + if speed > 50 then speed = 50 end + + nxt.OutputSetSpeed(1,0x20,20) + nxt.OutputSetSpeed(3,0x20,speed) + else + speed = 20 + ((target - avg)/2) + if speed > 50 then speed = 50 end + + nxt.OutputSetSpeed(1,0x20,speed) + nxt.OutputSetSpeed(3,0x20,20) + end + + idx = idx + 1 + until( 8 == nxt.ButtonRead() ) + + nxt.OutputSetSpeed(1,0,0) + nxt.OutputSetSpeed(3,0,0) + nxt.InputSetState(port,0,0) +end + +-- And using the function - press the orange button on the NXT to stop it +LineFollow(760,780) +--codeExampleEnd 5 + +--codeExampleStart 6 ----------------------------------------------------------- +-- Sync Motors B (I) and C (II) - the speed is s and the difference is t + +function MotorSync(s,t) + + nxt.OutputResetTacho(2,1,1,1) + nxt.OutputResetTacho(3,1,1,1) + + nxt.OutputSetRegulation(2,2,1) + nxt.OutputSetRegulation(3,2,1) + + nxt.DisableNXT( 1 ); + nxt.OutputSetSpeed(2,0x20,s, 0, t ) + nxt.OutputSetSpeed(3,0x20,s, 0, t ) + nxt.DisableNXT( 0 ); + + repeat + until( 8 == nxt.ButtonRead() ) + + nxt.OutputSetSpeed(2) + nxt.OutputSetSpeed(3) +end +-- And using the function - press the orange button on the NXT to stop it + +-- Motor I and II try to stay sunchronized +MotorSync(75,0) + +-- Motor I turns a bit slower than Motor I +MotorSync(75,20) + +-- Motor I stops - all power goes to Motor I +MotorSync(75,50) + +-- Motor I turns a bit slower than Motor 1 - in the opposite direction +MotorSync(75,60) +--codeExampleEnd 6 + +--codeExampleStart n ----------------------------------------------------------- +--codeExampleEnd n + + diff --git a/examples/tutorial/pbLuaBlueToothRemote.lua b/examples/tutorial/pbLuaBlueToothRemote.lua new file mode 100644 index 0000000..59b37a7 --- /dev/null +++ b/examples/tutorial/pbLuaBlueToothRemote.lua @@ -0,0 +1,285 @@ +-- This is the example code file for the webpage at: +-- +-- www.hempeldesigngroup.com/lego/pbLua/tutorial/pbLuaBlueToothRemote.html + +--codeExampleStart 1 ----------------------------------------------------------- +-- Turn the Bluetooth radio on: +nxt.BtPower(1) +--codeExampleEnd 1 + +--codeExampleStart 1a ----------------------------------------------------------- +-- make the NXT visible for Bluetooth searches: +nxt.BtVisible(1) +--codeExampleEnd 1a +-- +--codeExampleStart 2 ----------------------------------------------------------- +-- Reset the Bluetooth subsystem to factory defaults. Note theat this does +-- not reset the firmware, just the device tables. +nxt.BtFactoryReset() +--codeExampleEnd 2 + +--codeExampleStart 3 ----------------------------------------------------------- +-- Change the name of the NXT +nxt.BtSetName("LEFTY") +--codeExampleEnd 3 + +--codeExampleStart 4 ----------------------------------------------------------- +-- Enter the PIN code for your NXT +nxt.BtSetPIN("5551212") +--codeExampleEnd 4 + + +--codeExampleStart 12 ----------------------------------------------------------- +-- Dump the first 4 entries in the device table +btDevice(4) + +-- Results are below, do not paste the following text to the console! +Name: DELLD610 Addr:00:10:c6:62:f6:ba Class:00:02:01:04 Status:2 +Name: BT GPS V10 Addr:00:0a:3a:24:33:97 Class:00:00:1f:00 Status:130 +Name: Addr:00:00:00:00:00:00 Class:00:00:00:00 Status:0 +Name: Addr:00:00:00:00:00:00 Class:00:00:00:00 Status:0 +--codeExampleEnd 12 + +--codeExampleStart 13 ----------------------------------------------------------- +-- Search for the NXT +nxt.BtSearch(1) -- This takes about 20 seconds! +--codeExampleEnd 13 + +--codeExampleStart 14 ----------------------------------------------------------- +-- Dump the first 4 entries in the device table +btDevice(4) + +-- Results are below, do not paste the following text to the console! +Name: DELLD610 Addr:00:10:c6:62:f6:ba Class:00:02:01:04 Status:66 +Name: BT GPS V10 Addr:00:0a:3a:24:33:97 Class:00:00:1f:00 Status:130 +Name: LEFTY Addr:00:16:53:09:f7:59 Class:00:00:08:04 Status:130 +Name: RIGHTY Addr:00:16:53:09:f9:26 Class:00:00:08:04 Status:65 +--codeExampleEnd 14 + +--codeExampleStart 15 ----------------------------------------------------------- +-- Start the connection on CONTROL between channel 1 and device 3 (RIGHTY) +nxt.BtConnect(1,3) + +-- Wait 5 seconds before entering the PIN on CONTROL +nxt.BtSetPIN("5551212") + +-- Now enter the PIN on RIGHTY +nxt.BtSetPIN("5551212") +--codeExampleEnd 15 + +--codeExampleStart 16 ----------------------------------------------------------- +-- Check the connection table on CONTROL +btConnect() + +-- Results are below, do not paste the following text to the console! +Name: Addr:00:00:00:00:00:00 Class:00:00:00:00 PIN: Status:0 +Name: RIGHTY Addr:00:16:53:09:f9:26 Class:00:00:08:04 PIN:5551212 Status:0 +Name: Addr:00:00:00:00:00:00 Class:00:00:00:00 PIN: Status:0 +Name: Addr:00:00:00:00:00:00 Class:00:00:00:00 PIN: Status:0 +--codeExampleEnd 16 + +--codeExampleStart 17 ----------------------------------------------------------- +-- Check the device table on CONTROL +btDevice(4) + +-- Results are below, do not paste the following text to the console! +Name: DELLD610 Addr:00:10:c6:62:f6:ba Class:00:02:01:04 Status:2 +Name: BT GPS V10 Addr:00:0a:3a:24:33:97 Class:00:00:1f:00 Status:2 +Name: LEFTY Addr:00:16:53:09:f7:59 Class:00:00:08:04 Status:2 +Name: RIGHTY Addr:00:16:53:09:f9:26 Class:00:00:08:04 Status:2 +--codeExampleEnd 17 + +--codeExampleStart 18 ----------------------------------------------------------- +-- Sit in a loop and spit out anything from the Bluetooth radio to the +-- console...copy this to LEFTY and RIGHT + +function BtListen() + -- Make sure we're reading the raw stream, not NXT messages + nxt.BtStreamMode(1) + + -- Spin in a loop and echo any data we get until the big + -- orange button is pressed. + repeat + s = nxt.BtStreamRecv() + if s then + print( s ) + end + until( 8 == nxt.ButtonRead() ) +end +--codeExampleEnd 18 + +--codeExampleStart 19 ----------------------------------------------------------- +-- A little piece of code to wait until the BT system is idle... +function BtIdleWait() + local active + repeat + _,active = nxt.BtGetStatus() + until 17 == active +end + +-- Set up the connection to LEFTY on channel 1 and device 2 (your device +-- number may be different! +nxt.BtConnect(1,2) + +-- Wait until idle +BtIdleWait() + +-- Set up the connection to RIGHTY on channel 2 and device 3 (your device +-- number may be different! +nxt.BtConnect(2,3) +--codeExampleEnd 19 + +--codeExampleStart 20 ----------------------------------------------------------- +function BtStream() + -- Make sure we're reading the raw stream, not NXT messages + nxt.BtStreamMode(1) + + local i = 0 + + repeat + nxt.BtStreamSend(1,"LEFTY" .. i) + nxt.BtStreamSend(2,"RIGHTY" .. i) + i = i+1 + until( 8 == nxt.ButtonRead() ) +end +--codeExampleEnd 20 + +--codeExampleStart 21 ----------------------------------------------------------- +-- Start listening on LEFTY by typing this in the LEFTY console: +BtListen() + +-- Start listening on RIGHTY by typing this in the RIGHTY console: +BtListen() + +-- Start streaming by typing this in the CONTROL console: +BtStream() +--codeExampleEnd 21 + +--codeExampleStart 22 ----------------------------------------------------------- +-- Copy the BtListen() function into FLASH on LEFTY and RIGHTY and run +-- it at startup + +-- Create the program as an extended string... +s = [[ +function BtListen() + -- Make sure we're reading the raw stream, not NXT messages + nxt.BtStreamMode(1) + + -- Spin in a loop and echo any data we get until the big + -- orange button is pressed. + repeat + s = nxt.BtStreamRecv() + if s then + nxt.DisplayScroll() + nxt.DisplayText(s) + end + until( 8 == nxt.ButtonRead() ) +end + +repeat + BtListen() + + -- Wait for button to be released + repeat + until( 0 == nxt.ButtonRead() ) + + -- Wait for button to be pressed + repeat + until( 8 == nxt.ButtonRead() ) + + -- Wait for button to be released + repeat + until( 0 == nxt.ButtonRead() ) +until false +]] + +-- Create the file, save the handle so we can use it later... +h = nxt.FileCreate( "pbLuaStartup", string.len(s) ) + +-- Now write the string... +nxt.FileWrite( h, s ) + +-- And close the file... +nxt.FileClose( h ) + +-- The next time you boot LEFTY or RIGHTY, this program will run, even +-- if you're not connected to the console +--codeExampleEnd 22 + + +--codeExampleStart 23 ----------------------------------------------------------- +-- Copy the BtStream() function into FLASH on CONTROL and run +-- it at startup + +-- Create the program as an extended string... +s = [[ +function BtIdleWait() + local active + repeat + _,active = nxt.BtGetStatus() + until 17 == active +end + + +function BtStream() + nxt.BtDisconnectAll() + + -- Wait until idle + BtIdleWait() + + -- Set up the connection to LEFTY on channel 1 and device 2 (your device + -- number may be different! + nxt.BtConnect(1,1) + + -- Wait until idle + BtIdleWait() + + -- Set up the connection to RIGHTY on channel 2 and device 3 (your device + -- number may be different! + nxt.BtConnect(2,2) + + -- Wait until idle + BtIdleWait() + + --Make sure we're reading the raw stream, not NXT messages + nxt.BtStreamMode(1) + + local i = 0 + + repeat + nxt.BtStreamSend(1,"LEFTY" .. i) + nxt.BtStreamSend(2,"RIGHTY" .. i) + i = i+1 + until( 8 == nxt.ButtonRead() ) +end + +repeat + BtStream() + + -- Wait for button to be released + repeat + until( 0 == nxt.ButtonRead() ) + + -- Wait for button to be pressed + repeat + until( 8 == nxt.ButtonRead() ) + + -- Wait for button to be released + repeat + until( 0 == nxt.ButtonRead() ) +until false +]] + +-- Create the file, save the handle so we can use it later... +h = nxt.FileCreate( "pbLuaStartup", string.len(s) ) + +-- Now write the string... +nxt.FileWrite( h, s ) + +-- And close the file... +nxt.FileClose( h ) + +-- The next time you boot CONTROL, this program will run, even +-- if you're not connected to the console +--codeExampleEnd 23 + diff --git a/examples/tutorial/pbLuaBtConsole.lua b/examples/tutorial/pbLuaBtConsole.lua new file mode 100644 index 0000000..dc3e2fa --- /dev/null +++ b/examples/tutorial/pbLuaBtConsole.lua @@ -0,0 +1,233 @@ +-- This is the example code file for the webpage at: +-- +-- www.hempeldesigngroup.com/lego/pbLua/tutorial/pbLuaBtConsole.html + + +--codeExampleStart BtConsole_1 ----------------------------------------------------------- +> nxt.BtFactoryReset() +--codeExampleEnd BtConsole_1 + +--codeExampleStart BtConsole_2 ----------------------------------------------------------- +> nxt.BtPower(1) +--codeExampleEnd BtConsole_2 + +--codeExampleStart BtConsole_3 ----------------------------------------------------------- +> nxt.BtVisible(1) +--codeExampleEnd BtConsole_3 + +--codeExampleStart BtConsole_4 ----------------------------------------------------------- +> nxt.BtSetName("OGEL") +--codeExampleEnd BtConsole_4 + + +--codeExampleStart Linux_1 ----------------------------------------------------------- +rhempel@debian:~$ dmesg + +[ 3337.783560] usb 1-1: USB disconnect, address 4 +[ 3533.515988] Clocksource tsc unstable (delta = 4686977665 ns) +[ 3668.161395] usb 1-1: new full speed USB device using uhci_hcd and address 6 +[ 3668.403670] usb 1-1: configuration #1 chosen from 1 choice +[ 3668.467956] cdc_acm: This device cannot do calls on its own. It is no modem. +[ 3668.469863] cdc_acm 1-1:1.0: ttyACM0: USB ACM device +--codeExampleEnd Linux_1 + +--codeExampleStart Linux_2 ----------------------------------------------------------- +rhempel@debian:~$ ls /dev/ttyACM* +/dev/ttyACM0 +--codeExampleEnd Linux_2 + +--codeExampleStart Linux_3 ----------------------------------------------------------- +# Machine-generated file - use setup menu in minicom to change parameters. +pu port /dev/ttyACM0 +pu minit +pu mreset +--codeExampleEnd Linux_3 + +--codeExampleStart Linux_4 ----------------------------------------------------------- +rhempel@debian:~$ minicom acm0 +Welcome to minicom 2.3 + +OPTIONS: I18n +Compiled on Oct 24 2008, 06:37:44. +Port /dev/ttyACM0 + + Press CTRL-A Z for help on special keys +> +--codeExampleEnd Linux_4 + +--codeExampleStart Linux_5 ----------------------------------------------------------- +rhempel@debian:~$ sudo apt-get install bluez bluez-hcidump + +Unpacking bluez (from .../archives/bluez_4.57-1_i386.deb) ... +--codeExampleEnd Linux_5 + +--codeExampleStart Linux_6 ----------------------------------------------------------- +-- /etc/default/bluetooth + +HID2HCI_ENABLED=1 +HID2HCI_UNDO=1 +--codeExampleEnd Linux_6 + +----codeExampleStart Linux_7 ----------------------------------------------------------- +-- Only run this if your Bluetooth interface is connected to the USB bus +rhempel@debian:~$ lsusb +Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub +Bus 001 Device 002: ID 050d:016a Belkin Components +Bus 001 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub + +-- Check if your Bluetooth interface is recognized +rhempel@debian:~$ hcitool dev +Devices: + hci0 aa:bb:cc:dd:ee:ff +--codeExampleEnd Linux_7 + +--codeExampleStart Linux_8 ----------------------------------------------------------- +rhempel@debian:~$ sudo hcidump +HCI sniffer - Bluetooth packet analyzer ver 1.42 +device: hci0 snap_len: 1028 filter: 0xffffffff +< HCI Command: Create Connection (0x01|0x0005) plen 13 +> HCI Event: Command Status (0x0f) plen 4 +> HCI Event: Connect Complete (0x03) plen 11 +... +> HCI Event: Link Key Request (0x17) plen 6 +< HCI Command: Link Key Request Reply (0x01|0x000b) plen 22 +> HCI Event: Command Complete (0x0e) plen 10 +> HCI Event: Connect Complete (0x03) plen 11 +< HCI Command: Read Remote Supported Features (0x01|0x001b) plen 2 +< ACL data: handle 11 flags 0x02 dlen 10 + L2CAP(s): Info req: type 2 +> ACL data: handle 11 flags 0x02 dlen 16 + L2CAP(s): Info rsp: type 2 result 0 + Extended feature mask 0x0000 +... +... You get the idea +--codeExampleEnd Linux_8 +-- +--codeExampleStart Linux_9 ----------------------------------------------------------- +rhempel@debian:~$ /usr/sbin/hciconfig +hci0: Type: USB + BD Address: aa:bb:cc:dd:ee:ff ACL MTU: 1021:8 SCO MTU: 64:1 + UP RUNNING PSCAN + RX bytes:2145 acl:0 sco:0 events:82 errors:0 + TX bytes:2040 acl:0 sco:0 commands:82 errors:0 +--codeExampleEnd Linux_9 + +--codeExampleStart Linux_10 ----------------------------------------------------------- +rhempel@debian:~$ hcitool scan +Scanning ... + nn:xx:tt:mm:aa:cc OGEL +--codeExampleEnd Linux_10 + +--codeExampleStart Linux_11 ----------------------------------------------------------- +rhempel@debian:~$ ls /var/lib/bluetooth/aa:bb:cc:dd:ee:ff/ +classes config lastseen names +--codeExampleEnd Linux_11 + +--codeExampleStart Linux_12 ----------------------------------------------------------- +-- /var/lib/bluetooth/aa:bb:cc:dd:ee:ff/pincodes +-- Add a line that looks like this (put your desired pincode instead of 1234): + +nn:xx:tt:mm:aa:cc 1234 +--codeExampleEnd Linux_12 +-- +--codeExampleStart Linux_13 ----------------------------------------------------------- +-- /var/lib/bluetooth/aa:bb:cc:dd:ee:ff/trusts +-- Add a line that looks like this: + +nn:xx:tt:mm:aa:cc [all] +--codeExampleEnd Linux_13 + +--codeExampleStart Linux_14 ----------------------------------------------------------- +/etc/bluetooth/rfcomm.conf + +-- Edit the rfcomm0 section like so: +rfcomm0 { + # Automatically bind the device at startup + bind yes; + + # Bluetooth address of the device + device nn:xx:tt:mm:aa:cc; + + # RFCOMM channel for the connection + channel 1; + + # Description of the connection + comment "OGEL"; +} +--codeExampleEnd Linux_14 + +--codeExampleStart Linux_15 ----------------------------------------------------------- +rhempel@debian:~$ sudo /etc/init.d/bluetooth restart +--codeExampleEnd Linux_15 + +--codeExampleStart Linux_16 ----------------------------------------------------------- +> nxt.BtSetPIN("1234") + +-- Optionally, you can run this little snippet of code that will send the +-- PIN every time you press the orange button... + +function sendPIN() + local oldButton = 0 + local newButton = 0 + + while( 1 ) do + newButton = nxt.ButtonRead() + + if 0 == oldButton then + -- Only check buttons if no buttons were pressed! + + if 8 == newButton then + nxt.BtSetPIN("1234") + end + end + + oldButton = newButton + end +end + +-- And run the function (it's an endless loop - power off the NXT to stop it) +sendPIN() +--codeExampleEnd Linux_16 + +--codeExampleStart Linux_17 ----------------------------------------------------------- +rhempel@debian:~$ sudo rfcomm bind 0 +rhempel@debian:~$ sudo rfcomm connect 0 +Can't create RFCOMM TTY: Address already in use +--codeExampleEnd Linux_17 + +--codeExampleStart Linux_18 ----------------------------------------------------------- +rhempel@debian:~$ ls /var/lib/bluetooth/aa:bb:cc:dd:ee:ff/ +classes features lastused manufacturers pincodes +config lastseen linkkeys names trusts +--codeExampleEnd Linux_18 + +--codeExampleStart Linux_19 ----------------------------------------------------------- +rhempel@debian:~$ sudo /etc/init.d/bluetooth restart + +-- Verify that rfcomm0 is assigned to OGEL +rhempel@debian:~$ rfcomm +rfcomm0: 00:16:53:04:E8:A3 channel 1 clean +--codeExampleEnd Linux_19 + +--codeExampleStart Linux_20 ----------------------------------------------------------- +-- One last step, create a config for minicom in your home directory +-- called .minirc.OGEL with this as the contents: +# Machine-generated file - use setup menu in minicom to change parameters. +pu port /dev/rfcomm0 +pu minit +pu mreset +--codeExampleEnd Linux_20 + +--codeExampleStart Linux_21 ----------------------------------------------------------- +rhempel@debian:~$ minicom OGEL +Welcome to minicom 2.3 + +OPTIONS: I18n +Compiled on Oct 24 2008, 06:37:44. +Port /dev/rfcomm0 + + Press CTRL-A Z for help on special keys +> +--codeExampleEnd Linux_21 + + diff --git a/examples/tutorial/pbLuaCDCConnect.png b/examples/tutorial/pbLuaCDCConnect.png new file mode 100644 index 0000000..0167bff Binary files /dev/null and b/examples/tutorial/pbLuaCDCConnect.png differ diff --git a/examples/tutorial/pbLuaCDCConnect.xpm b/examples/tutorial/pbLuaCDCConnect.xpm new file mode 100644 index 0000000..5df8c17 --- /dev/null +++ b/examples/tutorial/pbLuaCDCConnect.xpm @@ -0,0 +1,114 @@ +/* XPM */ +static char * _xpm[] = { +"72 108 2 1", +" c #77cc88", +"* c #000044", +" ", +" ", +" ", +" ", +" ***** ***** ", +" * * * * * ", +" * * * * * ", +" * * * * * ", +" ***** * * ", +" ", +" ***** ******* ", +" * * * * * ", +" * * * * * ", +" * * * * * ", +" ***** *** ", +" ", +" ***** ", +" * * * * ", +" ******* * * ", +" * * * ", +" * * ", +" ", +" ** ", +" * * * ", +" * * * ", +" * * * ", +" **** ", +" ", +" ** ***** ", +" * * * * * ", +" * * * * * ", +" * * * * * ", +" **** * * ", +" ", +" *** ", +" * * ", +" * * ", +" * * ", +" *** ", +" ", +" ******* ***** ", +" * * * * ", +" * * * * ", +" * * * * ", +" ** ** **** ", +" ", +" **** ***** ", +" * * ", +" * * ", +" * * ", +" ***** **** ", +" ", +" * *** ", +" ****** * * * ", +" * * * * * ", +" * * * * ", +" * ** ", +" ", +" * *** ", +" ****** * * ", +" * * * * ", +" * * * ", +" * * ", +" ", +" *** * ", +" * * ****** ", +" * * * * ", +" * * * ", +" *** * ", +" ", +" ***** ", +" * ", +" * ", +" * ", +" **** ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ***** ", +" * * * ", +" * * * ", +" * * * ", +" ***** ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +}; diff --git a/examples/tutorial/pbLuaCDCInit.png b/examples/tutorial/pbLuaCDCInit.png new file mode 100644 index 0000000..0ae6170 Binary files /dev/null and b/examples/tutorial/pbLuaCDCInit.png differ diff --git a/examples/tutorial/pbLuaCDCInit.xpm b/examples/tutorial/pbLuaCDCInit.xpm new file mode 100644 index 0000000..7778854 --- /dev/null +++ b/examples/tutorial/pbLuaCDCInit.xpm @@ -0,0 +1,114 @@ +/* XPM */ +static char * _xpm[] = { +"72 108 2 1", +" c #77cc88", +"* c #000044", +" ", +" ", +" ", +" ", +" ** ***** ", +" * * * * ", +" * * * * ", +" * * * * ", +" **** * * ", +" ", +" ** ******* ", +" * * * * ", +" * * * * ", +" * * * * ", +" **** *** ", +" ", +" ** ***** ", +" * * * * ", +" * * * * ", +" * * * * ", +" **** * * ", +" ", +" ** ", +" * * ", +" * * ", +" * * ", +" **** ", +" ", +" ** ", +" * * * * ", +" * * ******* ", +" * * * * ", +" **** ", +" ", +" ***** ", +" * ", +" * ", +" * ", +" **** ", +" ", +" ******* ", +" * * * * * ", +" * * * ***** * ", +" * * * * ", +" ** ** ", +" ", +" **** * ", +" * ****** ", +" * * * ", +" * * ", +" ***** * ", +" ", +" * ", +" ****** ", +" * * ", +" * ", +" * ", +" ", +" * ", +" ****** ", +" * * ", +" * ", +" * ", +" ", +" *** ", +" * * ", +" * * ", +" * * ", +" *** ", +" ", +" ***** ", +" * ", +" * ", +" * ", +" **** ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ***** ", +" * * * ", +" * * * ", +" * * * ", +" ***** ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +}; diff --git a/examples/tutorial/pbLuaConsoleChooser.png b/examples/tutorial/pbLuaConsoleChooser.png new file mode 100644 index 0000000..256a040 Binary files /dev/null and b/examples/tutorial/pbLuaConsoleChooser.png differ diff --git a/examples/tutorial/pbLuaConsoleChooser.xpm b/examples/tutorial/pbLuaConsoleChooser.xpm new file mode 100644 index 0000000..f2f16a7 --- /dev/null +++ b/examples/tutorial/pbLuaConsoleChooser.xpm @@ -0,0 +1,114 @@ +/* XPM */ +static char * _xpm[] = { +"72 108 2 1", +" c #77cc88", +"* c #000044", +" ", +" ", +" ", +" ", +" ** ***** * * ********* ", +" * * * * * * * * ** ****** ", +" * * * * * * * ** ****** ", +" * * * * * * * * ** ****** ", +" **** ***** * * ** ** ** ", +" ******** ", +" ** ***** * * ** *** * ", +" * * * * * * ** ** ** ", +" * * * * * ******** ** ** ", +" * * * * * * * ** ** ** ", +" **** ** * * * *** *** ", +" ******** ", +" ** ******* * * * ", +" * * * * * * * * ** ** ", +" * * * * * * * ** ** ", +" * * * * * * * * ** ** ", +" **** * * * * ** * * ", +" ******** ", +" ** ******* * * ***** ******** ", +" * * * * * * ********* ", +" * * * * * ********* ", +" * * * * * * ********* ", +" **** * * * * * ******** ", +" ******** ", +" ** *** ** * ", +" * * * * * ***** ", +" * * * * * ***** ", +" * * * * * ***** ", +" **** *** ** *** * ", +" ******** ", +" ***** ***** ** *** ", +" * * * *** ** ", +" ** * * *** ** ", +" * * * *** ** ", +" **** **** ** *** ", +" ******** ", +" ******* ***** * * * ** ", +" * * * * * * * **** *** ", +" * * * * * * * ***** ** ", +" * * * * * * * ***** ** ", +" ** ** ***** * * *** ", +" ******** ", +" **** *** * ** *** ", +" * * * * * * ** ", +" * * * * * * ** ", +" * * * * * * ** ", +" ***** *** ** ***** ", +" ******** ", +" * ***** ** *** ", +" ****** * * * ** *** ** ", +" * * * * ******** *** ** ", +" * * * * * *** ** ", +" * * * ** *** ", +" ******** ", +" * *** *** ******** ", +" ****** * * * * * * * ***** ", +" * * * * * * * * * ", +" * * * * * * * * ****** ", +" * ** ** ******** ", +" ******** ", +" *** ** *** ", +" * * * * * * * ** ", +" * * ******* * * * ** ", +" * * * * * * ** ", +" *** *** *** ", +" ******** ", +" ***** ", +" * * * ", +" * ******* ", +" * * ", +" **** ", +" ", +" * * ", +" * * * ", +" * * * ", +" * * * ", +" * ", +" ", +" ***** ", +" * * * ", +" * * * ", +" * * * ", +" ***** ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +}; diff --git a/examples/tutorial/pbLuaCoroutines.lua b/examples/tutorial/pbLuaCoroutines.lua new file mode 100644 index 0000000..f54cba8 --- /dev/null +++ b/examples/tutorial/pbLuaCoroutines.lua @@ -0,0 +1,154 @@ +-- This is the example code file for the webpage at: +-- +-- www.hempeldesigngroup.com/lego/pbLua/tutorial/pbLuaCoroutines.html + +--codeExampleStart 1 ----------------------------------------------------------- +co = coroutine.create( +function () + for i=1,10 do + print("co",i) + coroutine.yield() + end +end +) +--codeExampleEnd 1 + +--codeExampleStart 2 ----------------------------------------------------------- + +co1 = coroutine.create( +function ( s ) + local t = nxt.TimerRead() + while s do + if t+1000 < nxt.TimerRead() then + t = t+1000 + print("co1", t) + end + + s = coroutine.yield() + end +end +) + +co2 = coroutine.create( +function ( s ) + local t = nxt.TimerRead() + while s do + if t+1500 < nxt.TimerRead() then + t = t+1500 + print("bo2", t) + end + + s = coroutine.yield() + end +end +) + + +repeat + local s = nxt.ButtonRead() +until false == (coroutine.resume(co1, s==0) and coroutine.resume(co2, s==0)) + +--codeExampleEnd 2 + +--codeExampleStart n ----------------------------------------------------------- +-- Using a coroutine to drive a motor back and forth until +-- a button is pressed + +SeeSaw1 = coroutine.create( +function ( port, speed, rot ) + local s = true + + nxt.OutputSetRegulation(port,1,1) + nxt.OutputResetTacho(port,1,1,1) + + while s do + nxt.OutputSetSpeed(port,0x20,speed,rot) + repeat + s = coroutine.yield() + _,_,_,_,_,_,d = nxt.OutputGetStatus( port ) + until d < 3 + speed = -speed + end +end +) + +coroutine.resume(SeeSaw1,1,75,360) +repeat + local s = nxt.ButtonRead() +until false == coroutine.resume(SeeSaw1,s==0) +--codeExampleEnd n + +--codeExampleStart n ----------------------------------------------------------- + + +function TurnWait( port, co ) + local s,v = coroutine.resume( co ) + local _,_,_,_,_,_,d = nxt.OutputGetStatus( port ) + return s, v, (d < 3) +end + +function Flipper( port, speed, rot, co ) + return coroutine.create( function () + nxt.OutputSetRegulation(port,1,1) + nxt.OutputResetTacho(port,1,1,1) + + local s,t,v,d = true,0,0,false + + repeat + while t == 0 do + s,v = coroutine.resume( co ) + t = t + v + end + + t = 0 + nxt.OutputSetSpeed(port,0x20, speed,rot) + repeat + s,v,d = TurnWait( port, co ) + t = t + v + until d + + while t == 0 do + s,v = coroutine.resume( co ) + t = t + v + end + + t = 0 + coroutine.yield(1) + + nxt.OutputSetSpeed(port,0x20,-speed,rot) + repeat + s,v,d = TurnWait( port, co ) + t = t + v + until d + + until s == false + end ) +end + + +function Ticker( n ) + return coroutine.create( function () + local t = nxt.TimerRead() + repeat + t = t + n + repeat + coroutine.yield( 0 ) + until t <= nxt.TimerRead() + print( "Tick" ) + coroutine.yield( 1 ) + until 0~=nxt.ButtonRead() + end ) +end + + +function Clock( co ) + repeat + until false == coroutine.resume( co ) +end + +-- Clock( Ticker( 1000 ) ) +-- Clock( Flipper( 1,75,90, Ticker( 1000 ) ) ) +-- Clock( Flipper( 2,75,90, Flipper( 1,75,90, Ticker( 1000 ) ) ) ) +Clock( Flipper( 3,75,180, Flipper( 2,75,180, Flipper( 1,75,180, Ticker( 1000 ) ) ) ) ) + +--codeExampleEnd n diff --git a/examples/tutorial/pbLuaDatalog.lua b/examples/tutorial/pbLuaDatalog.lua new file mode 100644 index 0000000..b15295b --- /dev/null +++ b/examples/tutorial/pbLuaDatalog.lua @@ -0,0 +1,222 @@ +-- This is the example code file for the webpage at: +-- +-- www.hempeldesigngroup.com/lego/pbLua/tutorial/pbLuaDatalog.html + +--codeExampleStart 1 ----------------------------------------------------------- +-- Read gyro sensor until the orange button is pressed +function GyroRead(port) + + -- Set up the gyro sensor with low sensitivity + nxt.InputSetType(port,0) + nxt.InputSetState(port,0,0) + nxt.InputSetDir(port,1,1) + + -- Now start reading the sensor and putting out data + repeat + print( nxt.TimerRead(), nxt.InputGetStatus(port) ) + until( 8 == nxt.ButtonRead() ) +end + +-- And using the function - press the orange button on the NXT to stop it +GyroRead(1) +--codeExampleEnd 1 + +--codeExampleStart 1r ----------------------------------------------------------- +52017 617 0 0 +52019 615 0 0 +52021 617 0 0 +52023 616 0 0 +52025 616 0 0 +52027 617 0 0 +52029 616 0 0 +--codeExampleEnd 1r + +--codeExampleStart 2 ----------------------------------------------------------- +-- Lots of tricks in this function, note the concatenation operator ".." and +-- that the last two results from nxt.InputGetStatus() are simply discarded! + +function sampleString(port) + return nxt.istr(nxt.TimerRead()) .. nxt.istr(nxt.InputGetStatus(port)) +end +--codeExampleEnd 2 + +--codeExampleStart 2s ----------------------------------------------------------- +-- Let's do a few examples first... +=string.byte(nxt.istr(0),1,4) +=string.byte(nxt.istr(255),1,4) +=string.byte(nxt.istr(65535),1,4) +=string.byte(nxt.istr(-1),1,4) + +-- And now use the function to generate the string... +port = 1 +s = sampleString(port) + +-- And dump the results. Can you figure out what the values were? +=string.byte(s,1,8) + +-- It's easy if you do this... + +-- The timestamp is the first 4 bytes (1 to 4) +=nxt.stri(string.sub(s,1,4)) + +-- The value is the second 4 bytes (5 to 8) +=nxt.stri(string.sub(s,5,8)) +--codeExampleEnd 2s + +--codeExampleStart 2r ----------------------------------------------------------- +-- Let's do a few examples first... +> =string.byte(nxt.istr(0),1,4) +0 0 0 0 + +> =string.byte(nxt.istr(255),1,4) +255 0 0 0 + +> =string.byte(nxt.istr(65535),1,4) +255 255 0 0 + +> =string.byte(nxt.istr(-1),1,4) +255 255 255 255 + +-- And now use the function to generate the string... +> port = 1 +> s = sampleString(port) + +-- And dump the results. Can you figure out what the values were? +> =string.byte(s,1,8) +148 26 10 0 106 2 0 0 + +-- It's easy if you do this... + +> -- The timestamp is the first 4 bytes (1 to 4) +> =nxt.stri(string.sub(s,1,4)) +662164 + +-- The value is the second 4 bytes (5 to 8) +> =nxt.stri(string.sub(s,5,8)) +618 +--codeExampleEnd 2r + +--codeExampleStart 3 ----------------------------------------------------------- +-- Function to save 100 timestamped samples to a file as quickly as +-- possible + +function save100 (port) + -- Set up the gyro sensor with low sensitivity + nxt.InputSetType(port,0) + nxt.InputSetState(port,0,0) + nxt.InputSetDir(port,1,1) + + -- Create an 800 byte file, save the handle + local file = nxt.FileCreate("sampleFile", 800) + + -- And now read and save 100 individual samples and timestamps + for i=1,100 do + nxt.FileWrite( file, nxt.istr(nxt.TimerRead()) .. nxt.istr(nxt.InputGetStatus(port)) ) + end + + -- And close the file + nxt.FileClose(file) +end + +-- And run the function on port 1 to try it out... +save100(1) +--codeExampleEnd 3 + +--codeExampleStart 4 ----------------------------------------------------------- +-- Function to dump timestamped samples from a file + +function DataDumper() + -- Open the file + file = nxt.FileOpen( "sampleFile" ) + + -- And now read individual samples and timestamps 8 bytes + -- at a time until there are no more + repeat + local s = nxt.FileRead( file, 8 ) + + if s then + local t = nxt.stri(string.sub(s,1,4)) + local v = nxt.stri(string.sub(s,5,8)) + print( string.format( "T:%08i V:%04i", t, v ) ) + end + until nil == s + + -- And close the file + nxt.FileClose(file) +end + +-- And run the function to see how fast the writing went... +DataDumper() + +T:00950217 V:0617 +T:00950221 V:0616 +T:00950224 V:0619 + ... +T:00950574 V:0616 +T:00950578 V:0615 +T:00950581 V:0618 + +-- Yep, that's 100 samples written in 364 msec! +--codeExampleEnd 4 + +--codeExampleStart 5 ----------------------------------------------------------- +-- Complete data logger example +s = [[ +function DataLogger () + -- Set up the gyro sensor on port 1 with low sensitivity + nxt.InputSetType(1,0) + nxt.InputSetState(1,0,0) + nxt.InputSetDir(1,1,1) + + -- Check to see if the file exists, and if so, erase it... + if nxt.FileExists("sampleFile") then + nxt.FileDelete("sampleFile") + end + + -- Create an 8000 byte file, save the handle + local file = nxt.FileCreate("sampleFile", 8000) + + -- Clear the display + nxt.DisplayClear() + + -- And now read and save up to 100 individual samples and timestamps + for i=1,1000 do + nxt.FileWrite( file, nxt.istr(nxt.TimerRead()) .. nxt.istr(nxt.InputGetStatus(1)) ) + + -- Update the LCD so we can see what's going on... + + nxt.DisplayText( i ) + + -- break out of the loop if the user hits the orange button + if 8 == nxt.ButtonRead() then + break + end + end + + -- And close the file + nxt.FileClose(file) + + -- And turn off the NXT + nxt.PowerDown() +end + +-- Don't forget tot execute it :-) +DataLogger() +]] +--codeExampleEnd 5 + +--codeExampleStart 6 ----------------------------------------------------------- +> =string.len(s) +970 +--codeExampleEnd 6 + +--codeExampleStart 7 ----------------------------------------------------------- +> f=nxt.FileCreate("pbLuaStartup", 1024) +> nxt.FileWrite(f,s) +> nxt.FileClose(f) +--codeExampleEnd 7 + +--codeExampleStart n ----------------------------------------------------------- +--codeExampleEnd n + + diff --git a/examples/tutorial/pbLuaFileSystem.lua b/examples/tutorial/pbLuaFileSystem.lua new file mode 100644 index 0000000..3485d89 --- /dev/null +++ b/examples/tutorial/pbLuaFileSystem.lua @@ -0,0 +1,248 @@ +-- This is the example code file for the webpage at: +-- +-- www.hempeldesigngroup.com/lego/pbLua/tutorial/pbLuaFileSystem.html + +--codeExampleStart 1 ----------------------------------------------------------- +-- Format the FLASH file system, erasing all files: +nxt.FileFormat(1) + +-- Format the FLASH file system, moves the file descriptor block to a new +-- location, makes erased descriptors usable, leaves exiting files untouched: +nxt.FileFormat(0) +--codeExampleEnd 1 + +--codeExampleStart 2 ----------------------------------------------------------- +-- Return information on the pbLua filesystem +function FileSysInfo() + files, blocks, blockSize = nxt.FileSysInfo() + + print( "Total File Descriptors -> " .. files ) + print( "Total FLASH Blocks -> " .. blocks ) + print( "FLASH Block Size -> " .. blockSize .. " bytes" ) +end +--codeExampleEnd 2 + +--codeExampleStart r2 ----------------------------------------------------------- +-- Print out the FLASH File System Information +FileSysInfo() + +-- Results are below, do not paste the following text to the console! +Total File Descriptors -> 31 +Total FLASH Blocks -> 374 +FLASH Block Size -> 256 bytes +--codeExampleEnd r2 + +--codeExampleStart 3 ----------------------------------------------------------- +-- Return information on the pbLua filesystem +function DumpFileDesc(from,to) + + print( "Type Name Block MaxBytes CurBytes CurPtr" ) + + for h=from,to do + print( string.format( "%4i %12s %5i %5i %5i %8i", nxt.FileHandleInfo(h) ) ) + end +end +--codeExampleEnd 3 + +--codeExampleStart r3 ----------------------------------------------------------- +-- Dump all of the file descriptors +DumpFileDesc(0,31) + +-- Results are below, do not paste the following text to the console! +Type Name Block MaxBytes CurBytes CurPtr + 3 pbLuaFileSys 0 512 0 1214976 + 1 ˙˙˙˙˙˙˙˙˙˙˙˙ 65535 65535 0 17991936 + 1 ˙˙˙˙˙˙˙˙˙˙˙˙ 65535 65535 0 17991936 + 1 ˙˙˙˙˙˙˙˙˙˙˙˙ 65535 65535 0 17991936 + ... +--codeExampleEnd r3 + +--codeExampleStart 4 ----------------------------------------------------------- +function Hello() + nxt.DisplayClear() + nxt.DisplayText( "Hello, World!" ) +end +--codeExampleEnd 4 + +--codeExampleStart 5 ----------------------------------------------------------- +programString = [[ +nxt.DisplayClear() +nxt.DisplayText( "Hello, World!" ) +]] +--codeExampleEnd 5 + +--codeExampleStart 6 ----------------------------------------------------------- +-- Print the number of bytes in the string: +=string.len( programString ) + +-- Or do it a bit fancier: +print( "programString has " .. string.len( programString ) .. " bytes" ) + +-- Compile the string into a function: +test = loadstring( programString ) + +-- And run it, but clear the display first: +nxt.DisplayClear() +test() +--codeExampleEnd 6 + +--codeExampleStart 7 ----------------------------------------------------------- +programString = [[ +nxt.DisplayClear() +nxt.DisplayText( "Hello, World!" ) +]] + +-- Create the file, save the handle so we can use it later... +h = nxt.FileCreate( "hello", 128 ) + +-- Now write the string... +nxt.FileWrite( h, programString ) + +-- And close the file... +nxt.FileClose( h ) +--codeExampleEnd 7 + +--codeExampleStart r7 ----------------------------------------------------------- +-- Now let's dump the first few file descriptors to see what we get: +DumpFileDesc(0,3) + +-- Results are below, do not paste the following text to the console! +Type Name Block MaxBytes CurBytes CurPtr + 3 pbLuaFileSys 0 512 0 1214976 + 5 hello 2 54 0 1215488 + 1 ˙˙˙˙˙˙˙˙˙˙˙˙ 65535 65535 0 17991936 + 1 ˙˙˙˙˙˙˙˙˙˙˙˙ 65535 65535 0 17991936 + ... +--codeExampleEnd r7 + +--codeExampleStart 8 ----------------------------------------------------------- +-- Read the whole file as a string +h = nxt.FileOpen("hello") +s = nxt.FileRead(h,"*a") +nxt.FileClose(h) + +print( s ) + +-- Results are below, do not paste the following text to the console! +nxt.DisplayClear() +nxt.DisplayText( "Hello, World!" ) +--codeExampleEnd 8 + + +--codeExampleStart 9 ----------------------------------------------------------- +-- Read the whole file a line at a time +h = nxt.FileOpen("hello") +repeat + s = nxt.FileRead(h,"*l") + print( string.len(s or ""), s ) +until nil == s +nxt.FileClose(h) + +-- Results are below, do not paste the following text to the console! +-- +-- Note that the value returned for the last line is nil, we've +-- arranged to have it printed here. Normally you would not print it. +18 nxt.DisplayClear() +34 nxt.DisplayText( "Hello, World!" ) +0 nil:0x0 +--codeExampleEnd 9 + +--codeExampleStart 10 ----------------------------------------------------------- +-- Read the whole file 7 bytes at a time +h = nxt.FileOpen("hello") +repeat + s = nxt.FileRead(h,7) + print( string.len(s or ""), s ) +until nil == s +nxt.FileClose(h) + +-- Results are below, do not paste the following text to the console! +7 nxt.Dis +7 playCle +7 ar() +nx +7 t.Displ +7 ayText( +7 "Hello +7 , World +5 !" ) + +0 nil:0x0 +--codeExampleEnd 10 + +--codeExampleStart 11 ----------------------------------------------------------- +-- Read a file into a function that can be executed +f = nxt.loadfile("hello") + +-- And now run the funtion to see the result +f() +--codeExampleEnd 11 + +--codeExampleStart 12 ----------------------------------------------------------- +-- Read the file and execute it all at once +nxt.dofile("hello") +--codeExampleEnd 12 + +--codeExampleStart 13 ----------------------------------------------------------- +-- Run the file chooser and return the name of the file chosen: +print( nxt.FileChooser("name") ) + +-- Or more simply... +print( nxt.FileChooser() ) +--codeExampleEnd 13 + +--codeExampleStart 13a ----------------------------------------------------------- +-- Run the file chooser and return the contents of the file chosen: +print( nxt.FileChooser("file") ) +--codeExampleEnd 13a + +--codeExampleStart 14 ----------------------------------------------------------- +-- Run the file chooser and load the contents of the file into a function: +=nxt.FileChooser("loadfile") + +-- Whoops, let's put it into a functioon and execute it... +f=nxt.FileChooser("loadfile") +f() +--codeExampleEnd 14 + +--codeExampleStart 15 ----------------------------------------------------------- +-- Run the file chooser and execute the contents of the file +> =nxt.FileChooser("dofile") +--codeExampleEnd 15 + +--codeExampleStart 16 ----------------------------------------------------------- +-- Run the file chooser and execute the contents of the file, but only give the +-- user 5 seconds to make up their mind +> =nxt.FileChooser("dofile",5) +--codeExampleEnd 16 + +--codeExampleStart 17 ----------------------------------------------------------- +programString = [[ +nxt.FileChooser("dofile") + +melody = string.char(0x02, 0x00, 0x04, 0x00, + 0x01, 0x00, 0x04, 0x00, + 0x02, 0x00, 0x02, 0x00, + 0x03, 0x00, 0x02, 0x00, + 0x01, 0x00, 0x01, 0x00, + 0x03, 0x00, 0x01, 0x00) + +while 0 == nxt.SoundMelody( melody, 1 ) do +-- do nothing +end +]] + +h = nxt.FileCreate( "pbLuaStartup", 512 ) + +-- Now write the string... +nxt.FileWrite( h, programString ) + +-- And close the file... +nxt.FileClose( h ) +--codeExampleEnd 17 + + +--codeExampleStart n ----------------------------------------------------------- +--codeExampleEnd n + + diff --git a/examples/tutorial/pbLuaFirstSteps.lua b/examples/tutorial/pbLuaFirstSteps.lua new file mode 100644 index 0000000..44cf2be --- /dev/null +++ b/examples/tutorial/pbLuaFirstSteps.lua @@ -0,0 +1,131 @@ +-- This is the example code file for the webpage at: +-- +-- www.hempeldesigngroup.com/lego/pbLua/tutorial/pbLuaFirstSteps.html + +--codeExampleStart 1 ----------------------------------------------------------- +-- Hello World! for pbLua + +print( "Hello World!" ) +--codeExampleEnd 1 + +--codeExampleStart 2 ----------------------------------------------------------- +-- Reading the NXT millisecond timer + +print( nxt.TimerRead() ) +--codeExampleEnd 2 + +--codeExampleStart 3 ----------------------------------------------------------- +-- Reading the NXT millisecond timer using the short form of print + +=nxt.TimerRead() +--codeExampleEnd 3 + +--codeExampleStart 4 ----------------------------------------------------------- +-- Reading the NXT millisecond timer and storing it in a variable + +cur = nxt.TimerRead() + +-- And now print the saved result... + +print( cur ) + +-- or equivalently at the console... + +=cur +--codeExampleEnd 4 + +--codeExampleStart 5 ----------------------------------------------------------- +-- Implementing a simple busy-wait loop + +function BusyWait( n ) + local start, stop + start = nxt.TimerRead() + + repeat + stop = nxt.TimerRead() + until start+n < stop +end + +-- And use it like this: + +function testBusyWait( n ) + print( nxt.TimerRead() ) + BusyWait( n ) + print( nxt.TimerRead() ) +end +--codeExampleEnd 5 + +--codeExampleStart 6 ----------------------------------------------------------- +-- Reading the NXT front panel buttons + +print( nxt.ButtonRead() ) +--codeExampleEnd 6 + +--codeExampleStart 7 ----------------------------------------------------------- +-- Detecting a button press... + +function WaitButtonPress() + repeat + b = nxt.ButtonRead() + until b ~= 0 + + return b, nxt.TimerRead() +end + +-- and using the function + +b,t = WaitButtonPress() + +print( "Button -> " .. b .. " Time -> " .. t ) +--codeExampleEnd 7 + +--codeExampleStart 8 ----------------------------------------------------------- +-- Detecting a button release... + +function WaitButtonRelease() + local b + + repeat + b = nxt.ButtonRead() + until b == 0 + + return b, nxt.TimerRead() +end + +-- A function that combines these operations: + +function TimeButtonPress() + local b,s = WaitButtonPress() + _,e = WaitButtonRelease() + + print( "Button -> " .. b .. " Time -> " .. s ) + print( "Released at Time -> " .. e ) + print( "Total Time Pressed -> " .. e-s ) +end +--codeExampleEnd 8 + +--codeExampleStart 9 ----------------------------------------------------------- +-- Detecting button state... + +function WaitButtonState( s ) + repeat + b = nxt.ButtonRead() + until b == s + + return b, nxt.TimerRead() +end + +-- A function that combines these operations: + +function TimeButtonPress() + b,s = WaitButtonState( 8 ) + _,e = WaitButtonState( 0 ) + + print( "Button -> " .. b .. "Time -> " .. s ) + print( "Released at Time -> " .. e ) + print( "Total Time Pressed -> " .. e-s ) +end +--codeExampleEnd 9 + +--codeExampleStart n +--codeExampleEnd n diff --git a/examples/tutorial/pbLuaFloatMath.lua b/examples/tutorial/pbLuaFloatMath.lua new file mode 100644 index 0000000..9ba0e36 --- /dev/null +++ b/examples/tutorial/pbLuaFloatMath.lua @@ -0,0 +1,192 @@ +-- This is the example code file for the webpage at: +-- +-- www.hempeldesigngroup.com/lego/pbLua/tutorial/pbLuaFloatMath.html + +--codeExampleStart 1 ----------------------------------------------------------- +> f=123.456 +tty: stdin:1: malformed number near '123.456' +--codeExampleEnd 1 + +--codeExampleStart 2 ----------------------------------------------------------- +> =nxt.float(123, 456) +123.000457 +--codeExampleEnd 2 + +--codeExampleStart 3 ----------------------------------------------------------- +> =nxt.float(123, 456000) +123.456001 +--codeExampleEnd 3 + +--codeExampleStart 4 ----------------------------------------------------------- +> =nxt.float(-123, 456000) +-122.543998 +--codeExampleEnd 4 + +--codeExampleStart 5 ----------------------------------------------------------- +> =nxt.float(-123, -456000) +-123.456001 +--codeExampleEnd 5 + +--codeExampleStart 6 ----------------------------------------------------------- +> =-nxt.float(123, 456000) +-123.456001 +--codeExampleEnd 6 + +--codeExampleStart 7 ----------------------------------------------------------- +> =nxt.float(123) +123.000000 +--codeExampleEnd 7 + +--codeExampleStart 8 ----------------------------------------------------------- +> =nxt.float() +0.000000 +--codeExampleEnd 8 + +--codeExampleStart 9 ----------------------------------------------------------- +> =nxt.float(32456,9) +32456.000000 +--codeExampleEnd 9 + +--codeExampleStart 10 ----------------------------------------------------------- +> =nxt.float("08056.2984") +8056.298339 +--codeExampleEnd 10 + +--codeExampleStart 10a ----------------------------------------------------------- +> f=nxt.float("08056.2984") +> =nxt.int(f) +8056 298339 +--codeExampleEnd 10a + +--codeExampleStart 11 ----------------------------------------------------------- +> =nxt.float("123.45E17") +1.234496E19 +> =nxt.float("123.45e-10") +1.234500E-8 +--codeExampleEnd 11 + +--codeExampleStart 12 ----------------------------------------------------------- +> =1+2 +3 +--codeExampleEnd 12 + +--codeExampleStart 13 ----------------------------------------------------------- +> ="11"+2 +13 +--codeExampleEnd 13 + +--codeExampleStart 14 ----------------------------------------------------------- +> =1+4.567 +tty: stdin:1: malformed number near '4.567' +> ="123.45"+98 +tty: stdin:1: attempt to perform arithmetic on a string value +--codeExampleEnd 14 + +--codeExampleStart 15 ----------------------------------------------------------- +> f=nxt.float(1) +> =f +1.000000 +> =9+f +10.000000 +--codeExampleEnd 15 + +--codeExampleStart 16 ----------------------------------------------------------- +f=nxt.float(3) +g=nxt.float(4) +=f+g +7.000000 + +=f-g +-1.000000 + +=f*g +12.000000 + +=f/g +0.750000 +--codeExampleEnd 16 + +--codeExampleStart 17 ----------------------------------------------------------- +f=nxt.float(45,0) +=f +45.000000 + +f=nxt.float("45.0") +=f +45.000000 + +=nxt.sin(f) +0.707106 + +=nxt.sin(45) +0.707106 + +=nxt.sin("45") +0.707106 +--codeExampleEnd 17 + +--codeExampleStart 18 ----------------------------------------------------------- +f = nxt.float(49) +g = nxt.float(234) +=nxt.max(f,g) +234.000000 + +=nxt.min(f,g) +49.000000 + +f=49 +g=234 +=nxt.max(f,g) +234 + +=nxt.min(f,g) +49 +--codeExampleEnd 18 + +--codeExampleStart 19 ----------------------------------------------------------- +d = 56 +=nxt.pi()*d +175.929199 +--codeExampleEnd 19 + +--codeExampleStart 20 ----------------------------------------------------------- +d = 56 +t = nxt.TimerRead() +for i=1,10000 do + c = nxt.pi()*d +end +print( "10,000 iterations in ", nxt.TimerRead()-t, " milliseconds " ) +print( "c is ", c ) + +10,000 iterations in 3426 milliseconds +c is 175.929199 +--codeExampleEnd 20 + +--codeExampleStart 21 ----------------------------------------------------------- +=nxt.float(355)/nxt.float(113) +3.141592 + +=nxt.pi() +3.141592 + +=355/113 +3 +--codeExampleEnd 21 + +--codeExampleStart 22 ----------------------------------------------------------- +d = 56 +t = nxt.TimerRead() +for i=1,10000 do + c = (d*355)/113 +end +print( "10,000 iterations in ", nxt.TimerRead()-t, " milliseconds " ) +print( "c is ", c ) + +10,000 iterations in 304 milliseconds +c is 175 +--codeExampleEnd 22 + +--codeExampleStart n ----------------------------------------------------------- +--codeExampleEnd n + + diff --git a/examples/tutorial/pbLuaGPS.lua b/examples/tutorial/pbLuaGPS.lua new file mode 100644 index 0000000..ba5c043 --- /dev/null +++ b/examples/tutorial/pbLuaGPS.lua @@ -0,0 +1,377 @@ +-- This is the example code file for the webpage at: +-- +-- www.hempeldesigngroup.com/lego/pbLua/tutorial/pbLuaGPS.html + +--codeExampleStart 1 ----------------------------------------------------------- +-- Turn the Bluetooth radio off: +nxt.BtPower(0) + +-- Turn the Bluetooth radio on: +nxt.BtPower() + +-- or +nxt.BtPower(1) +--codeExampleEnd 1 + +--codeExampleStart 2 ----------------------------------------------------------- +-- Reset the Bluetooth subsystem to factory defaults. Note theat this does +-- not reset the firmware, just the device tables. You'll need to do a fresh +-- search of the Bluetooth devices +nxt.BtFactoryReset() + +-- Turn the visibility of the NXT on: +nxt.BtVisible() + +-- Turn the visibility of the NXT off: +nxt.BtVisible(0) + +-- Start searching for other visible Bluetooth devices: +nxt.BtSearch() + +-- Abort the search: +nxt.BtSearch(0) +--codeExampleEnd 2 + +--codeExampleStart 3 ----------------------------------------------------------- +-- Turn on the Bluetoorh radio, make the NXT visible and search for +-- other devices +function btIdleWait() + local active + repeat + _,active = nxt.BtGetStatus() + until 17 == active +end + +nxt.BtPower() +btIdleWait() + +nxt.BtVisible() +btIdleWait() + +nxt.BtSearch() -- This takes about 20 seconds! +btIdleWait() + +-- Now you're ready to use the Bluetooth system! +--codeExampleEnd 3 + +--codeExampleStart 4 ----------------------------------------------------------- +-- Turn on the Bluetooth system but make the NXT invisible to discovery +nxt.BtPower() +nxt.BtVisible(0) +--codeExampleEnd 4 + +--codeExampleStart 5 ----------------------------------------------------------- +-- Make the NXT visible to discovery +nxt.BtVisible() +--codeExampleEnd 5 + +--codeExampleStart 6 ----------------------------------------------------------- +-- Change the name of the NXT +nxt.BtSetName("Frodo") +--codeExampleEnd 6 + +--codeExampleStart 7 ----------------------------------------------------------- +-- Search for the NXT +nxt.BtSearch() -- This takes about 20 seconds! +btIdleWait() +--codeExampleEnd 7 + +--codeExampleStart 8 ----------------------------------------------------------- +-- btMonitor(n) monitors the Bluetooth system for n seconds and +-- prints a message any time there's a change + +function btMonitor( n ) + local t = nxt.TimerRead() + local oldState, oldActive, oldUpdate + + repeat + state, active, update = nxt.BtGetStatus() + if (state ~= oldState) or (active ~= oldActive) or (update ~= oldUpdate) then + print( nxt.TimerRead() - t, state, active, update ) + oldState = state + oldActive = active + oldUpdate = update + end + until t+n < nxt.TimerRead() +end +--codeExampleEnd 8 + +--codeExampleStart 9 ----------------------------------------------------------- +btMonitor(30000) +--codeExampleEnd 9 + +--codeExampleStart 10 ----------------------------------------------------------- +-- Set the PIN in your NXT +nxt.BtSetPIN("yourPIN") -- Put your own PIN in the quotes! +--codeExampleEnd 10 + +--codeExampleStart 11 ----------------------------------------------------------- +-- btDevice(n) dumps the first n entries in the Bluetooth device table + +function btDevice( n ) + for idx=0,n-1 do + name, class, addr, status = nxt.BtGetDeviceEntry( idx ) + + -- Format the BT device address + addr = string.format("%02x:%02x:%02x:%02x:%02x:%02x", string.byte( addr, 1, 6 ) ) + + -- Format the BT class + class = string.format("%02x:%02x:%02x:%02x", string.byte( class, 1, 4 )) + + -- Print the device info + print(string.format("Name:%16s Addr:%s Class:%s Status:%i",name,addr,class,status)) + end +end +--codeExampleEnd 11 + +--codeExampleStart 12 ----------------------------------------------------------- +-- Dump the first 4 entries in the device table +btDevice(4) + +-- Results are below, do not paste the following text to the console! +Name: Addr:00:00:00:00:00:00 Class:00:00:00:00 Status:0 +Name: Addr:00:00:00:00:00:00 Class:00:00:00:00 Status:0 +Name: Addr:00:00:00:00:00:00 Class:00:00:00:00 Status:0 +Name: Addr:00:00:00:00:00:00 Class:00:00:00:00 Status:0 +--codeExampleEnd 12 + +--codeExampleStart 13 ----------------------------------------------------------- +-- Initiate a new search for Bluetooth devices +nxt.BtSearch() +btMonitor(30000) + +-- Results are below, do not paste the following text to the console! +0 65 10 3 +13822 65 10 4 +13823 65 10 5 +15630 65 10 4 +15631 65 17 0 +--codeExampleEnd 13 + +--codeExampleStart 14 ----------------------------------------------------------- +-- Dump the first 4 entries in the device table +btDevice(4) + +-- Results are below, do not paste the following text to the console! +Name: Ralph DellD610 Addr:00:10:c6:62:f6:ba Class:00:1c:01:0c Status:65 +Name: Addr:00:00:00:00:00:00 Class:00:00:00:00 Status:0 +Name: Addr:00:00:00:00:00:00 Class:00:00:00:00 Status:0 +Name: Addr:00:00:00:00:00:00 Class:00:00:00:00 Status:0 +--codeExampleEnd 14 + +--codeExampleStart 15 ----------------------------------------------------------- +-- btConnect() dumps all the connection entries in the Bluetooth connection +-- table +function btConnect() + for idx=0,3 do + name, class, pin, addr, handle, status, linkq = nxt.BtGetConnectEntry( idx ) + + -- Format the BT device address + addr = string.format("%02x:%02x:%02x:%02x:%02x:%02x", string.byte( addr, 1, 6 ) ) + + -- Format the BT class + class = string.format("%02x:%02x:%02x:%02x", string.byte( class, 1, 4 )) + + -- Print the connection info + print(string.format("Name:%16s Addr:%s Class:%s PIN:%s Status:%i",name,addr,class,pin,status)) + end +end +--codeExampleEnd 15 + +--codeExampleStart 16 ----------------------------------------------------------- +-- Summarize the Bluetooth connection table +btConnect() + +-- Results are below, do not paste the following text to the console! +Name: Addr:00:10:c6:62:f6:ba Class:00:00:00:00 PIN:xyzzy Status:0 +Name: Addr:00:00:00:00:00:00 Class:00:00:00:00 PIN: Status:0 +Name: Addr:00:00:00:00:00:00 Class:00:00:00:00 PIN: Status:0 +Name: Addr:00:00:00:00:00:00 Class:00:00:00:00 PIN: Status:0 +--codeExampleEnd 16 + +--codeExampleStart 17 ----------------------------------------------------------- +-- Connect device 0 to channel 0 +nxt.BtConnect(0,0) +--codeExampleEnd 17 + +----codeExampleStart 18 ----------------------------------------------------------- +-- Dump the connection table again +btConnect() + +-- Results are below, do not paste the following text to the console! +Name: Ralph DellD610 Addr:00:10:c6:62:f6:ba Class:f8:7a:01:0c PIN: Status:1 +Name: Addr:00:00:00:00:00:00 Class:00:00:00:00 PIN: Status:0 +Name: Addr:00:00:00:00:00:00 Class:00:00:00:00 PIN: Status:0 +Name: Addr:00:00:00:00:00:00 Class:00:00:00:00 PIN: Status:0 +--codeExampleEnd 18 + +----codeExampleStart 19 ----------------------------------------------------------- +-- Put the NXT Bluetooth into raw streaming mode, and send some text +nxt.BtStreamMode(1) +nxt.BtStreamSend(0,"Hello world!") + +-- And disconnect if we're done... +nxt.BtDisconnect(0) +--codeExampleEnd 19 + +----codeExampleStart 20 ----------------------------------------------------------- +-- Search for the Navibe +nxt.BtSearch() + +-- Wait 20 seconds, then dump the device table to see if we can find it +btDevice(4) + +-- Results are below, do not paste the following text to the console! +Name: Ralph DellD610 Addr:00:10:c6:62:f6:ba Class:f8:7a:01:0c Status:66 +Name: BT GPS V10 Addr:00:0a:3a:24:33:97 Class:00:00:1f:00 Status:65 +Name: Addr:00:00:00:00:00:00 Class:00:00:00:00 Status:0 +Name: Addr:00:00:00:00:00:00 Class:00:00:00:00 Status:0 +--codeExampleEnd 20 + +----codeExampleStart 21 ----------------------------------------------------------- +nxt.BtConnect(1,1) -- Device 1, connection 1 + +-- You may have to also set the PIN for successful connection... +nxt.BtSetPIN("0000") +--codeExampleEnd 21 + +----codeExampleStart 22 ----------------------------------------------------------- +$GPGSA,A,2,,,,,,,,,,,,,50.0,50.0,50.0*06 +$GPRMC,140817.000,V,4433.2983,N,08056.3970,W,1.42,77.42,020707,,,E*51 +$GPGGA,140818.000,4433.2984,N,08056.3964,W,6,00,50.0,168.7,M,-36.0,M,,0000*5C +$GPGSA,A,2,,,,,,,,,,,,,50.0,50.0,50.0*06 +$GPRMC,140818.000,V,4433.2984,N,08056.3964,W,1.42,77.42,020707,,,E*5C +$GPGGA,140819.000,4433.2984,N,08056.3959,W,6,00,50.0,168.7,M,-36.0,M,,0000*53 +$GPGSA,A,2,,,,,,,,,,,,,50.0,50.0,50.0*06 +$GPGSV,3,1,10,18,71,320,30,21,62,184,32,09,46,130,,22,36,290,20*79 +$GPGSV,3,2,10,24,29,154,,26,28,050,22,29,18,052,,03,13,300,*78 +$GPGSV,3,3,10,14,12,233,,19,07,327,*75 +$GPRMC,140819.000,V,4433.2984,N,08056.3959,W,1.42,77.42,020707,,,E*53 +$GPGGA,140820.000,4433.2985,N,08056.3954,W,6,00,50.0,168.7,M,-36.0,M,,0000*55 +$GPGSA,A,2,,,,,,,,,,,,,50.0,50.0,50.0*06 +$GPRMC,140820.000,V,4433.2985,N,08056.3954,W,1.42,77.42,020707,,,E*55 +$GPGGA,140821.000,4433.2985,N,08056.3948,W,6,00,50.0,168.7,M,-36.0,M,,0000*59 +$GPGSA,A,2,,,,,,,,,,,,,50.0,50.0,50.0*06 +--codeExampleEnd 22 + +----codeExampleStart 23 ----------------------------------------------------------- +-- Connect, set to stream mode, and then send a dummy character to +-- get communications running. Remember to have btIdleWait() loaded ! +nxt.BtConnect(1,1) +btIdleWait() +nxt.BtStreamMode(1) +nxt.BtStreamSend(1,"") + +-- Wait a few seconds for BT data to accumulate, then enter: +print(nxt.BtStreamRecv()) + +-- Results are below, do not paste the following text to the console! +$GPRMC,170837.063,A,4433.3037,N,08056.4227,W,3.28,309.27,161108,,,D*70 +$GPGGA,170838.063,4433.3023,N,08056.4205,W,2,03,2 + +-- Now disconnect +nxt.BtDisconnect(1) +--codeExampleEnd 23 + +----codeExampleStart 24 ----------------------------------------------------------- +-- Code to parse out a GPGGA string +function parseGPGGA (s) + print( s ) + _,_,time,lat,ns,long,ew,_,_,_,alt = string.find(s, + "([^,]+),([^,]+),([NS]),([^,]+),([EW]),([^,]+),([^,]+),([^,]+),([^,]+)") + + -- If we have a valid string, then update the NXT display + + if( nil ~= alt ) then + print( time,lat,ns,long,ew,alt ) + nxt.DisplayText( string.format( "Time %s", time), 0, 0 ) + nxt.DisplayText( string.format( "Lat %s%s", lat, ns), 0, 8 ) + nxt.DisplayText( string.format( "Long %s%s", long, ew), 0, 16 ) + nxt.DisplayText( string.format( "Alt %sm", alt), 0, 24 ) + end +end + +-- Main routine that looks for strings from the +function btGPS( timeout ) + local t=nxt.TimerRead() + local s + local gps = "" + + nxt.DisplayClear() + + -- And now loop until we get fully formed GPS messages + while( t+timeout > nxt.TimerRead() ) do + + -- Get and available GPS data from the BT device + s = nxt.BtStreamRecv() + + if s then +-- print( "--" .. s ) + + gps = gps .. s + + start = string.find( gps, "\$GP", 2 ) + + while nil ~= start do + + if start > 1 then + -- Here's where we pull out an entire $GP string + + data = string.sub( gps, 1, start-2 ) + _,_,sentence,data = string.find( data, "\$GP(%u+),(.+)" ) + + -- And check to see if it's one we're interested in + + if "GGA" == sentence then + parseGPGGA( data ) + end + + -- Here's where you can parse other strings... + + -- And now skip over the string we just parsed to get ready for + -- the next one + + gps = string.sub( gps, start, -1 ) + + end + start = string.find( gps, "\$GP", 2 ) + end + end + end +end +--codeExampleEnd 24 + +----codeExampleStart 25 ----------------------------------------------------------- +-- Set up the connection to the Navibe GPS +nxt.BtConnect(1,1) -- Device 1, connection 1 +btIdleWait() + +-- Put the strean into binary mode +nxt.BtStreamMode(1) + +-- Do a dummy send to get the NXT to accept streaming data +nxt.BtStreamSend(1,"") + +-- And now start reading for 5 seconds +btGPS(5000) + +-- Results are below, do not paste the following text to the console! +143115.000 4433.3073 N 08056.3969 W 172.7 +143116.000,433.3073,N,08056.3969,W,1,03,2.8,172.7,M,-36.0,M,,0000*65 +143116.000 433.3073 N 08056.3969 W 172.7 +143117.000,4433.3073,N,08056.3969,W,1,03,2.8,172.7,M,-36.0,M,,0000*64 +143117.000 4433.3073 N 08056.3969 W 172.7 +143118.000,4433.3073,N,08056.3969,W,1,03,2.8,172.7,M,-36.0,M,,0000*6B +143118.000 4433.3073 N 08056.3969 W 172.7 +143119.000,4433.3073,N,08056.3969,W,1,03,2.8,172.7,M,-36.0,M,,0000*6A +143119.000 4433.3073 N 08056.3969 W 172.7 +143120.000,4433.3073,N,08056.3969,W,1,03,2.8,172.7,M,-36.0,M,,0000*60 +143120.000 4433.3073 N 08056.3969 W 172.7 +--codeExampleEnd 25 + +----codeExampleStart n ----------------------------------------------------------- +--codeExampleEnd n + +----codeExampleStart n ----------------------------------------------------------- +--codeExampleEnd n + diff --git a/examples/tutorial/pbLuaGyro.lua b/examples/tutorial/pbLuaGyro.lua new file mode 100644 index 0000000..c904339 --- /dev/null +++ b/examples/tutorial/pbLuaGyro.lua @@ -0,0 +1,329 @@ +-- This is the example code file for the webpage at: +-- +-- www.hempeldesigngroup.com/lego/pbLua/tutorial/pbLuaGyro.html + +--codeExampleStart 1 ----------------------------------------------------------- +-- Initialize the Gyro sensor on a port + +function GyroInit(port,active) + nxt.InputSetType(port,0) + + if 0 == (active or 0) then nxt.InputSetState(port,0,0) + else nxt.InputSetState(port,1,0) + end + + nxt.InputSetDir(port,1,1) +end + +-- Read the Gyro sensor no faster than every 4 msec and +-- print the timestamp and result. Stop when we press the +-- orange button + +function GyroTest(port, timeout) + timeout = timeout or 4 + + local sampletick = 0 + local tick, new + + repeat + tick = nxt.TimerRead() + if tick-sampletick >= timeout then + new = nxt.InputGetStatus(port) + print( tick .. " | " .. new ) + sampletick = tick + end + until( 8 == nxt.ButtonRead() ) + + repeat + -- spin here until the button is released! + until( 0 == nxt.ButtonRead() ) + +end + +-- Inititialize the gyro on port 1 to less sensitive mode and print +-- the samples + +GyroInit(1,0) +GyroTest(1) +--codeExampleEnd 1 + +--codeExampleStart 1r ----------------------------------------------------------- +2279974 617 +2279978 617 +2279983 617 +2279994 617 +2279999 617 +2280003 617 +2280007 620 +2280011 614 +2280017 616 +2280030 617 +2280034 617 +2280038 617 +2280042 615 +2280048 617 +2280053 616 +2280067 617 +2280071 617 +2280075 617 +2280079 617 +2280083 617 +--codeExampleEnd 1r + +--codeExampleStart 2 ----------------------------------------------------------- +-- Read the Gyro sensor no faster than every 4 msec and calculate the +-- running average. Each sample is scaled by 64 and the average is +-- weighted by a factor of 128. + +function GyroZero(port, scale, weight) + local sampletick = 0 + local printtick = 0 + local avg = 0 + local fweight = nxt.float( scale*weight ) + + local tick, new + + repeat + local tick = nxt.TimerRead() + + -- update the average no faster than every 4 msec + if tick-sampletick >= 4 then + new = nxt.InputGetStatus(port)*scale + avg = avg - (avg/weight) + new + sampletick = tick + end + + -- print the average no faster than every 256 msec + if tick-printtick >= 256 then + print( tick, avg, avg/fweight ) + printtick = tick + end + + until( 8 == nxt.ButtonRead() ) + + repeat + -- spin here until the button is released! + until( 0 == nxt.ButtonRead() ) + + return( avg ) +end + +-- Inititialize the gyro in port 1 to less sensitive mode and print +-- the running average until the orange button is pressed + +GyroInit(1,0) +=GyroZero(1,64,128) +--codeExampleEnd 2 + +--codeExampleStart 2r ----------------------------------------------------------- +> =GyroZero(1,64,128) +130430 39488 4.820312 +130686 1845131 225.235717 +130942 3031650 370.074462 +131198 3758822 458.840576 +131454 4230305 516.394653 +131710 4532917 553.334594 +131966 4718822 576.028076 +132222 4837786 590.550048 +132478 4917269 600.252563 +132734 4964312 605.995117 +132990 4995417 609.792114 +133246 5015514 612.245361 +133502 5027208 613.672851 +133758 5034958 614.618896 +134014 5039344 615.154296 +134270 5042426 615.530517 +134526 5044153 615.741333 +134782 5045634 615.922119 +135038 5046739 616.057006 +135294 5046977 616.086059 +135550 5047888 616.197265 +135806 5048128 616.226562 +136062 5047896 616.198242 +136318 5048005 616.211547 +136574 5048054 616.217529 +136830 5048699 616.296264 +137086 5048668 616.292480 +--codeExampleEnd 2r + +--codeExampleStart 3 ----------------------------------------------------------- +-- Read the Gyro sensor no faster than every 32 msec and subtract the scaled +-- zero point returned by a previous call to GyroZero(). + +function GyroRead(port,scale,weight,zero) + local sampletick = 0 + local fweight = nxt.float( scale*weight ) + + local tick, new + + repeat + tick = nxt.TimerRead() + + -- take a new sample no faster than every 32 msec + if tick-sampletick >= 32 then + new = nxt.InputGetStatus(port)*scale*weight - zero + print( tick, new, new/fweight ) + sampletick = tick + end + + until( 8 == nxt.ButtonRead() ) + + repeat + -- spin here until the button is released! + until( 0 == nxt.ButtonRead() ) + +end + +-- Inititialize the gyro in port 1 to less sensitive mode and print +-- the running average until the orange button is pressed, then print +-- the zero compensated output until the orange button is pressed +-- +-- Notice how the output of one function is part of the input to +-- the next one... + +GyroInit(1,0) +GyroRead(1,64,128, GyroZero(1,64,128) ) +--codeExampleEnd 3 + +--codeExampleStart 3r ----------------------------------------------------------- +--codeExampleEnd 3r + +--codeExampleStart 4 ----------------------------------------------------------- +-- Read the Gyro sensor no faster than every 16 msec and subtract the scaled +-- zero point returned by a previous call to GyroZero(). Keep a running total +-- of the sum which is the current angular displacement + +function GyroSum(port,scale,weight,zero,period) + local tick = nxt.TimerRead() + local printtick,sampletick = tick,tick + local old, new, sum = 0,0,0 + local fweight = nxt.float( scale*weight*1000 ) + + repeat + tick = nxt.TimerRead() + + -- take a new sample no faster than every period msec + if tick-sampletick >= period then + new = nxt.InputGetStatus(port)*scale*weight - zero + sum = sum + ((new+old)/2)*(tick-sampletick) + + old = new + sampletick = tick + -- print( tick, new, diff, sum, sum/(scale*weight*1000), speed ) + end + + -- print the sum no faster than every 1000 msec + if tick-printtick >= 1000 then + print( sum, sum/fweight ) + printtick = tick + end + + if 1 == nxt.ButtonRead() then + sum = 0 + end + + until( 8 == nxt.ButtonRead() ) + + repeat + -- spin here until the button is released! + until( 0 == nxt.ButtonRead() ) +end + +-- Inititialize the gyro in port 1 to less sensitive mode and print +-- the running average until the orange button is pressed, then print +-- the zero compensated output and total angular displacement until +-- the orange button is pressed +-- +-- Notice how the output of one function is part of the input to +-- the next one... + +GyroInit(1,0) +GyroSum(1,64,128, GyroZero(1,64,128), 32 ) +--codeExampleEnd 4 + +--codeExampleStart 4r ----------------------------------------------------------- +-- Here's the output of the program after the zero point stabilizes. I'm turning +-- the sensor 90 degrees clockwise in a fixture and the indicated angle is -91 +-- degrees. When I return the sensor to the original position the indicated +-- angle is back to the original -1 degrees + +4981144 0.608049 +3260429 0.398001 +1979037 0.241581 +3651252 0.445709 +101220116 12.355970 +652550725 79.657073 +764644166 93.340354 +707941286 86.418617 +15886016 1.939210 +-894571 -0.109200 +510008 0.062256 +1992112 0.243177 +--codeExampleEnd 4r + +--codeExampleStart 5 ----------------------------------------------------------- +-- Balance the robot + +function GyroBalance(port,scale,weight,zero,period,pid) + local tick = nxt.TimerRead() + local printtick,sampletick = tick,tick + local old, new, sum, diff, speed = 0,0,0,0,0 + local fweight = nxt.float( scale*weight ) + + -- Set the motors on port 1 and port 3 to non-regulated + -- brake mode + nxt.OutputSetRegulation(1,0,1) + nxt.OutputSetRegulation(3,0,1) + + repeat + tick = nxt.TimerRead() + + -- take a new sample no faster than every period msec + if tick-sampletick >= period then + new = nxt.InputGetStatus(port)*scale*weight - zero + diff = new - old + sum = sum + ((new+old)/2)*(tick-sampletick) + + speed = (pid.p*new+pid.d*diff+pid.i*(sum/1000))/(scale*weight*256) + speed = nxt.min(100,speed) + speed = nxt.max(speed,-100) + nxt.OutputSetSpeed(1,0x20,speed) + nxt.OutputSetSpeed(3,0x20,speed) + old = new + sampletick = tick + -- print( tick, new, diff, sum, sum/(scale*weight*1000), speed ) + end + + if 1 == nxt.ButtonRead() then + sum = 0 + end + + until( 8 == nxt.ButtonRead() ) + + -- Don't forget to turn off the motors! + + nxt.OutputSetSpeed(1,0,0) + nxt.OutputSetSpeed(3,0,0) + + repeat + -- spin here until the button is released! + until( 0 == nxt.ButtonRead() ) + +end + +-- Inititialize the gyro in port 1 to less sensitive mode and print +-- the running average until the orange button is pressed, then balance +-- the robot +-- +-- Notice how the output of one function is part of the input to +-- the next one... + +pid = {p=180,i=6000,d=100} +GyroInit(1,0) +GyroBalance(1,16,128, GyroZero(1,16,128),32, pid ) +--codeExampleEnd 5 + +--codeExampleStart nr ----------------------------------------------------------- +--codeExampleEnd nr + + diff --git a/examples/tutorial/pbLuaHiTechnicCompass.lua b/examples/tutorial/pbLuaHiTechnicCompass.lua new file mode 100644 index 0000000..7410806 --- /dev/null +++ b/examples/tutorial/pbLuaHiTechnicCompass.lua @@ -0,0 +1,216 @@ +-- This is the example code file for the webpage at: +-- +-- www.hempeldesigngroup.com/lego/pbLua/tutorial/pbLuaHiTechnicCompass.html + +--codeExampleStart 1 ----------------------------------------------------------- +-- Read compass sensor in raw mode until the orange button is pressed + +function CompassRead(port) + -- Set up the port and report on the sensor type (I2C address 2) + checkI2C(port,2) + + -- Read and print the results until the orange button is pressed + repeat + -- Read 8 bytes of data from the sensor + nxt.I2CSendData( port, nxt.I2Cdata(2), 4 ) + waitI2C( port ) + s = nxt.I2CRecvData( port, 4 ) + + -- Break the resulting string into 8 bytes and print the results + c1,c2,c3,c4 = string.byte(s,1,8) + print( string.format( "Result: %3i %3i %3i %3i", + c1, c2, c3, c4 ) ) + until( 8 == nxt.ButtonRead() ) +end + +-- Run the test code... +CompassRead(1) +--codeExampleEnd 1 + +--codeExampleStart 2 ----------------------------------------------------------- +function Spin(speed) + nxt.OutputSetSpeed(2,32,-speed) + nxt.OutputSetSpeed(3,32, speed) +end + +function Move(speed) + nxt.OutputSetSpeed(2,32, speed) + nxt.OutputSetSpeed(3,32, speed) +end + +function Stop() + nxt.OutputSetSpeed(2) + nxt.OutputSetSpeed(3) +end +--codeExampleEnd 2 + +--codeExampleStart 3 ----------------------------------------------------------- +function RunCompass(port) + -- Set up the port and report on the sensor type + checkI2C(port,2) + + nxt.OutputSetRegulation(2,1,1) + nxt.OutputSetRegulation(3,1,1) + + -- Read and print the results until the orange button is pressed + repeat + -- Read 8 bytes of data from the sensor + nxt.I2CSendData( port, nxt.I2Cdata(2), 4 ) + waitI2C( port ) + s = nxt.I2CRecvData( port, 4 ) + + -- Break the resulting string into 8 bytes and print the results + c1,c2,c3,c4 = string.byte(s,1,8) + print( string.format( "Result: %3i %3i %3i %3i", + c1, c2, c3, c4 ) ) + + angle = c1 + + if angle < 3 then + Spin(0) + elseif angle < 90 then + Spin(-60) + elseif angle < 177 then + Spin( 60) + else + Spin(0) + end + + until( 8 == nxt.ButtonRead() ) + + Stop() +end + +-- And run the test code... +RunCompass(1) +--codeExampleEnd 3 + +--codeExampleStart 4 ----------------------------------------------------------- +function RunCompass(port,desired) + -- Initialize the desired direction - remember to divide by two + desired = desired/2 or 0 + + -- Set up the port and report on the sensor type + checkI2C(port,2) + + nxt.OutputSetRegulation(2,1,1) + nxt.OutputSetRegulation(3,1,1) + + -- Read and print the results until the orange button is pressed + repeat + -- Read 8 bytes of data from the sensor + nxt.I2CSendData( port, nxt.I2Cdata(2), 4 ) + waitI2C( port ) + s = nxt.I2CRecvData( port, 4 ) + + -- Break the resulting string into 8 bytes and print the results + c1,c2,c3,c4 = string.byte(s,1,8) + print( string.format( "Result: %3i %3i %3i %3i", + c1, c2, c3, c4 ) ) + + -- Figure out the difference and adjust to a positive value + angle = (c1 - desired + 180) % 180 + + -- angle = c1 + + if angle < 3 then + Spin(0) + elseif angle < 90 then + Spin(-60) + elseif angle < 177 then + Spin( 60) + else + Spin(0) + end + + until( 8 == nxt.ButtonRead() ) + + Stop() +end + +-- And run the test code... +RunCompass(1,90) +--codeExampleEnd 4 + +--codeExampleStart 5 ----------------------------------------------------------- +function RunCompass(port,desired,tolerance) + -- Initialize the desired direction - remember to divide by two + desired = (desired or 0) / 2 + tolerance = (tolerance or 2) / 2 + + -- Set up the port and report on the sensor type + checkI2C(port,2) + + nxt.OutputSetRegulation(2,1,1) + nxt.OutputSetRegulation(3,1,1) + + -- Read and print the results until the orange button is pressed + repeat + -- Read 8 bytes of data from the sensor + nxt.I2CSendData( port, nxt.I2Cdata(2), 4 ) + waitI2C( port ) + s = nxt.I2CRecvData( port, 4 ) + + -- Break the resulting string into 8 bytes and print the results + c1,c2,c3,c4 = string.byte(s,1,8) + print( string.format( "Result: %3i %3i %3i %3i", + c1, c2, c3, c4 ) ) + + -- Figure out the difference and adjust to a positive value + angle = (c1 - desired + 180) % 180 + + if angle < tolerance then + Spin(0) + elseif angle < 90 then + Spin( -(10 + angle) ) + elseif angle < 180-tolerance then + Spin( 10 + 180 - angle ) + else + Spin(0) + end + + until( 8 == nxt.ButtonRead() ) + + Stop() +end + +-- And run the test code... +RunCompass(1,90,2) +--codeExampleEnd 5 + +--codeExampleStart 6 ----------------------------------------------------------- +-- Put the compass in calibrate mode and spin very slowly for 5 seconds + +function CompassCalibrate( port ) + -- Set up the port and report on the sensor type + checkI2C(port,2) + + -- Force the compass into calibrate mode + nxt.I2CSendData( port, string.char( 0x41, 0x43 ), 1 ) + waitI2C( port ) + print( "Calibration Result->" .. string.byte( nxt.I2CRecvData( port, 1 ) ) ) + + -- Force regulation mode so we can get the lowest possible steady speed + nxt.OutputSetRegulation(2,1,1) + nxt.OutputSetRegulation(3,1,1) + + --Now spin slowly for 20 seconds - then stop + Spin( 15 ) + + local t=nxt.TimerRead() + repeat + -- do nothing + until( t+20000 < nxt.TimerRead() ) + + Stop() + + -- Go back to normal mode and check calibration results + nxt.I2CSendData( port, string.char( 0x41, 0x00 ), 1 ) + waitI2C( port ) + print( "Calibration Result->" .. string.byte( nxt.I2CRecvData( port, 1 ) ) ) +end + +-- Running the calibration routine +CompassCalibrate(1) +--codeExampleEnd 6 + diff --git a/examples/tutorial/pbLuaHiTechnicProto.lua b/examples/tutorial/pbLuaHiTechnicProto.lua new file mode 100644 index 0000000..2256117 --- /dev/null +++ b/examples/tutorial/pbLuaHiTechnicProto.lua @@ -0,0 +1,21 @@ +-- This is the example code file for the webpage at: +-- +-- www.hempeldesigngroup.com/lego/pbLua/tutorial/pbLuaI2C.html + +--codeExampleStart 1 ----------------------------------------------------------- +function I2CReadProto(port) + -- Read 14 bytes of data from the sensor + nxt.I2CSendData( port, nxt.I2Cdata[2], 14 ) + waitI2C( port ) + s = nxt.I2CRecvData( port, 14 ) + + -- Break the resulting string into 8 bytes and print the results + c = {string.byte(s,1,14)} + + print( string.format( "Result: %3i %3i %3i %3i %3i %3i %3i %3i", + c[1], c[2], c[3], c[4], c[5], c[6], c[7], c[8] ) ) +end + +-- And using the function - press the orange button on the NXT to stop it +I2CRead(4) + diff --git a/examples/tutorial/pbLuaHiTechnicTrike.lua b/examples/tutorial/pbLuaHiTechnicTrike.lua new file mode 100644 index 0000000..188fbd1 --- /dev/null +++ b/examples/tutorial/pbLuaHiTechnicTrike.lua @@ -0,0 +1,199 @@ +-- This is the example code file for the webpage at: +-- +-- www.hempeldesigngroup.com/lego/pbLua/tutorial/pbLuaHiTechnicTrike.html + +--codeExampleStart 1 ----------------------------------------------------------- +-- Simple test code for reading orange switch + +function TestButton() + + print( "Waiting for keypress" ) + + -- Now spin here until someone presses the orange key + repeat + until( 8 == nxt.ButtonRead() ) + + -- And spin here until someone presses the ornage key again + repeat + print( "Running main routine" ) + until( 8 == nxt.ButtonRead() ) + + print( "Done" ) +end + +-- Running the test +TestButton() +--codeExampleEnd 1 + +--codeExampleStart 2 ----------------------------------------------------------- +-- A better framework for reading the orange switch + +function TestButton() + + print( "Waiting for keypress" ) + + -- Now spin here until someone presses and releases the orange key + local oldKey = 0; + local newKey = 0; + + repeat + oldKey = newKey + newKey = nxt.ButtonRead() + until( oldKey == 8 and newKey == 0 ) + + -- And spin here until someone presses the orange key again + repeat + print( "Running main routine" ) + until( 8 == nxt.ButtonRead() ) + + print( "Done" ) +end + +-- Running the test +TestButton() +--codeExampleEnd 2 + +--codeExampleStart 3 ----------------------------------------------------------- +-- Move the Trike forward for one second...then stop. Note that we're using +-- our orange switch framework more sensibly. You can pass a function to the +-- TestButton() function now! + +function TestTrike( doThis ) + + print( "Waiting for keypress" ) + + -- Now spin here until someone presses and releases the orange key + local oldKey = 0; + local newKey = 0; + + repeat + oldKey = newKey + newKey = nxt.ButtonRead() + until( oldKey == 8 and newKey == 0 ) + + doThis() + + print( "Done" ) +end + +-- Here's the actual test function + +function MoveForward( ) + local ticks = nxt.TimerRead() + + -- Turn the motors on + -- + nxt.OutputSetSpeed(2,32,80) + nxt.OutputSetSpeed(3,32,80) + + -- Stay here for 1 second (1000 ticks) + -- + repeat + -- this space intentionally left blank + until( ticks+1000 < nxt.TimerRead() ) + + -- Turn the motors off + -- + nxt.OutputSetSpeed(2,0,0) + nxt.OutputSetSpeed(3,0,0) +end + +-- Running the test +TestTrike( MoveForward ) +--codeExampleEnd 3 + + +--codeExampleStart 4 ----------------------------------------------------------- +-- A first pass at functions to move the Trike +-- +function TrikeForward( speed ) + nxt.OutputSetSpeed(2,32, speed) + nxt.OutputSetSpeed(3,32, speed) +end + +function TrikeReverse( speed ) + nxt.OutputSetSpeed(2,32,-speed) + nxt.OutputSetSpeed(3,32,-speed) +end + +function TrikeClockwise( speed ) + nxt.OutputSetSpeed(2,32,-speed) + nxt.OutputSetSpeed(3,32, speed) +end + +function TrikeCounterClockwise( speed ) + nxt.OutputSetSpeed(2,32, speed) + nxt.OutputSetSpeed(3,32,-speed) +end + +function TrikeStop() + nxt.OutputSetSpeed(2,0,0) + nxt.OutputSetSpeed(3,0,0) +end +--codeExampleEnd 4 + +--codeExampleStart 5 ----------------------------------------------------------- +-- Make is so we only have to change one function if the motor port changes + +function MoveTrike( leftSpeed, rightSpeed ) + nxt.OutputSetSpeed(2,32,rightSpeed) + nxt.OutputSetSpeed(3,32,leftSpeed) +end + +function TrikeForward( speed ) + MoveTrike( speed, speed ) +end + +function TrikeReverse( speed ) + MoveTrike(-speed,-speed ) +end + +function TrikeClockwise( speed ) + MoveTrike(-speed, speed ) +end + +function TrikeCounterClockwise( speed ) + MoveTrike( speed,-speed ) +end + +function TrikeStop() + MoveTrike( 0, 0 ) +end +--codeExampleEnd 5 + +--codeExampleStart 6 ----------------------------------------------------------- +-- New test function, use the framework from example 3 + +function TimedMoves( ) + local ticks = nxt.TimerRead() + + TrikeForward( 80 ) + + repeat + -- this space intentionally left blank + until( ticks+1000 < nxt.TimerRead() ) + + TrikeReverse( 80 ) + + repeat + -- this space intentionally left blank + until( ticks+2000 < nxt.TimerRead() ) + + TrikeClockwise( 80 ) + + repeat + -- this space intentionally left blank + until( ticks+3000 < nxt.TimerRead() ) + + TrikeCounterClockwise( 80 ) + + repeat + -- this space intentionally left blank + until( ticks+4000 < nxt.TimerRead() ) + + TrikeStop( 80 ) +end + +-- Running the test +TestTrike( TimedMoves ) +--codeExampleEnd 6 diff --git a/examples/tutorial/pbLuaI2C.lua b/examples/tutorial/pbLuaI2C.lua new file mode 100644 index 0000000..5bf8a89 --- /dev/null +++ b/examples/tutorial/pbLuaI2C.lua @@ -0,0 +1,123 @@ +-- This is the example code file for the webpage at: +-- +-- www.hempeldesigngroup.com/lego/pbLua/tutorial/pbLuaI2C.html + +--codeExampleStart 1 ----------------------------------------------------------- +-- Initialize port 4 for I2C communication + + nxt.I2CInitPins(4) + +-- Use a variable to hold the port number + + port = 4 + + nxt.I2CInitPins(port) +--codeExampleEnd 1 + +--codeExampleStart 2 ----------------------------------------------------------- +-- setupI2C() - sets up the specified port to handle an I2C sensor + +function setupI2C(port) + nxt.InputSetType(port,2) + nxt.InputSetDir(port,1,1) + nxt.InputSetState(port,1,1) + + nxt.I2CInitPins(port) +end + +-- Now put the standard I2C messages into the nxt table +nxt.I2Cversion = string.char( 0x02, 0x00 ) +nxt.I2Cproduct = string.char( 0x02, 0x08 ) +nxt.I2Ctype = string.char( 0x02, 0x10 ) +nxt.I2Ccontinuous = string.char( 0x02, 0x41, 0x02 ) +nxt.I2Cdata = string.char( 0x02, 0x42 ) +--codeExampleEnd 2 + +--codeExampleStart 3 ----------------------------------------------------------- +-- Use the ultrasound sensor in port 4, make sure the +-- previous sample has been loaded + +setupI2C(4) + +-- Now send the product string, up to 8 bytes can be sent by the sensor + +nxt.I2CSendData( 4, nxt.I2Cproduct, 8 ) +--codeExampleEnd 3 + +--codeExampleStart 4 ----------------------------------------------------------- +-- Reading the data is simple. Make sure the previous example has been +-- loaded. The = notation is a short form for "print" + +=nxt.I2CRecvData(4) +--codeExampleEnd 4 + +--codeExampleStart 5 ----------------------------------------------------------- +-- waitI2C() - sits in a tight loop until the I2C system goes idle + +function waitI2C( port ) + while( 0 ~= nxt.I2CGetStatus( port ) ) do + end +end +--codeExampleEnd 5 + +--codeExampleStart 6 ----------------------------------------------------------- +-- Put it all together in a function that prints out a report of which +-- sensor is connected to a port + +function checkI2C(port) + setupI2C(port) + + nxt.I2CSendData( port, nxt.I2Cversion, 8 ) + waitI2C( port ) + print( "Version -> " .. nxt.I2CRecvData( port, 8 ) ) + + nxt.I2CSendData( port, nxt.I2Cproduct, 8 ) + waitI2C( port ) + print( "Product ID -> " .. nxt.I2CRecvData( port, 8 ) ) + + nxt.I2CSendData( port, nxt.I2Ctype, 8 ) + waitI2C( port ) + print( "SensorType -> " .. nxt.I2CRecvData( port, 8 ) ) +end + +-- And now run the function to see if it recognizes the sensor +checkI2C(4) + +-- Results are below, do not paste the following text to the console! +Version -> V1.0 +Product ID -> LEGO +SensorType -> Sonar +--codeExampleEnd 6 + +--codeExampleStart 7 ----------------------------------------------------------- +function I2CRead(port) + -- Set up the port and report on the sensor type + checkI2C(port) + + -- Put it into continuous sample mode + nxt.I2CSendData( port, nxt.I2Ccontinuous, 0 ) + waitI2C( port ) + + -- Read and print the results until the orange button is pressed + + repeat + -- Read 8 bytes of data from the sensor + nxt.I2CSendData( port, nxt.I2Cdata, 8 ) + waitI2C( port ) + s = nxt.I2CRecvData( port, 8 ) + + -- Break the resulting string into 8 bytes and print the results + c1,c2,c3,c4,c5,c6,c7,c8 = string.byte(s,1,8) + print( string.format( "Result: %3i %3i %3i %3i %3i %3i %3i %3i", + c1, c2, c3, c4, c5, c6, c7, c8 ) ) + until( 8 == nxt.ButtonRead() ) +end + +-- And using the function - press the orange button on the NXT to stop it +I2CRead(4) +--codeExampleEnd 7 + +--codeExampleStart n ----------------------------------------------------------- +--codeExampleEnd n + + diff --git a/examples/tutorial/pbLuaI2CCommon.lua b/examples/tutorial/pbLuaI2CCommon.lua new file mode 100644 index 0000000..c670f25 --- /dev/null +++ b/examples/tutorial/pbLuaI2CCommon.lua @@ -0,0 +1,86 @@ +-- This is the example code file for the tutorials at: +-- +-- www.hempeldesigngroup.com/lego/pblua/tutorial/ +-- +-- These routines are basic helper functions to make dealing with +-- the I2C sensor ports a bit easier. + +--codeExampleStart 1 ----------------------------------------------------------- +-- setupI2C() - sets up the specified port to handle an I2C sensor + +function setupI2C(port) + nxt.InputSetType(port,11) + nxt.I2CInitPins(port) +end + +-- These are functions that return strings that can be used to +-- access any register in any I2C device. All you need to pass +-- in as parameters are the device address and the register you +-- want to start reading from. +-- +function nxt.I2CReadString( devaddr, regaddr ) + return string.char( devaddr, regaddr ) +end + +-- Now we'll add 4 generic helpers to get strings from the standard +-- registers for use with the LEGO MINDSTORMS NXT sensors +-- +function nxt.I2Cversion( devaddr ) + return nxt.I2CReadString( devaddr, 0x00 ) +end + +function nxt.I2Cproduct( devaddr ) + return nxt.I2CReadString( devaddr, 0x08 ) +end + +function nxt.I2Ctype( devaddr ) + return nxt.I2CReadString( devaddr, 0x10 ) +end + +function nxt.I2Cdata( devaddr ) + return nxt.I2CReadString( devaddr, 0x42 ) +end + +-- waitI2C() - sits in a tight loop until the I2C system goes idle, there +-- are better ways to do this, but this is good enough for +-- now + +function waitI2C( port ) + while( 0 ~= nxt.I2CGetStatus( port ) ) do + end +end + +-- Put it all together in a function that prints out a report of which +-- sensor is connected to a port +-- +-- Recall that nxt.I2CSendData() is capable of write/read operation. In +-- other words, if you want to read 8 bytes of data starting at the +-- ProductId field, just send the correct string and specify 8 bytes in +-- the receive data parameter. All nxt.I2CRecvData() does is read the +-- bytes out of the buffer that the nxt.I2CSendData() filled up! + +function checkI2C( port, devaddr ) + setupI2C(port) + + nxt.I2CSendData( port, nxt.I2Cversion( devaddr ), 8 ) + waitI2C( port ) + print( "Version -> " .. nxt.I2CRecvData( port, 8 ) ) + + nxt.I2CSendData( port, nxt.I2Cproduct( devaddr ), 8 ) + waitI2C( port ) + print( "Product ID -> " .. nxt.I2CRecvData( port, 8 ) ) + + nxt.I2CSendData( port, nxt.I2Ctype( devaddr ), 8 ) + waitI2C( port ) + print( "SensorType -> " .. nxt.I2CRecvData( port, 8 ) ) +end + +-- For an I2C device on port 1, all you need to do is: + +checkI2C(1,2) +--codeExampleEnd 1 + +--codeExampleStart n ----------------------------------------------------------- +--codeExampleEnd n + + diff --git a/examples/tutorial/pbLuaIRLink.lua b/examples/tutorial/pbLuaIRLink.lua new file mode 100644 index 0000000..7bb38ad --- /dev/null +++ b/examples/tutorial/pbLuaIRLink.lua @@ -0,0 +1,131 @@ +-- This is the example code file for the webpage at: +-- +-- www.hempeldesigngroup.com/lego/pbLua/tutorial/pbluaIRLink.html + +--codeExampleStart 1 ----------------------------------------------------------- +-- And use it - make sure you specify the port you have plugged the +-- IR Link in to: + +checkI2C(1,2) + +-- Gives these results: + +-- Version -> ýV1.2 +-- Product ID -> HiTechnc +-- SensorType -> IRLink +--codeExampleEnd 1 + +--codeExampleStart 2 ----------------------------------------------------------- +-- Set up the two strings that we'll use alternately. The only difference +-- is the toggle bit. It will send the combo-direct command on channel 0 to +-- turn OutputA onfwd and OutputB float. The mode byte is 2 for PF motors. +-- If the IR signal is lost, the motors will turn off. +-- +-- Note: Output A is the RED connector, and make sure the IR receiver is +-- set to channel 0! + +s0 = nxt.EncodeIR( 0x011, 2 ) +s1 = nxt.EncodeIR( 0x811, 2 ) + +-- And this is the test function + +function IRTest(port) + -- Set up the port and report on the sensor type + checkI2C(port,2) + + repeat + nxt.I2CSendData( port, s0, 0 ) + waitI2C( port ) + nxt.I2CSendData( port, s1, 0 ) + waitI2C( port ) + until( 8 == nxt.ButtonRead() ) +end + +-- And using the function - press the orange button on the NXT to stop it +IRTest(1) +--codeExampleEnd 2 + +--codeExampleStart 3 ----------------------------------------------------------- +-- Set up strings for brake, fwd, rev for motor A + +b0 = nxt.EncodeIR( 0x013, 2 ) +b1 = nxt.EncodeIR( 0x813, 2 ) + +f0 = nxt.EncodeIR( 0x011, 2 ) +f1 = nxt.EncodeIR( 0x811, 2 ) + +r0 = nxt.EncodeIR( 0x012, 2 ) +r1 = nxt.EncodeIR( 0x812, 2 ) + +-- And this is the test function + +function IRTest(port) + -- Set up the port and report on the sensor type + checkI2C(port,2) + + repeat + if nxt.ButtonRead() == 2 then -- Set up for FWD + s0, s1 = f0, f1 -- multi-assignment, cool! + elseif nxt.ButtonRead() == 4 then -- Set up for REV + s0, s1 = r0, r1 + else -- Set up for BRAKE + s0, s1 = b0, b1 + end + + nxt.I2CSendData( port, s0, 0 ) + waitI2C( port ) + nxt.I2CSendData( port, s1, 0 ) + waitI2C( port ) + until( 8 == nxt.ButtonRead() ) +end + +-- And using the function - press the orange button on the NXT to stop it +IRTest(1) +--codeExampleEnd 3 + +--codeExampleStart 4 ----------------------------------------------------------- +-- Set up strings with toggles for StepFWD, StepRev, Stop for channel 1 + +StepFwd = { nxt.EncodeIR( 0x100, 1 ), nxt.EncodeIR( 0x101, 1 ) } +StepRev = { nxt.EncodeIR( 0x110, 1 ), nxt.EncodeIR( 0x111, 1 ) } +Stop = { nxt.EncodeIR( 0x120, 1 ), nxt.EncodeIR( 0x121, 1 ) } + +-- And this is the test function + +function TrainTest(port) + -- Set up the port and report on the sensor type + checkI2C(port,2) + + local toggle = true + local s = Stop[1] + + repeat + if nxt.ButtonRead() == 2 then -- Set up for FWD + if toggle then s = StepFwd[1] else s = StepFwd[2] end + toggle = not toggle + elseif nxt.ButtonRead() == 4 then -- Set up for REV + if toggle then s = StepRev[1] else s = StepRev[2] end + toggle = not toggle + elseif nxt.ButtonRead() == 1 then -- Set up for Stop + if toggle then s = Stop[1] else s = Stop[2] end + toggle = not toggle + end + + repeat + -- spin here until the button is released! + until( 0 == nxt.ButtonRead() ) + + nxt.I2CSendData( port, s, 0 ) + waitI2C( port ) + + until( 8 == nxt.ButtonRead() ) +end + +-- And using the function - press the orange button on the NXT to stop it +TrainTest(1) +--codeExampleEnd 4 + +--codeExampleStart n ----------------------------------------------------------- +--codeExampleEnd n + + diff --git a/examples/tutorial/pbLuaLCDControl.lua b/examples/tutorial/pbLuaLCDControl.lua new file mode 100644 index 0000000..9060371 --- /dev/null +++ b/examples/tutorial/pbLuaLCDControl.lua @@ -0,0 +1,191 @@ +-- This is the example code file for the webpage at: +-- +-- www.hempeldesigngroup.com/lego/pbLua/tutorial/pbLuaLCDControl.html + +--codeExampleStart 1 ----------------------------------------------------------- +-- Hello World! for the LCD Display + +nxt.DisplayClear() +nxt.DisplayText( "Hello World!" ) +--codeExampleEnd 1 + +--codeExampleStart 2 ----------------------------------------------------------- +-- Writing text to the LCD + +nxt.DisplayClear() + +nxt.DisplayText( "Line 1", 0, 0 ) +nxt.DisplayText( "Line 2", 4, 8 ) +nxt.DisplayText( "Line 3", 8, 16 ) +nxt.DisplayText( "Line 4", 12, 24 ) +nxt.DisplayText( "Line 5", 16, 32 ) +nxt.DisplayText( "Line 6", 20, 40 ) +nxt.DisplayText( "Line 7", 24, 48 ) +nxt.DisplayText( "Line 8", 28, 56 ) +--codeExampleEnd 2 + +--codeExampleStart 3 ----------------------------------------------------------- +-- Writing alternating light and dark text to the LCD + +nxt.DisplayClear() + +nxt.DisplayText( "Line 1", 0, 0, 0 ) +nxt.DisplayText( "Line 2", 4, 8, 1 ) +nxt.DisplayText( "Line 3", 8, 16 ) +nxt.DisplayText( "Line 4", 12, 24, 999 ) +nxt.DisplayText( "Line 5", 16, 32, 0 ) +nxt.DisplayText( "Line 6", 20, 40, -8 ) +nxt.DisplayText( "Line 7", 24, 48, 0 ) +nxt.DisplayText( "Line 8", 28, 56, 1 ) +--codeExampleEnd 3 + +--codeExampleStart 4 ----------------------------------------------------------- +-- Scrolling the LCD + +nxt.DisplayClear() +nxt.DisplayText( "Line 1" ) +nxt.DisplayScroll() +nxt.DisplayText( "Line 2" ) +nxt.DisplayScroll() +nxt.DisplayText( "Line 3" ) +nxt.DisplayScroll() +nxt.DisplayText( "Line 4" ) +nxt.DisplayScroll() +--codeExampleEnd 4 + +--codeExampleStart 5 ----------------------------------------------------------- +-- Demonstration of setting random display pixels + +function RandomDisplayPixel() + local x,y + nxt.DisplayClear() + + for i=1,10000 do + x = nxt.random(100) + y = nxt.random(64) + nxt.DisplayPixel(x,y) + end + +end + +-- Another way of writing this without local variables is + +function RandomDisplayPixel() + nxt.DisplayClear() + + for i=1,10000 do + nxt.DisplayPixel(nxt.random(100),nxt.random(64)) + end + +end + +-- And an even faster way is + +function RandomDisplayPixel() + nxt.DisplayClear() + + local random = nxt.random + local DisplayPixel = nxt.DisplayPixel + + for i=1,10000 do + DisplayPixel(random(100),random(64)) + end + +end +--codeExampleEnd 5 + +--codeExampleStart 6 ----------------------------------------------------------- +-- Reading the Display and Writing it to the Console + +function DumpDisplay() + + -- Set up the header for the XPM file + -- + s = [[ +/* XPM */ +static char * _xpm[] = { +"72 108 2 1", +" c #77cc88", +"* c #000044", ]] + + -- Print the header + -- + print( s ) + + -- Now go ahead and loop through the pixels to print the body of the XPM file + -- + for x=-4,103 do + s = "" + for y=67,-4,-1 do + if nxt.DisplayGetPixel(x,y) then + s = s .. "*" + else + s = s .. " " + end + end + + print( "\"" .. s .. "\"," ) + end + + -- Close off the XPM file + -- + print( "};" ) +end +--codeExampleEnd 6 + +--codeExampleStart 7 ----------------------------------------------------------- +-- main() startup display +nxt.DisplayClear() + +nxt.DisplayText( "Wait for BT", 0, 0, 0 ) +nxt.DisplayText( "Act 11 Upd 01", 0, 48, 0 ) +nxt.DisplayText( "yyyyy Button 0", 0, 56, 0 ) + +DumpDisplay() +-- +--codeExampleEnd 7 + +--codeExampleStart 8 ----------------------------------------------------------- +-- Console Chooser startup display +nxt.DisplayClear() + +nxt.DisplayText( "USB Console", 0, 0, 1 ) +nxt.DisplayText( "BT Console", 0, 8, 0 ) +nxt.DisplayText( "xxxx mV Cells", 0, 24, 0 ) +nxt.DisplayText( "OGEL", 0, 40, 0 ) +nxt.DisplayText( "yyyyy Button 0", 0, 56, 0 ) + +DumpDisplay() +--codeExampleEnd 8 + +--codeExampleStart 9 ----------------------------------------------------------- +-- CDC Init Display +nxt.DisplayClear() + +nxt.DisplayText( "CDC Init", 0, 0, 0 ) +nxt.DisplayText( "yyyyy Button 0", 0, 56, 0 ) + +DumpDisplay() +--codeExampleEnd 9 + +--codeExampleStart 10 ----------------------------------------------------------- +-- CDC Connect Display +nxt.DisplayClear() + +nxt.DisplayText( "CDC Connect", 0, 0, 0 ) +nxt.DisplayText( "00199 Button 0", 0, 56, 0 ) + +DumpDisplay() +--codeExampleEnd 10 + +--codeExampleStart 11 ----------------------------------------------------------- +-- pbLua Version Display +nxt.DisplayClear() + +nxt.DisplayText( "pbLua xx.yy.zz", 0, 0, 0 ) + +DumpDisplay() +--codeExampleEnd 11 + +--codeExampleStart n ----------------------------------------------------------- +--codeExampleEnd n diff --git a/examples/tutorial/pbLuaLinearActuators.lua b/examples/tutorial/pbLuaLinearActuators.lua new file mode 100644 index 0000000..ebeaaca --- /dev/null +++ b/examples/tutorial/pbLuaLinearActuators.lua @@ -0,0 +1,55 @@ +-- This is the example code file for the webpage at: +-- +-- www.hempeldesigngroup.com/lego/pbLua/tutorial/pbLuaLinearActuators.html + +--codeExampleStart 2 ----------------------------------------------------------- +-- Save current Motor position, turn forward while grey button is pressed, +-- then reverse to original position... + +port = 1 +nxt.OutputResetTacho(port,1,1,1) +nxt.OutputSetRegulation(port,1,1) + +function CycleProbe( port, fwd, rev ) + -- Save the starting tacho position + local _,startPos = nxt.OutputGetStatus(port) + + while 0 == nxt.ButtonRead() do + -- Wait for button press + end + + -- Start moving toward the target at half speed + nxt.OutputSetSpeed(port,0x20,fwd) + + while 0 ~= nxt.ButtonRead() do + -- Wait for button release + end + + -- Brake motor now + nxt.OutputSetSpeed(port,0x20,0) + + t = nxt.TimerRead() + while t+400 > nxt.TimerRead() do + -- Let the system settle down + end + + -- Save the current tacho position + local _,endPos = nxt.OutputGetStatus(port) + + print( startPos, endPos, nxt.abs(endPos-startPos) ) + + -- Reverse the motor back to the starting position at full speed + nxt.OutputSetSpeed(port,0x20,-rev,nxt.abs(endPos-startPos)) + + t = nxt.TimerRead() + while t+5000 > nxt.TimerRead() do + -- Let the system settle down + end +end +--codeExampleEnd 2 + + +--codeExampleStart n ----------------------------------------------------------- +--codeExampleEnd n + + diff --git a/examples/tutorial/pbLuaMemory.lua b/examples/tutorial/pbLuaMemory.lua new file mode 100644 index 0000000..bf733c4 --- /dev/null +++ b/examples/tutorial/pbLuaMemory.lua @@ -0,0 +1,167 @@ +-- This is the example code file for the webpage at: +-- +-- www.hempeldesigngroup.com/lego/pbLua/tutorial/pbLuaMemory.html + +--codeExampleStart 1 ----------------------------------------------------------- +-- gcinfo() returns the approximate memory use in K (1024 byte) multiples +>=gcinfo() +16 +-- This tells us we are using about 16*1024 = 16,384 bytes +-- +-- For a more detailed estimate, use collectgarbage(), like this +-- The first value is the approximate memory use in K (1024 byte) multiples +-- and the second value is the fractional K values (mod 1024) +>=collectgarbage("count") +16 403 +-- This tells us we are using about 16*1024 + 403 = 16,787 bytes +-- +--Use the second form when you need a more accurate estimate of RAM usage +--codeExampleEnd 1 + +--codeExampleStart 2 ----------------------------------------------------------- +-- Basic heap information available from pbLua +>=nxt.HeapInfo() +454 443 11 6728 2434 4294 + +-- This tells us two important things: +-- +-- We have 454 "chunks" of memory in our heap, 443 are in use, and 11 are free +-- +-- We have 6728 "blocks" of memory (each 8 bytes), 2434 are in use, 4294 are free +--codeExampleEnd 2 + +--codeExampleStart 3 ----------------------------------------------------------- +>nxt.HeapInfo(1) + +Dumping the umm_heap... +|0x00201fb8|B 0|NB 1|PB 0|Z 1|NF 3096|PF 0| +|0x00201fc0|B 1|NB 43|PB 0|Z 42| +|0x00202110|B 43|NB 68|PB 1|Z 25| +... +|0x00208118|B 3116|NB 3120|PB 3111|Z 4| +|0x00208138|B 3120|NB 3124|PB 3116|Z 4| +|0x00208158|B 3124|NB 3130|PB 3120|Z 6|NF 3148|PF 3096| +|0x00208188|B 3130|NB 3133|PB 3124|Z 3| +|0x002081a0|B 3133|NB 3144|PB 3130|Z 11| +|0x002081f8|B 3144|NB 3148|PB 3133|Z 4| +|0x00208218|B 3148|NB 3149|PB 3144|Z 1|NF 3070|PF 3124| +|0x00208220|B 3149|NB 0|PB 3148|Z 3580|NF 0|PF 136| +Total Entries 607 Used Entries 563 Free Entries 44 +Total Blocks 6728 Used Blocks 3072 Free Blocks 3656 + +-- This somewhat truncated wiew of the heap dump lets you figure out exactly +-- how fragmented the heap is - if you are so inclined +--codeExampleEnd 3 + +--codeExampleStart 4 ----------------------------------------------------------- +-- Dump the contents of the "debug" table using the pairs() iterator, the +-- following output is slightly altered for readability... +>for k,v in pairs(debug) do print(k,v) end +getupvalue function:0x204214 +debug function:0x2040ec +sethook function:0x204264 +getmetatable function:0x2041fc +gethook function:0x20411c +setmetatable function:0x2042d4 +setlocal function:0x20429c +traceback function:0x204324 +setfenv function:0x20424c +getinfo function:0x204154 +setupvalue function:0x2042ec +getlocal function:0x20418c +getregistry function:0x2041c4 +getfenv function:0x204104 +--codeExampleEnd 4 + +--codeExampleStart 5 ----------------------------------------------------------- +-- This example shows the RAM savings we get by eliminating the debug table +-- +-- First, do a round of garbage collection... +=collectgarbage() + +-- Now print out the current memory usage... +=collectgarbage("count") +16 776 + +-- That's (16*1024)+776 = 17160 bytes in use +-- +-- Now let's delete the debug table, do a round of garbage collection, and +-- print the new memory usage... + +debug=nil +=collectgarbage() + +-- Now print out the current memory usage... +=collectgarbage("count") +15 938 + +-- That's (15*1024)+939 = 16299 bytes in use +--codeExampleEnd 5 + +--codeExampleStart 6 ----------------------------------------------------------- +-- Now delete the table, string, and nxt libraries and see how much RAM is +-- in use... +table=nil +string=nil +nxt=nil +=collectgarbage() + +-- Now print out the current memory usage... +=collectgarbage("count") +7 698 + +-- That's (7*1024)+698 = 7866 bytes in use - a pretty decent savings! +--codeExampleEnd 6 + +--codeExampleStart 7 ----------------------------------------------------------- +-- What does require() return? +>=require() +table:0x204c74 + +-- It's a table, so let's put the table through an iterator to what's in it... +>for k,v in pairs(require()) do print(k,v) end +1 all +2 table +3 string +4 debug +5 nxt_misc +6 nxt_bt +7 nxt_math +8 nxt_file +9 nxt_output +10 nxt_display +11 nxt_i2c +12 nxt_rs485 +13 nxt_input +14 nxt_sound +--codeExampleEnd 7 + +--codeExampleStart 8 ----------------------------------------------------------- +-- First, let's dump debug - it should give an error since it's gone... +for k,v in pairs(debug) do print(k,v) end +tty: stdin:1: bad argument #1 to 'pairs' (table expected, got nil) + +-- Now let's load up the debug library and dump it. I've reformatted the +-- output slightly... +require("debug") +for k,v in pairs(debug) do print(k,v) end +getupvalue function:0x204ccc +debug function:0x203274 +sethook function:0x204c7c +getmetatable function:0x204ce4 +gethook function:0x203734 +setmetatable function:0x20315c +setlocal function:0x204c44 +traceback function:0x20310c +setfenv function:0x204c94 +getinfo function:0x2036fc +setupvalue function:0x203144 +getlocal function:0x204d54 +getregistry function:0x204d1c +getfenv function:0x20374c +--codeExampleEnd 8 + +--codeExampleStart n ----------------------------------------------------------- +--codeExampleEnd n + + diff --git a/examples/tutorial/pbLuaRFIDSensor.lua b/examples/tutorial/pbLuaRFIDSensor.lua new file mode 100644 index 0000000..168dd62 --- /dev/null +++ b/examples/tutorial/pbLuaRFIDSensor.lua @@ -0,0 +1,290 @@ +-- This is the example code file for the webpage at: +-- +-- www.hempeldesigngroup.com/lego/pbLua/tutorial/pbluaIRLink.html + +--codeExampleStart 1 ----------------------------------------------------------- +-- And use it - make sure you specify the port you have plugged the +-- IR Link in to port 1 + +nxt.RFIDdummy = string.char( 0x04, 0x00, 0x00 ) +nxt.RFIDboot = string.char( 0x04, 0x41, 0x81 ) +nxt.RFIDstart = string.char( 0x04, 0x41, 0x83 ) +nxt.RFIDstatus = string.char( 0x04, 32 ) + +setupI2C(1) + +nxt.I2CSendData( 1, nxt.RFIDboot, 0 ) +nxt.I2CSendData( 1, nxt.RFIDstart, 0 ) + +nxt.I2CSendData( 1, nxt.RFIDdummy, 0 ) +waitI2C( 1 ) +checkI2C(1, 4) + +-- Gives these results: + +-- Version -> V1.0 +-- Product ID -> CODATEX +-- SensorType -> RFID +--codeExampleEnd 1 + +--codeExampleStart 2 ----------------------------------------------------------- +-- Turn on the RFID sensor and take a single reading, then print the result + +nxt.RFIDsingle = string.char( 0x04, 0x41, 0x01 ) + +-- And this is the test function + +function singleRFID(port,delay) + -- Do a single reading + nxt.I2CSendData( port, nxt.RFIDdummy, 0 ) + waitI2C( port ) + + nxt.I2CSendData( port, nxt.RFIDsingle, 0 ) + waitI2C( port ) + + -- wait delay msec ... + + local t = nxt.TimerRead() + while t+delay > nxt.TimerRead() do + -- This space intentionally left blank! + end + + nxt.I2CSendData( port, nxt.I2Cdata[4], 5 ) + waitI2C( port ) + local result = nxt.I2CRecvData( port, 5 ) + + -- Break the resulting string into 5 bytes and print them + + local c1,c2,c3,c4,c5 = string.byte(result,1,5) + + print( string.format( "Result: %02x %02x %02x %02x %02x", + c1, c2, c3, c4, c5 ) ) +end + +-- And using the function +singleRFID(1,200) +singleRFID(1,200) +singleRFID(1,200) + +--codeExampleEnd 2 + +--codeExampleStart 3 ----------------------------------------------------------- +-- Turn on the RFID sensor and take continuous readings, then print results +-- if consecutive readings are different and non-null... + +nxt.RFIDcontinuous = string.char( 0x04, 0x41, 0x02 ) +nxt.RFIDstatus = string.char( 0x04, 0x32 ) + +-- These strings represent bad RFID results + +nullRFID = string.char( 0x00, 0x00, 0x00, 0x00, 0x00 ) + +-- And this is the test function + +function contRFID(port,delay) + -- wake up the sensor + nxt.I2CSendData( port, nxt.RFIDdummy, 0 ) + waitI2C( port ) + + local oldResult, result = "", "" + local status = 0 + + repeat + oldResult = result + + -- Do continuous reading + nxt.I2CSendData( port, nxt.RFIDcontinuous, 0 ) + waitI2C( port ) + + -- Check status, and wait if it's 0 + nxt.I2CSendData( port, nxt.RFIDstatus, 1 ) + waitI2C( port ) + status = string.byte( nxt.I2CRecvData( port, 1 ) ) + if 0 == status then + -- wait 250 msec + local t = nxt.TimerRead() + while t+250 > nxt.TimerRead() do + -- This space intentionally left blank! + end + end + + -- wait delay msec before reading sensor + local t = nxt.TimerRead() + while t+delay > nxt.TimerRead() do + -- This space intentionally left blank! + end + + nxt.I2CSendData( port, nxt.I2Cdata[4], 5 ) + waitI2C( port ) + result = nxt.I2CRecvData( port, 5 ) + + -- print results if valid and different from previous + + if ((result ~= nullRFID) and (result ~= oldResult)) then + -- Break the resulting string into 5 bytes and print them + + local c1,c2,c3,c4,c5 = string.byte(result,1,5) + + print( string.format( "Result: %02x %02x %02x %02x %02x", + c1, c2, c3, c4, c5 ) ) + end + + until( 8 == nxt.ButtonRead() ) +end + +-- And using the function +contRFID(1,200) +--codeExampleEnd 3 + +--codeExampleStart 4 ----------------------------------------------------------- +> contRFID(1,100) +Result: 50 00 2a 18 b6 +Result: 50 00 29 d8 3b +Result: 50 00 2a 18 b6 +Result: 04 16 1d 5f de + +--codeExampleEnd 4 + +--codeExampleStart 5 ----------------------------------------------------------- +-- Here are statements that you can run one at a time to sound tones: +nxt.SoundTone(440) +nxt.SoundTone(880) +nxt.SoundTone(110) + +-- Here is a way to assign the tones to specific badges from the +-- previous examples. First start with a blank table: + +badgeAction = {} + +-- Next, index the table with a string and store compiled tone function: + +badgeAction[ "low" ] = + loadstring( "nxt.SoundTone(440)" ) + + +badgeAction[ "high" ] = + loadstring( "nxt.SoundTone(880)" ) + +-- And test the array one element at a time as a function: + +badgeAction["low"]() -- should sound a low tone + +badgeAction["high"]() -- should sound a high tone +--codeExampleEnd 5 + +--codeExampleStart 5r ----------------------------------------------------------- +-- What happens with a non-existent index? + +badgeAction["dummy"]() + +tty: stdin:1: attempt to call field 'dummy' (a nil value) +--codeExampleEnd 5r + +--codeExampleStart 6 ----------------------------------------------------------- +-- Set up a metatable, it can have any name we want, but this is a consistent +-- style if the metatable is for one table only... + +badgeAction.mt = {} + +-- Now specify what to do when we index a non=existent value... + +badgeAction.mt.f = loadstring( "nxt.SoundTone(110)" ) +badgeAction.mt.__index = function() return badgeAction.mt.f end +--codeExampleEnd 6 + +--codeExampleStart 6r ----------------------------------------------------------- +-- And test it out... + +badgeAction["dummy"]() + +tty: stdin:1: attempt to call field 'dummy' (a nil value) +--codeExampleEnd 6r + +--codeExampleStart 7 ----------------------------------------------------------- +-- Assign the new metatable to the original table + +setmetatable(badgeAction, badgeAction.mt) + +-- And test it out... + +badgeAction["dummy"]() +--codeExampleEnd 7 + +--codeExampleStart 8 ----------------------------------------------------------- +-- Example code to sound tones when badges are recognized +-- +-- First, enter table values for the badges we want associated with tones + +badgeAction[ string.char( 0x50, 0x00, 0x2a, 0x18, 0xb6 ) ] = + loadstring( "nxt.SoundTone(440)" ) + +badgeAction[ string.char( 0x50, 0x00, 0x29, 0xd8, 0x3b ) ] = + loadstring( "nxt.SoundTone(880)" ) + +-- Make sure that you've set up the metatable from the previous example... +-- +-- Then load up this new function. + +function badgeTone(port,delay) + -- wake up the sensor + nxt.I2CSendData( port, nxt.RFIDdummy, 0 ) + waitI2C( port ) + + local oldResult, result = "", "" + local status = 0 + + repeat + oldResult = result + + -- Do continuous reading + nxt.I2CSendData( port, nxt.RFIDcontinuous, 0 ) + waitI2C( port ) + + -- Check status, and wait if it's 0 + nxt.I2CSendData( port, nxt.RFIDstatus, 1 ) + waitI2C( port ) + status = string.byte( nxt.I2CRecvData( port, 1 ) ) + if 0 == status then + -- wait 250 msec + local t = nxt.TimerRead() + while t+250 > nxt.TimerRead() do + -- This space intentionally left blank! + end + end + + -- wait delay msec before reading sensor + local t = nxt.TimerRead() + while t+delay > nxt.TimerRead() do + -- This space intentionally left blank! + end + + nxt.I2CSendData( port, nxt.I2Cdata[4], 5 ) + waitI2C( port ) + result = nxt.I2CRecvData( port, 5 ) + + -- print results if valid and different from previous + + if ((result ~= nullRFID) and (result ~= oldResult)) then + -- Break the resulting string into 5 bytes and print them + + local c1,c2,c3,c4,c5 = string.byte(result,1,5) + + print( string.format( "Result: %02x %02x %02x %02x %02x", + c1, c2, c3, c4, c5 ) ) + + -- And don't forget to sound the tone! + badgeAction[ result ]() + + end + + until( 8 == nxt.ButtonRead() ) +end + +-- And using the function +badgeTone(1,200) +--codeExampleEnd 8 +-- +--codeExampleStart n ----------------------------------------------------------- +--codeExampleEnd n + + diff --git a/examples/tutorial/pbLuaRequire.lua b/examples/tutorial/pbLuaRequire.lua new file mode 100644 index 0000000..88fcba0 --- /dev/null +++ b/examples/tutorial/pbLuaRequire.lua @@ -0,0 +1,223 @@ +-- This is the example code file for the webpage at: +-- +-- www.hempeldesigngroup.com/lego/pbLua/tutorial/pbLuaRequire.html + +--codeExampleStart 1 ----------------------------------------------------------- + +-- "all" +-- +nxt_names = { + "nxt_misc" + , "nxt_bt" + , "nxt_file" + , "nxt_output" + , "nxt_display" + , "nxt_i2c" + , "nxt_rs485" + , "nxt_input" + , "nxt_sound" } + +-- , "nxt_math" + +for _,s in pairs(nxt_names) do print(s) end + +for k,v in pairs(list()) do print(k,v) end +for k,v in pairs(list(nil)) do print(k,v) end +for k,v in pairs(list("foo")) do print(k,v) end + +for _,s in pairs(nxt_names) do + print( "----" .. s .. "----" ) + for k,v in pairs(list(s)) do print(k,v) end +end +--codeExampleEnd 1 + +require() +require(nil) +require("foo") + +for _,s in pairs(nxt_names) do + print( "----" .. s .. "----" ) + require(s) +end + +unload() +unload(nil) +unload("foo") + +for _,s in pairs(nxt_names) do + print( "----" .. s .. "----" ) + unload(s) +end + +for k,v in pairs(_G) do print(k,v) end + +for k,v in pairs(nxt) do print(k,v) end + +for _,s in pairs(nxt_names) do + print( "----" .. s .. "----" ) + require(s) +end + + , "nxt_bt" + , "nxt_sound" } + +require("all") + +require("nxt_misc") +require("nxt_bt") +require("nxt_file") +require("nxt_output") +require("nxt_display") +require("nxt_i2c") +require("nxt_rs485") +require("nxt_input") +require("nxt_sound") + + +for k,v in pairs(string) do nxt[k]=nil end +for k,v in pairs(table) do nxt[k]=nil end +for k,v in pairs(debug) do nxt[k]=nil end + +string=nil +table=nil +debug=nil + + +=collectgarbage("count") +=collectgarbage() +=collectgarbage("count") +=collectgarbage() +=collectgarbage("count") +=collectgarbage() +=collectgarbage("count") +=collectgarbage() +=collectgarbage("count") +=collectgarbage() +=collectgarbage("count") +=collectgarbage() +=collectgarbage("count") +=collectgarbage() +=collectgarbage("count") + + +for k,v in pairs(nxt) do nxt[k]=nil end +for k,v in pairs(foo) do foo[k]=nil end + + +foo = {} +for k,v in pairs(nxt) do foo[k]=nxt[k] end + +nxt=nil + + +=collectgarbage("count") +=collectgarbage() +=collectgarbage("count") +=collectgarbage() +=collectgarbage("count") +=collectgarbage() +=collectgarbage("count") +=collectgarbage() +=collectgarbage("count") +=collectgarbage() +=collectgarbage("count") +=collectgarbage() +=collectgarbage("count") +=collectgarbage() +=collectgarbage("count") + + +for k,v in pairs(_G) do print(k,v) end + +nxt_names = { + "nxt_misc" + , "nxt_file" + , "nxt_output" + , "nxt_display" + , "nxt_i2c" + , "nxt_rs485" + , "nxt_input" + , "nxt_file" + , "nxt_output" + , "nxt_display" + , "nxt_i2c" + , "nxt_rs485" + , "nxt_input" + , "nxt_file" + , "nxt_output" + , "nxt_display" + , "nxt_i2c" + , "nxt_rs485" + , "nxt_input" + , "nxt_file" + , "nxt_output" + , "nxt_display" + , "nxt_i2c" + , "nxt_rs485" + , "nxt_input" + , "nxt_file" + , "nxt_output" + , "nxt_display" + , "nxt_i2c" + , "nxt_rs485" + , "nxt_input" + , "nxt_file" + , "nxt_output" + , "nxt_display" + , "nxt_i2c" + , "nxt_rs485" + , "nxt_input" + , "nxt_file" + , "nxt_output" + , "nxt_display" + , "nxt_i2c" + , "nxt_rs485" + , "nxt_input" + , "nxt_file" + , "nxt_output" + , "nxt_display" + , "nxt_i2c" + , "nxt_rs485" + , "nxt_input" + , "nxt_file" + , "nxt_output" + , "nxt_display" + , "nxt_i2c" + , "nxt_rs485" + , "nxt_input" + , "nxt_file" + , "nxt_output" + , "nxt_display" + , "nxt_i2c" + , "nxt_rs485" + , "nxt_input" + } + + +for _,s in pairs(nxt_names) do + print( "----" .. s .. "----" ) + require(s) +end + +for k,v in pairs(nxt) do nxt[k]=nil end +nxt=nil + +=collectgarbage("count") +=collectgarbage() +=collectgarbage("count") +=collectgarbage() +=collectgarbage("count") +=collectgarbage() +=collectgarbage("count") +=collectgarbage() +=collectgarbage("count") +=collectgarbage() +=collectgarbage("count") +=collectgarbage() +=collectgarbage("count") +=collectgarbage() +=collectgarbage("count") + +--codeExampleStart n ----------------------------------------------------------- +--codeExampleEnd n + diff --git a/examples/tutorial/pbLuaSensors.lua b/examples/tutorial/pbLuaSensors.lua new file mode 100644 index 0000000..0c8b613 --- /dev/null +++ b/examples/tutorial/pbLuaSensors.lua @@ -0,0 +1,303 @@ +-- This is the example code file for the webpage at: +-- +-- www.hempeldesigngroup.com/lego/pbLua/tutorial/pbLuaSensors.html + +--codeExampleStart 1 ----------------------------------------------------------- +-- Read touch sensor until the orange button is pressed +function TouchRead(port) + + nxt.InputSetType(port,1) + + repeat + print( nxt.TimerRead(), nxt.InputGetStatus(port) ) + until( 8 == nxt.ButtonRead() ) +end + +-- And using the function - press the orange button on the NXT to stop it +TouchRead(1) +--codeExampleEnd 1 + +--codeExampleStart 1a ----------------------------------------------------------- +-- Read touch sensor in boolean mode until the orange button is pressed +function TouchRead(port) + + nxt.InputSetType(port,1,0x20) + + repeat + print( nxt.TimerRead(), nxt.InputGetStatus(port) ) + until( 8 == nxt.ButtonRead() ) +end + +-- And using the function - press the orange button on the NXT to stop it +TouchRead(1) +--codeExampleEnd 1a + +--codeExampleStart 1b ----------------------------------------------------------- +-- Read touch sensor in transition count mode until the orange button is pressed +function TouchRead(port) + + nxt.InputSetType(port,1,0x40) + + repeat + print( nxt.TimerRead(), nxt.InputGetStatus(port) ) + until( 8 == nxt.ButtonRead() ) +end + +-- And using the function - press the orange button on the NXT to stop it +TouchRead(1) +--codeExampleEnd 1b + +--codeExampleStart 1c ----------------------------------------------------------- +-- Read touch sensor in period count mode until the orange button is pressed +function TouchRead(port) + + nxt.InputSetType(port,1,0x60) + + repeat + print( nxt.TimerRead(), nxt.InputGetStatus(port) ) + until( 8 == nxt.ButtonRead() ) +end + +-- And using the function - press the orange button on the NXT to stop it +TouchRead(1) +--codeExampleEnd 1c + + +--codeExampleStart 2 ----------------------------------------------------------- +-- Read touch sensor until the orange button is pressed - note that it's a +-- lot easier to simply read the sensor in boolean mode... + +function TouchChange(port, thresh) + + nxt.InputSetType(port,0) + + local oldState,newState + + repeat + if( thresh < nxt.InputGetStatus( port ) ) then + newState = 0 + else + newState = 1 + end + + if newState ~= oldState then + print( nxt.TimerRead(), newState ) + oldState = newState + end + + until( 8 == nxt.ButtonRead() ) +end + +-- And using the function - press the orange button on the NXT to stop it +TouchChange(1,500) +--codeExampleEnd 2 + +--codeExampleStart 3 ----------------------------------------------------------- +-- Read sound sensor until the orange button is pressed +function SoundRead(port) + + nxt.InputSetType(port,0,7) + + repeat + print( nxt.TimerRead(), nxt.InputGetStatus(port) ) + until( 8 == nxt.ButtonRead() ) +end + +-- And using the function - press the orange button on the NXT to stop it +SoundRead(2) +--codeExampleEnd 3 + +--codeExampleStart 4 ----------------------------------------------------------- +-- Read sound sensor and scale the results the hard way +function SoundScale(port,sensitive) + + sensitive = sensitive or 0 + + if 0 == sensitive then nxt.InputSetType(port,8) + else nxt.InputSetType(port,7) + end + + repeat + local raw = nxt.InputGetStatus(port) + + -- Check if raw value is less than minimum, adjust if needed + if raw < 162 then raw = 0 + else raw = raw - 162 + end + + -- Scale the result + raw = (raw*100)/83 + + -- Check if raw value is greater than maximum, adjust if needed + if raw > 1023 then raw = 1023 + end + + -- Invert the raw value + raw = 1023 - raw + + -- Make a string that represents the volume... + + print( nxt.TimerRead(), string.rep("*", raw/16 ) ) + until( 8 == nxt.ButtonRead() ) +end + +-- And using the function - press the orange button on the NXT to stop it +SoundScale(2,0) +--codeExampleEnd 4 + +--codeExampleStart 4a ----------------------------------------------------------- +-- Read sound sensor and scale the results the easy way +function SoundScale(port,sensitive) + + sensitive = sensitive or 0 + + if 0 == sensitive then nxt.InputSetType(port,8,0x80) + else nxt.InputSetType(port,7,0x80) + end + + repeat + local _,_,_,raw = nxt.InputGetStatus(port) + + print( nxt.TimerRead(), string.rep("*", raw/2) ) + until( 8 == nxt.ButtonRead() ) +end + +-- And using the function - press the orange button on the NXT to stop it +SoundScale(2,0) +--codeExampleEnd 4a + +--codeExampleStart 5 ----------------------------------------------------------- +-- Read light sensor until the orange button is pressed +function LightRead(port,active) + + active = active or 0 + + if 0 == active then nxt.InputSetType(port,6,0x80) + else nxt.InputSetType(port,5,0x80) + end + + repeat + print( nxt.TimerRead(), nxt.InputGetStatus(port) ) + until( 8 == nxt.ButtonRead() ) +end + +-- And using the function - press the orange button on the NXT to stop it +LightRead(3,0) +--codeExampleEnd 5 + +--codeExampleStart 6 ----------------------------------------------------------- +-- Read light sensor until the orange button is pressed +function Barcode(port,active,threshold,guard) + + nxt.InputSetType(port,0) + + active = active or 0 + + if 0 == active then nxt.InputSetState(port,0,0) + else nxt.InputSetState(port,1,0) + end + + nxt.InputSetDir(port,1,1) + + local oldState = 1 + local newState = 1 + local light + + repeat + light = nxt.InputGetStatus(port) + + if light > (threshold + guard) then newState = 0 end + if light < (threshold + guard) then newState = 1 end + + if newState ~= oldState then + print( nxt.TimerRead(), newState ) + oldState = newState + end + + until( 8 == nxt.ButtonRead() ) +end + +-- And here's how to call the function. You may need to try this +-- with different values for the threshold and guard +Barcode(3,1,700,20) +--codeExampleEnd 6 + +--codeExampleStart 7a ----------------------------------------------------------- +-- The color sensor turns on steady red... +function RedSensor(port) + + nxt.InputSetType(port,14) + + repeat + print( nxt.TimerRead(), nxt.InputGetStatus(port) ) + + until( 8 == nxt.ButtonRead() ) +end +-- And using the function - press the orange button on the NXT to stop it +RedSensor(3) +--codeExampleEnd 7a + +--codeExampleStart 7b ----------------------------------------------------------- +-- The color sensor turns on steady green... +function GreenSensor(port) + + nxt.InputSetType(port,15) + + repeat + print( nxt.TimerRead(), nxt.InputGetStatus(port) ) + + until( 8 == nxt.ButtonRead() ) +end +-- And using the function - press the orange button on the NXT to stop it +GreenSensor(3) +--codeExampleEnd 7b + +--codeExampleStart 7c ----------------------------------------------------------- +-- The color sensor turns on steady blue... +function BlueSensor(port) + + nxt.InputSetType(port,16) + + repeat + print( nxt.TimerRead(), nxt.InputGetStatus(port) ) + + until( 8 == nxt.ButtonRead() ) +end +-- And using the function - press the orange button on the NXT to stop it +BlueSensor(3) +--codeExampleEnd 7c + +--codeExampleStart 7d ----------------------------------------------------------- +-- The color sensor is an active full color device - must use pct mode +function FullSensor(port) + + nxt.InputSetType(port,13,0x80) + + repeat + print( nxt.TimerRead(), nxt.InputGetStatus(port) ) + + until( 8 == nxt.ButtonRead() ) +end +-- And using the function - press the orange button on the NXT to stop it +FullSensor(3) +--codeExampleEnd 7d +-- +--codeExampleStart 7e ----------------------------------------------------------- +-- The color sensor is a passive light sensor - must use pct mode +function NoneSensor(port) + + nxt.InputSetType(port,17,0x80) + + repeat + print( nxt.TimerRead(), nxt.InputGetStatus(port) ) + + until( 8 == nxt.ButtonRead() ) +end +-- And using the function - press the orange button on the NXT to stop it +NoneSensor(3) +--codeExampleEnd 7e +-- +--codeExampleStart n ----------------------------------------------------------- +--codeExampleEnd n + + diff --git a/examples/tutorial/pbLuaSerialFlash.lua b/examples/tutorial/pbLuaSerialFlash.lua new file mode 100644 index 0000000..4894ee9 --- /dev/null +++ b/examples/tutorial/pbLuaSerialFlash.lua @@ -0,0 +1,68 @@ +-- Daniel, here's a full example that works on stock pbLua +-- as currently distributed on my website + +-- Define a function to set up an I2C port + +function setupI2C(port) + nxt.InputSetType(port,2) + nxt.InputSetDir(port,1,1) + nxt.InputSetState(port,1,1) + + nxt.I2CInitPins(port) +end + +-- And a function to wait for the I2C bus to go idle + +function waitI2C( port ) + while( 0 ~= nxt.I2CGetStatus( port ) ) do + end +end + +-- Set up the I2C FLASH memory to be on port 1 + +port = 1 + +setupI2C(port) + +-- Here's where we write data to the I2C FLASH. The bytes +-- are ordered like this: +-- +-- A0 is the device code and address +-- 0x45 0x98 are the address bytes in big endian format +-- 11 12 13 14 are the bytes to write +-- +-- Since the total write string can be only 16 bytes long, you +-- can only write 13 bytes of data, so round it down to 8 or 12 +-- +-- What makes this a write? The 3rd parameter to the I2CSendData +-- function is 0, which means no restart! + +memstr = string.char( 0xA0, 0x45, 0x98, 21, 22, 23, 24 ) +nxt.I2CSendData( port, memstr, 0 ) +waitI2C( port ) + +-- Here's where we read data from the I2C FLASH. The bytes +-- are ordered like this: +-- +-- A0 is the device code and address +-- 0x45 0x98 are the address bytes in big endian format +-- 11 12 13 14 are the bytes to write +-- +-- Since the total read string can be only 16 bytes long, you +-- can read up to 16 bytes at a time (I think) + +memstr = string.char( 0xA0, 0x45, 0x98 ) +nxt.I2CSendData( port, memstr, 4 ) +waitI2C( port ) + +-- Here's where we read the I2C buffer and print the results +-- byte by byte... + +print( string.byte(nxt.I2CRecvData(port),1,4) ) + +for i=1,1024 do + memstr = string.char( 0xA0, 0x45, 0x98 ) + nxt.I2CSendData( port, memstr, 16 ) + waitI2C( port ) +-- print( string.byte(nxt.I2CRecvData(port),1,16) ) +end diff --git a/examples/tutorial/pbLuaStartupMain.png b/examples/tutorial/pbLuaStartupMain.png new file mode 100644 index 0000000..2fefda0 Binary files /dev/null and b/examples/tutorial/pbLuaStartupMain.png differ diff --git a/examples/tutorial/pbLuaStartupMain.xpm b/examples/tutorial/pbLuaStartupMain.xpm new file mode 100644 index 0000000..e4f2e3d --- /dev/null +++ b/examples/tutorial/pbLuaStartupMain.xpm @@ -0,0 +1,114 @@ +/* XPM */ +static char * _xpm[] = { +"72 108 2 1", +" c #77cc88", +"* c #000044", +" ", +" ", +" ", +" ", +" ** ****** ******* ", +" * * * * * ", +" * * * * ** ", +" * * * * * ", +" **** ****** ******* ", +" ", +" ** *** * ", +" * * * * * * * ", +" * * * * * * * ", +" * * * * * * * ", +" **** * **** ", +" ", +" ** * ", +" * * ****** * * ", +" * * * * ***** * ", +" * * * * ", +" **** * ", +" ", +" ** * ", +" * * ****** ", +" * * * * ", +" * * * ", +" **** * ", +" ", +" ** ", +" * * * * ", +" * * ******* ", +" * * * ", +" **** ", +" ", +" * ", +" * * ****** ", +" ******* * * ", +" * * ", +" * ", +" ", +" ******* *** ", +" * * * * * ", +" * * * * * ", +" * * * * * ", +" ** ** *** ", +" ", +" **** ****** ***** ", +" * * * ", +" * * * ", +" * * * ", +" ***** ****** * ", +" ", +" * ***** ", +" ****** * * ", +" * * * * ", +" * * * ", +" * * ", +" ", +" * *** ******* ", +" ****** * * * * * ", +" * * * * * * * ", +" * * * * * * ", +" * ******* ** ** ", +" ", +" *** * ", +" * * * ", +" * * ******* ", +" * * * ", +" *** * ", +" ", +" ***** ***** ", +" * * * * ", +" * * * * ", +" * * * * ", +" **** ***** ", +" ", +" ", +" * * ", +" ******* ", +" * ", +" ", +" ", +" ***** ", +" * * * ", +" * * * ", +" * * * ", +" ***** ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +}; diff --git a/examples/tutorial/pbLuaVersion.png b/examples/tutorial/pbLuaVersion.png new file mode 100644 index 0000000..39730e8 Binary files /dev/null and b/examples/tutorial/pbLuaVersion.png differ diff --git a/examples/tutorial/pbLuaVersion.xpm b/examples/tutorial/pbLuaVersion.xpm new file mode 100644 index 0000000..4197c7a --- /dev/null +++ b/examples/tutorial/pbLuaVersion.xpm @@ -0,0 +1,114 @@ +/* XPM */ +static char * _xpm[] = { +"72 108 2 1", +" c #77cc88", +"* c #000044", +" ", +" ", +" ", +" ", +" ***** ", +" * * ", +" * * ", +" * * ", +" * ", +" ", +" ******* ", +" * * ", +" * * ", +" * * ", +" *** ", +" ", +" ******* ", +" * ", +" * ", +" * ", +" * ", +" ", +" **** ", +" * ", +" * ", +" * ", +" ***** ", +" ", +" * ", +" * * * ", +" * * * ", +" * * * ", +" **** ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" * * ", +" * * ", +" * ", +" * * ", +" * * ", +" ", +" * * ", +" * * ", +" * ", +" * * ", +" * * ", +" ", +" ", +" ** ", +" ** ", +" ", +" ", +" ", +" ** ", +" * * ", +" * * ", +" * * ", +" **** ", +" ", +" ** ", +" * * ", +" * * ", +" * * ", +" **** ", +" ", +" ", +" ** ", +" ** ", +" ", +" ", +" ", +" * * ", +" ** * ", +" * * * ", +" * ** ", +" * * ", +" ", +" * * ", +" ** * ", +" * * * ", +" * ** ", +" * * ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +}; diff --git a/examples/tutorial/pbLuaXmodem.lua b/examples/tutorial/pbLuaXmodem.lua new file mode 100644 index 0000000..c62dd0c --- /dev/null +++ b/examples/tutorial/pbLuaXmodem.lua @@ -0,0 +1,146 @@ +-- This is the example code file for the webpage at: +-- +-- www.hempeldesigngroup.com/lego/pbLua/tutorial/pbLuaXmodem.html + +--codeExampleStart 1 ----------------------------------------------------------- +nxt.DisplayClear() +i = 0 + +repeat + s=nxt.XMODEMRecv() + if s then + nxt.DisplayText( string.format( "Record %i", i ) ) + i = i + 1 + end +until s == nil +--codeExampleEnd 1 + +--codeExampleStart 2 ----------------------------------------------------------- +nxt.DisplayClear() +a={} +repeat + s=nxt.XMODEMRecv() + if s then + table.insert(a,s) + end +until s == nil +--codeExampleEnd 2 + +--codeExampleStart 3 ----------------------------------------------------------- +for _,s in ipairs(a) do + nxt.FileWrite(0,s) +end +--codeExampleEnd 3 + +----codeExampleStart 4 ----------------------------------------------------------- +p = "" +i = 0 +repeat + s = nxt.XMODEMSend(p) + if( s ) then + if i == 256 then + p = nil + else + p = string.rep( string.char(i), 128 ) + i = i + 1 + end + end +until s == nil +--codeExampleEnd 4 + +--codeExampleStart 5 ----------------------------------------------------------- +p = "" +addr = 0x100000 + +repeat + local s = nxt.XMODEMSend(p) + + if( s ) then + if addr >= 0x140000 then + p = nil + else + p = nxt.MemRead(addr,128) + addr = addr + 128 + end + end + +until s == nil +--codeExampleEnd 5 + +--codeExampleStart 6 ----------------------------------------------------------- +-- Function to set up the light sensor and then start transferring data +-- to the host as quickly as possible. Call the function, then start the +-- XMOPDEM transfer on the host, and then press the orange button to +-- start the sampling... + +function LogLight( port ) +-- Set up the light sensor on port 1 for passive mode + + nxt.InputSetType(port,0) + nxt.InputSetState(port,0,0) + nxt.InputSetDir(port,1,1) + + repeat + -- Wait here until the orange button is pressed + until( 8 == nxt.ButtonRead() ) + + local startTicks = nxt.TimerRead() + local sampleTick = startTicks + local p = "" + local d = "" + local s = true + + repeat + local nowTicks = nxt.TimerRead() + + -- Grab a light sensor sample and add it to our string if + -- at least 3 milliseconds have passed and we're still sending + + if (sampleTick + 3 <= nowTicks) and (p ~= nil) then + d = d .. string.format( "%06i %06i\r\n", nowTicks, nxt.InputGetStatus(port) ) + sampleTick = nowTicks + end + + -- Only try sending if we have more than 128 bytes to send + + if string.len(d) > 128 then + s = nxt.XMODEMSend(p) + + if( s ) then + if startTicks + 10000 < nowTicks then + p = nil + else + p = string.sub(d,1,128) + d = string.sub(d,129) + print(p) + end + end + end + until s == nil +end +--codeExampleEnd 6 + +--codeExampleStart 7 ----------------------------------------------------------- +-- Start the high-speed datalogger + +LogLight(1) +--codeExampleEnd 7 + +--codeExampleStart 7r ----------------------------------------------------------- +119345 000623 +119348 000619 +119351 000621 +119354 000623 +119357 000619 +119360 000623 +119363 000622 +119366 000622 +119369 000623 +119372 000623 +119375 000619 +119378 000619 +--codeExampleEnd 7r + +--codeExampleStart n ----------------------------------------------------------- +--codeExampleEnd n + diff --git a/pbLua.rfw b/pbLua.rfw new file mode 100755 index 0000000..7d803c0 Binary files /dev/null and b/pbLua.rfw differ diff --git a/usbDriver/pbLanguages.inf b/usbDriver/pbLanguages.inf new file mode 100644 index 0000000..c6b4d50 --- /dev/null +++ b/usbDriver/pbLanguages.inf @@ -0,0 +1,32 @@ +[Version] +Signature="$Windows NT$" +Class=Ports +ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318} +Provider=%ProviderName% +DriverVer=10/15/2009,1.0.0.2 + +[MANUFACTURER] +%ProviderName%=DeviceList, NTx86, NTamd64 + +[DeviceList.NTx86] +%pbLanguages%=DriverInstall,USB\VID_0694&PID_FF00 + +[DeviceList.NTamd64] +%pbLanguages%=DriverInstall,USB\VID_0694&PID_FF00 + +[DriverInstall] +include=mdmcpq.inf +CopyFiles=FakeModemCopyFileSection +AddReg=LowerFilterAddReg,SerialPropPageAddReg + +[DriverInstall.Services] +include = mdmcpq.inf +AddService = usbser, 0x00000002, LowerFilter_Service_Inst + +; This adds the serial port property tab to the device properties dialog +[SerialPropPageAddReg] +HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider" + +[Strings] +ProviderName = "HDG" +pbLanguages = "pbLanguages Virtual Com Port"