Commits

Brian Thorne committed dd67772

Add embedded lua code to send CAN signal on button press.

Comments (0)

Files changed (5)

Binary file added.

+
+-- Save references to pins and buttons
+local BTN_UP = pio.PE_0
+local BTN_DOWN = pio.PE_1
+local BTN_LEFT = pio.PE_2
+local BTN_RIGHT = pio.PE_3
+local BTN_SELECT = pio.PF_1
+local STA_LED = pio.PF_0
+local sta_led_status = 0
+
+pio.pin.setdir(pio.INPUT, BTN_UP, BTN_DOWN, BTN_LEFT, BTN_RIGHT, BTN_SELECT)
+pio.pin.setpull(pio.PULLUP, BTN_UP, BTN_DOWN, BTN_LEFT, BTN_RIGHT, BTN_SELECT)
+pio.pin.setdir(pio.OUTPUT, STA_LED)
+
+local setlow = pio.pin.setlow
+local sethigh = pio.pin.sethigh
+local getval = pio.pin.getval
+
+function toggle_status_led()
+    if sta_led_status == 0 then
+        sta_led_status = 1
+        sethigh(STA_LED)
+    else
+        sta_led_status = 0
+        setlow(STA_LED)
+    end
+    tmr.delay(500000)
+end
+
+function btn_pressed( button )
+  return getval( button ) == 0
+end
+
+local canID = 0x42
+local canport = 0
+
+can.setup(canport, 105263)
+local CANSTD = can.ID_STD
+
+--- Send a message over the Controller Area Network
+--- @param data Message data as string (up to 8 bytes) 
+function canSend(data)
+	print("Sending can message", data)
+    can.send(canport, canID, CANSTD, data)
+end
+
+running = true
+while running do
+    if (btn_pressed(BTN_SELECT)) then
+    	running = false
+    	print("done")
+    elseif (btn_pressed(BTN_UP)) then
+    	canSend("up")
+    elseif (btn_pressed(BTN_DOWN)) then
+    	canSend("down")
+    elseif (btn_pressed(BTN_LEFT)) then
+    	canSend("left")
+    elseif (btn_pressed(BTN_RIGHT)) then
+    	canSend("right")
+    end
+    tmr.delay(100000)
+end
+print("finished")

internet_socket.py

+# Internet sockets... yawn
+import socket
+
+tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+tcp_socket.connect(("nz.pycon.org", 80))
+tcp_socket.sendall(b"GET / HTTP/1.1\r\n")
+
+Sockets?
+========
+
+* This talk isn't really about sockets
+* (well not entirely)
+* now that is cleared up lets get sockets out of the way...
+
+# Network Sockets
+
+The rather normal network socket:
+
+    import socket
+    tcp_socket = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
+    tcp_socket.connect(("google.com", 80))
+    tcp_socket.sendall(b"GET / HTTP/1.1\r\n")
+
+* A not so distant cousin to how your browser kicks off a request...
+* Let's take a look at the normal client/server example for network sockets
+
+# Server
+
+    def echo(conn):
+        while True:
+            data = conn.recv(1024)
+            if not data: break
+            conn.send(data)
+        conn.close()
+    
+    def consumer_server(...
+        s = socket.socket(address_family, socket_type, protocol)
+        s.bind(
+        s.listen(5)
+        while True:
+            conn, addr = s.accept()
+            threading.Thread(target=echo, args=(conn,)).start()
+
++ listen(5) tells the OS to queue up to 5 connection requests
++ Note a new thread gets spun up for every client connection
++ Threads spin up plenty quick
++ Yes all the error handling has been removed to ease readability at the expense of all usability..
+
+# Client
+
+    af, socktype, proto, _, sa = socket.getaddrinfo(
+        host, 
+        random_port, 
+        socket.AF_UNSPEC, 
+        socket.SOCK_STREAM)[0]
+    s = socket.socket(af, socktype, proto)
+    s.connect(sa)
+    s.sendall(outgoingdata)
+
++ Leaving the address family unspecified will return INET and INET6
+
+# Demo
+
+Meet the Freerunner - open source phone running SHR (debian based)
+
+    ssh root@192.168.7.2
+    
+    cd code
+    cat server.py
+    python server.py
+
++ Well it would be a bit boring just running on my laptop!
+
++ Incase I forget run on the pc:
+    python3 basic_socket_client.py 
+
+# Unix Sockets
+
+So on GNU/Linux *everything* is a file. This includes everything 
+from .txt files to Sockets.
+
+* TCP/UDP sockets **can** connect endpoints on the same network
+
+* Unix Sockets can only connect endpoints on the same machine.
+
+* This lets the Kernel make some assumptions and cut out the  
+expensive "networking" layer.
+
+# Unix Sockets
+
+They are extensively used for Inter Process Communicaton, including 
+internally in Python's multiprocessing.connection module:
+
+    # A higher level module for using sockets (or Windows named pipes)
+    #
+    # multiprocessing/connection.py
+
+* From Python 3.3 Unix Sockets can also be used to send open
+ file descriptors (open files or sockets) to another Process using 
+ the sendmsg() and recvmsg() calls.
+
+Socket (ab)use
+==============
+
++ What if you were running your python program on a cretin system that
+  didn't give you enough memory?
+  
++ But you knew the kernel had access to
+  plenty more...
+  
++ You **could** fire off a socket and use it as some FIFO form 
+  of memory storage...
+
+# Extremely Contrived Example
+
+![](images/memory_example.png)
+
++ Main thread wants to "save some data" out of process memory by 
+  creating a local socket with a large buffer
++ the consumer thread just creates the socket/s
++ to illustrate the concept my worker thread isn't allowed to access 
+  this memory (read from socket) until all the data has been stored
++ sha256 on the bytes saved and recalled should match
+
+
+# example socket_memory.py output
+
+    Connected by ('127.0.0.1', 45527)
+    waiting for producer to finish filling the socket
+    "Saved" 250 blocks of 2048 random bytes
+    SHA256 of sent: 290491d7b26ab55cf62cf9ea662634b0bd63509dfbaf02877aab458a161a5fd9
+    okay lets have your data
+    Received 250 x 2048 bytes of data
+    SHA256 of recv: 290491d7b26ab55cf62cf9ea662634b0bd63509dfbaf02877aab458a161a5fd9
+
++ No I'm not really serious, but it did appear to work...
+
+# New toy
+
+![](images/raspi.png)
+
+The much awaited Rasberry Pi!
++ actually I'm **still** waiting for mine
++ easily fitted with a USB bluetooth dongle
++ actually just another computer...
++ which is a bit boring
++ need something more fun
+
+# New(er) toy!
+![](images/iRacer.jpg)
+iRacer from sparkfun
+
++ on-board Bluetooth radio
++ RFCOMM Bluetooth...
++ Protocol is dead easy - **0xXY** where X is the direction 
+  and Y is the speed. E.G 0x16: Direction=Forwards, mid-speed.
++ https://www.sparkfun.com/products/11162
+
+# Bluetooth
+
+![](images/bluetooth_documentation.png)
+
+**One** mention of "bluetooth" on the Python 3.3 socket docs...
++ How hard could it be...
++ Okay I had to use the source but the end result is easy!
+
+    import socket
+    import time
+
+    class BluetoothCar:
+        def __init__(self, mac_address="00:12:05:XX:XX:XX"):
+            self.socket = socket.socket(
+                socket.AF_BLUETOOTH, 
+                socket.SOCK_STREAM, 
+                socket.BTPROTO_RFCOMM)
+            
+            self.socket.connect((mac_address, 1))
+            
+        def forwards(self, duration=1.0):
+            self.drive(0x16, duration)
+        ...
+        
+        def drive(self, command, duration):
+            self.socket.send(bytes([command]))
+            time.sleep(duration)
+            self.socket.send(bytes([0x00]))
+
+
+# CAN
+
+TODO...
 host = 'localhost'
 random_port = 50000 + int(10000 * random())
 
-# Our "consumer_server" thread will signal when it has successfully 
+# Our "consumer_server" thread will signal when it has successfully
 # created a socket, then wait for the producer to finish before starting
 # to consume (so we KNOW that the entire data was in the socket at once)
 e = threading.Event()
 
 def grab_sock():
-    af, socktype, proto, _, sa = socket.getaddrinfo(host, 
-                                                random_port, 
-                                                socket.AF_UNSPEC, 
+    af, socktype, proto, _, sa = socket.getaddrinfo(host,
+                                                random_port,
+                                                socket.AF_UNSPEC,
                                                 socket.SOCK_STREAM)[-1]
     try:
         s = socket.socket(af, socktype, proto)
             outgoing_data = random_source.read(bytes_per_packet)
             m.update(outgoing_data)
             s.send(outgoing_data)
-    
+
     s.close()
     print('"Saved" {} blocks of {} random bytes'.format(num_packets, bytes_per_packet))
     print("SHA256 of sent: {}".format(m.hexdigest()))
     print("Received {} x {} bytes of data".format(len(received_bytes), len(received_bytes[0])))
     digest = hashlib.sha256()
     [digest.update(received_block) for received_block in received_bytes]
-                  
+
     print("SHA256 of recv: {}".format(digest.hexdigest()))
 
 
     threading.Thread(target=worker, args=(conn, addr)).start()
 
 threading.Thread(target=consumer_server).start()
-stream_data(num_packets)
+stream_data(num_packets)
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.