Connect Lopy with Windows over BLE - windows

I am trying to send data from the Lopy to my Windows PC over Bluetooth Low Energy (BLE).
On the PC, I see the Lopy and I can connect him. But a few seconds later the Lopy disconnects.
This is my code:
bluetooth = Bluetooth()
bluetooth.set_advertisement(name='LoPy', service_uuid=b'1234567890123456')
def conn_cb (bt_o):
events = bt_o.events() # this method returns the flags and clears the internal registry
if events & Bluetooth.CLIENT_CONNECTED:
print("Client connected")
pycom.rgbled(0x00ff00)
elif events & Bluetooth.CLIENT_DISCONNECTED:
print("Client disconnected")
pycom.rgbled(0xFF0000)
bluetooth.callback(trigger=Bluetooth.CLIENT_CONNECTED | Bluetooth.CLIENT_DISCONNECTED, handler=conn_cb)
bluetooth.advertise(True)
srv1 = bluetooth.service(uuid=b'1223190123456', isprimary=True)
chr1 = srv1.characteristic(uuid=b'ab3451230123456', value=5)
while True:
print("Send Data")
chr1.value("here is the data need to be send it should be a very very long string")
time.sleep(3.050)
def char1_cb_handler(chr, data):

Related

TCP packets recieved on interface but not by Ruby TCPServer

I have a Ruby TCPServer that does not recieve TCP packets intermittently. Note the below is run inside another threads << Thread.new do as I have multiple TCP post listeners.
server = TCPServer.new(7207)
Thread.start(server.accept) do |client|
# process packet, send to AWS SQS
raw = ""
while (line = client.gets)
raw += line
end
sender = client.peeraddr
text = raw.unpack1("H*")
message_body = { payload: text, rx_at: Time.current, sender:}
puts "#{Time.current} : --- New uplink #{message_body}"
# send message to AWS SQS
client.close
end
I see the packets in tcpdump / wireshark but not on my TCPServer. I have a pcap file available:
https://www.dropbox.com/s/7m3hr1b7065tenx/tcp.pcap?dl=0
Example lost packets occurred on:
ip 10.0.225.43 at 27/07/2022 20:56:57 and 27/07/2022 20:39:31
Apologies after checking Wireshark this looks like a network problem not a Ruby / dev problem. The device was not sending FIN frames so the network stack was not publishing the packet up to my app.

How to connect multiple RC522 RFID Reader to Raspberry PI?

I want to know if it is possible to connect multiple RC522 to one Raspberry PI, if yes how do we do it? I read in some articles that with CS(chip select) pin we can control Readers, but the CS pin is not present on RC522 I have.
Can you please help me?
Chip Select (CS) is referred to as SS or NSS in some of the RFC522 documentation, is that the issue? If so, connect your CS0 to NSS on one module, CS1 to the NSS on the other, and you can use both modules on the same SPI bus.
If you need more devices than that, you could switch to the I2C interface. In I2C mode, a number of the pins on the chip become address selects, so you can put a whole bunch of them on the same I2C bus. The data sheet for the chip is always helpful with this sort of information. Section 8.1, "Digital interfaces" may be particularly helpful.
In I2C mode, you have 5 bits of addressing, so you can put up to 32 devices on the bus.
Posted this answer before on the raspberry pi stackexchange.
I'll just repost it here for visibility.
You can use the RST Pins to select the reader you want to use. Connect all the other pins in parallel (see schematic below). Just set all the RST pins to low, except the one on the pin you want to use. Set that one to high. Then initialize SPI, read/write, and close SPI again.
I wrote a more detailed explanation here.
This is the schematics and code I made:
Schematic for 2 readers
Schematic for 4 readers
Code to run it all (using pimylifeup's MFRC522-Python Library):
import RPi.GPIO as GPIO
from mfrc522 import SimpleMFRC522
import spidev
class NFC():
def __init__(self, bus=0, device=0, spd=1000000):
self.reader = SimpleMFRC522()
self.close()
self.bus
self.boards = {}
self.bus = bus
self.device = device
self.spd = spd
def reinit(self):
self.reader.READER.spi = spidev.SpiDev()
self.reader.READER.spi.open(self.bus, self.device)
self.reader.READER.spi.max_speed_hz = self.spd
self.reader.READER.MFRC522_Init()
def close(self):
self.reader.READER.spi.close()
def addBoard(self, rid, pin):
self.boards[rid] = pin
def selectBoard(self, rid):
if not rid in self.boards:
print("readerid " + rid + " not found")
return False
for loop_id in self.boards:
GPIO.output(self.boards[loop_id], loop_id == rid)
return True
def read(self, rid):
if not self.selectBoard(rid):
return None
self.reinit()
cid, val = self.reader.read_no_block()
self.close()
return val
def write(self, rid, value):
if not self.selectBoard(rid):
return False
self.reinit()
self.reader.write_no_block(value)
self.close()
return True
if __name__ == "__main__":
nfc = NFC()
nfc.addBoard("reader1",5)
nfc.addBoard("reader2",6)
data = nfc.read("reader1")
nfc.write("reader2",data)

Pushing data to websocket browser client in Lua

I want to use a NodeMCU device (Lua based top level) to act as a websocket server to 1 or more browser clients.
Luckily, there is code to do this here: NodeMCU Websocket Server
(courtesy of #creationix and/or #moononournation)
This works as described and I am able to send a message from the client to the NodeMCU server, which then responds based on the received message. Great.
My questions are:
How can I send messages to the client without it having to be sent as a response to a client request (standalone sending of data)? When I try to call socket.send() socket is not found as a variable, which I understand, but cannot work out how to do it! :(
Why does the decode() function output the extra variable? What is this for? I'm assuming it will be for packet overflow, but I can never seem to make it return anything, regardless of my message length.
In the listen method, why has the author added a queuing system? is this essential or for applications that perhaps may receive multiple simultaneous messages? Ideally, I'd like to remove it.
I have simplified the code as below:
(excluding the decode() and encode() functions - please see the link above for the full script)
net.createServer(net.TCP):listen(80, function(conn)
local buffer = false
local socket = {}
local queue = {}
local waiting = false
local function onSend()
if queue[1] then
local data = table.remove(queue, 1)
return conn:send(data, onSend)
end
waiting = false
end
function socket.send(...)
local data = encode(...)
if not waiting then
waiting = true
conn:send(data, onSend)
else
queue[#queue + 1] = data
end
end
conn:on("receive", function(_, chunk)
if buffer then
buffer = buffer .. chunk
while true do
local extra, payload, opcode = decode(buffer)
if opcode==8 then
print("Websocket client disconnected")
end
--print(type(extra), payload, opcode)
if not extra then return end
buffer = extra
socket.onmessage(payload, opcode)
end
end
local _, e, method = string.find(chunk, "([A-Z]+) /[^\r]* HTTP/%d%.%d\r\n")
local key, name, value
for name, value in string.gmatch(chunk, "([^ ]+): *([^\r]+)\r\n") do
if string.lower(name) == "sec-websocket-key" then
key = value
break
end
end
if method == "GET" and key then
acceptkey=crypto.toBase64(crypto.hash("sha1", key.."258EAFA5-E914-47DA-95CA-C5AB0DC85B11"))
conn:send(
"HTTP/1.1 101 Switching Protocols\r\n"..
"Upgrade: websocket\r\nConnection: Upgrade\r\n"..
"Sec-WebSocket-Accept: "..acceptkey.."\r\n\r\n",
function ()
print("New websocket client connected")
function socket.onmessage(payload,opcode)
socket.send("GOT YOUR DATA", 1)
print("PAYLOAD = "..payload)
--print("OPCODE = "..opcode)
end
end)
buffer = ""
else
conn:send(
"HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nContent-Length: 12\r\n\r\nHello World!",
conn.close)
end
end)
end)
I can only answer 1 question, the others may be better suited for the library author. Besides, SO is a format where you ask 1 question normally.
How can I send messages to the client without it having to be sent as a response to a client request (standalone sending of data)?
You can't. Without the client contacting the server first and establishing a socket connection the server wouldn't know where to send the messages to. Even with SSE (server-sent events) it's the client that first initiates a connection to the server.

BLE gatttool reading serial data from bluno?

I am trying to send data over BLE from Bluno to a Raspberry Pi (Raspian), bluez 5.50.
Whilst the connection seems to be fine. I am struck in a point where am unable to retrieve serial data from notification handle.
Below is what I tried.
pi#raspberrypi:~ $ sudo gatttool -b <BLE-MAC-ADDRESS> -I
<BLE-MAC-ADDRESS>[LE]> connect
Attempting to connect to <BLE-MAC-ADDRESS>
Connection successful
[<BLE-MAC-ADDRESS>][LE]>
Notification handle = 0x0025 value : 32
Notification handle = 0x0025 value : 32
Notification handle = 0x0025 value : 32
Notification handle = 0x0025 value : 32
[<BLE-MAC-ADDRESS>][LE]>char-read-hnd 0x0025
handle : 0x0025 value : 01
Notification handle = 0x0025 value : 32
Notification handle = 0x0025 value : 32
[<BLE-MAC-ADDRESS>][LE]>
So the problem here is , Notification handle listener 'listens' to the serial data and returns the value( 2 -> Hex:32) every 1 second from Bluno (as programmed in Adurinosketch).
But when I try to retrieve this value through the command char-read (tried both by handle & uuid) it always returns 01 ?!!!
Ultimately I want to retrieve this value in my Python code (am using Pexpect for this)
Any help / directions appreciated.
Ok , Here is what I ended up doing in my Python code to retrieve the value
`
child = pexpect.spawn("sudo gatttool -b <BLUNO-MAC-ADDR> -I")
# Connect to the device.
print("Connecting to Bluno...")
child.sendline("connect")
child.expect("Connection successful", timeout=5)
print(" Connected!")
while True:
child.expect("Notification handle = 0x0025 value: ", timeout=10)
child.expect("\r\n", timeout=10)
resp = child.before
print(process_my_data(bytearray.fromhex(resp.decode("utf-8")).decode()))
`

Send data to a decent user with Kemal over websocket

How can i send data data to a decent user connected via websockets? I know,
Websocket connections yields the context, but how can i filter a decent socket connection for sending data to only 1 (or some) connected user(s) depending on context (env)?
SOCKETS = [] of HTTP::WebSocket
ws "/chat" do |socket,env|
room = env.params.query["room"]
SOCKETS << socket
socket.on_message do |message|
SOCKETS.each { |socket| socket.send message}
end
socket.on_close do
SOCKETS.delete socket
end
end
Must socket contain the room or needs SOCKETS to be a Hash?
You can store sockets as hash and give id to your clients and then you can send saved socket of your recent client.
I mean that
SOCKETS = {} of String => HTTP::WebSocket
socket.on_message do |message|
j = JSON.parse(message)
case j["type"]
when "login"
user_id = j["id"].to_s
SOCKETS[user_id] = socket
when "whisper"
to = j["to"].to_s
from = j["from"]
user = SOCKETS[to].send("#{from} is whispering you!")
end
something like that.

Resources