How Do I Make A Pi Pico W Connect To A Network With Wps? - micropython

First time using Stack overflow so I'll do my best to explain.
TLDR - HOW DO I MAKE A PI PICO W CONNECT TO A NETWORK WITH WPS?
I'm making a thing, that basically checks whether the value of a particular stock has gone up or down and lights up green or red LED's based on whether the price is up or down. That's all well and good, but to do this it needs to connect to wifi, and being that the thing I'm making has no screen, or keyboard, all we have to accomplish this is the LED's (for the device to communicate with us) and whatever button I put on there.
My plan was to have the device look at a file called "your_wifi_details.txt" for the SSID and pass, and if it finds them, connect - if nothing is there, or if it cannot connect using those details, it is to enter "WPS mode" where the lights will flash, and the user presses the WPS button on their router then presses a button on the device.
Everything is wired up and working perfectly aside from I cannot work out how to get WPS to work on a Pi Pico W. I think I've gotten really close, but i'm getting the error "'CYW43' object has no attribute 'scan_wps'"
(The lines of code are:
# If the button is pressed, scan for WiFi networks that support WPS
if not button.value():
sta_if.scan_wps()
# Connect to the first WiFi network that supports WPS
sta_if.connect_wps()
)
Then it goes on to connect to the API's and such to get the stock price and from there everything is good.
Literally everything works, if I manually go into the "your_wifi_details.txt" and put in a correct SSID and password, we're golden, but I can't have users required to download thonny and connect to the device and edit files and yada yada... so I am really hoping this WPS thing can work.
This is the first 'proper' program i've written since starting to learn python so apologies if this is a stupid approach, it's taken a lot or time and confusion to get this far but it's so nearly working, I just need a little help over the finish line so if anyone has faced this problem or can help me toward a solution I'd be super grateful
Here's excerpts from the relevant bits of code that are connected to the problem. There's a lot of "print" debugging commands so I can see in the terminal in Thonny where the program is at and what it's doing, obviously in the final use case there won't be a screen or keyboard so all that stuff will be taken out once development is complete:
import urequests
import network
import time
import machine
#--------------(Stackoverflow comment) then further down
#stackoverflow comment: I don't know why this next line is in bold, it shouldn't be
# Set up the button (connected to pin 15)
button = machine.Pin(15, machine.Pin.IN, machine.Pin.PULL_UP)
print ('pin 15 set as button')
#--------------(Stackoverflow comment) then further down still
while True:
print ('enter while true loop')
# Connect to the WiFi network
sta_if = network.WLAN(network.STA_IF)
#print ('firstline passed, sleeping for 10 seconds')
#ignore this, unnecessary now
#for i in range (0, 20):
# time.sleep(0.55)
# print ('sleeping...')
#print ('nap over, trying to continue..')
sta_if.active(True)
print ('firing up connection')
# Read the WiFi SSID and password from the text file
with open("your_wifi_details.txt", "r") as f:
ssid = f.readline().strip()
password = f.readline().strip()
print ('read your_wifi_details.txt successfully')
# Try to connect to the WiFi network
sta_if.connect(ssid, password)
print ('attempting to connect to wifi')
# Wait until the device is connected to the WiFi network
while not sta_if.isconnected():
# Flash the LEDs to indicate that the device is unable to connect
print ('connection failed, attempting to flash LEDs')
green_led.on()
red_led.on()
time.sleep(0.5)
green_led.off()
red_led.off()
time.sleep(0.5)
# Set up the button (connected to pin 0)
print ('setting up button for WPS')
button = machine.Pin(15, machine.Pin.IN, machine.Pin.PULL_UP)
# If the button is pressed, scan for WiFi networks that support WPS
if not button.value():
sta_if.scan_wps()
# Connect to the first WiFi network that supports WPS
sta_if.connect_wps()
# Save the WiFi SSID and password to the "your_wifi_details.txt" file
with open("your_wifi_details.txt", "w") as f:
f.write(sta_if.config("essid") + "\n")
f.write(sta_if.config("password") + "\n")
print ('wifi details written to file')
# Print the WiFi connection status in the terminal so I can see if it worked
print("Connected to WiFi:", sta_if.isconnected())

Related

How to read Analog Output Holding Registers on Advantech ADAM 6717 through ModBus TCP

I've been exploring the ADAM 6717 from Advantech.
This is the ModBus address table for said device:
At first I wanted to modify the value of the Digital output channel 0(DO0), so, as can be seen from the picture above, such address is the 0x0017.
I succeed at this by using a ModBus tool and the following settings:
Sending either "On" or "Off", turns On and off a LED connected to that output. Everything runs smoothly according to my expectation up to this point.
The problem arises when I want to read the Analog Input channel 6 or equivalently, address 400431~40044.
Since that address lies on the Analog Output Holding Registers part of the address table, I though that the following settings would accomplish the job:
However, as can be seen above, the reading shows 0.0 when there is actually 6V connected to that input (a potentiometer)
It is worth mentioning that I've made sure to enable the AI6 channel as well as setting it to Voltage mode instead of current. Also, the web utility for the device shows the AI6 reading correctly as I change the potentiometer's resistance value.
So the problem doesn't lie in the connection from the potentiometer to the AI6 but somewhere else.
Out of nothing and leaving aside what I think I know on this topic, I though of changing the function from 0x03 to 0x04
However, the response is exactly the same.
It bugs me that I can read and write values to the output coils but not the Analog output holding registers.
Is there any configuration that I might be missing over here?
Thanks in advance.
Device settings:
IP address: 10.0.0.1
Port in which the ModBus service is running: 5020

STM32 CDC_Receive_FS callback never called

I am trying to use the USB Device library on STM32Cube but when I execute using the debugger or that I try to turn an LED on in CDC_Receive_FS, it never reaches that point.
Here is how I set up everyting:
My board is a NUCLEO-F746ZG
I enabled USB_OTG_FS in Device_Only mode, activated _VBUS and _SOF. Left everything else by default and USB On The Go FS global interrupt is enabled!
I set up USB_DEVICE: Class For FS IP set to Virtual Port Com, left everything by default
Main loop left empty
CDC_Receive_FS: put breakpoint in it and/or HAL_GPIO_WritePin(LD1_GPIO_Port, LD1_Pin, GPIO_PIN_SET);
I have TIM2 set up for the things I would like to do when it will work
Then I tried to send data to the board, first using Python using serial with a baudrate of 921600 but got nothing. Then using PuTTY with a baudrate of 9600, still nothing...
If anyone has a clue, I have been struggling with it the whole day.
Here is the whole project: https://ecloud.global/s/cjGYqK6z9g58Lm4

Calibrating a touch screen monitor

A friend of mine got me a EloTouchSystems 2216 AccuTouch USB TouchMoitor, if was apart of a POS system they were replacing, and I am trying to calibrate it on Linux Mint. I have downloaded the xinput_calibrater app and ran it. Here the output from the program:
Calibrating standard Xorg driver "EloTouchSystems,Inc Elo TouchSystems 2216 AccuTouch® USB Touchmonitor Interface"
current calibration values: min_x=0, max_x=65535 and min_y=0, max_y=65535
If these values are estimated wrong, either supply it manually with the --precalib option, or run the 'get_precalib.sh' script to automatically get it (through HAL).
--> Making the calibration permanent <--
copy the snippet below into '/etc/X11/xorg.conf.d/99-calibration.conf' (/usr/share/X11/xorg.conf.d/ in some distro's)
Section "InputClass"
Identifier "calibration"
MatchProduct "EloTouchSystems,Inc Elo TouchSystems 2216 AccuTouch® USB Touchmonitor Interface"
Option "MinX" "5504"
Option "MaxX" "59519"
Option "MinY" "57834"
Option "MaxY" "6123"
Option "SwapXY" "0" # unless it was already set to 1
Option "InvertX" "0" # unless it was already set
Option "InvertY" "0" # unless it was already set
EndSection
I copied the the snippet as directed to the 99-calibration.conf file, and restarted my computer and nothing happened.
I have tried changing the "InvertX" and "InvertY" values to 1 (changing only one at a time) and rebooting after each time with not success. I am at a lose as to what to do. Can someone offer any suggestions, Please.
P.S. The monitor was manufactured by Fujitsu, and I am using the most current version of Linux Mint.
Additional Information: After posting the question, I realized I did not mention what the touch screen was doing. When I touch the screen and move my finger up and down on the screen, the cursor moves in the opposite direction.

Sending commands to uart on python

I am trying to write a pyserial command to the uart port to control the robot arm.
I have some manual:
manual for arm
manual command example
I use pyserial like that:
import serial
from time import sleep
port = serial.Serial("/dev/ttyUSB0", baudrate=9600, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, bytesize=8, timeout=1)
port.write(b"\x055\x55\x0B\x03\x02\x20\x03\x02\xB0\x04\x09\xFC\x03\xaa")
sleep(0.3)
#port.write(b"\x05")
#sleep(0.3)
#port.write(b"\x06")
#sleep(0.03)
#port.write(b"\x08\x01\x00")
print('send')
At first I tried to run it in one line, the buzzer will beep that the command was accepted, but the hand does not move.
Then I tried to split the Header separately for the Length in the next line and the Command with Parameters in the next.
Tell me how you can send these commands to the port, maybe there is something ready to do this in Python?
LSC Series Servo Controller Communication Protocol V1.2 manual says:
If the user transmits the correct data to the servo
controller, the blue LED 2 on the controller will flash one time, indicating that the
correct data have been received. If the user transmits the wrong data, then the blue
LED2 will not have any reaction and will keep the bright, then the buzzer will beepbeep twice to remind the user of the data error.
The only thing in that manual about that buzzer is that it beeps 2 times if there is a data error...

serial monitoring method to test communication via com ports without a serial communication device

I have a Verilog code simulated and synthesized on ISE design toolkit. I've got an FPGA spartan 6 device which is to be used for the implementation. But there is a problem with the device (probably a power issue) which makes the device unavailable in any of the COM ports when I connected it to my PC. So I want to check whether my Matlab code which I made for serial communication through the device does the desired job. So I need a method to test serial communication via any of the COM ports without connecting a serial com device to the PC. Is there any such method that I can Tx Rx serial data from Matlab to COM ports? Any software or any other method would be highly appreciated :)
I found a way to test Matlab serial communication using virtual serial ports.
Download "Freeware Virtual COM Ports Emulator" from: http://freevirtualserialports.com/
I installed it in Windows 10, and it's working (as trial).
Add a pair of two serial ports:
Execute the following Matlab code sample to verify it's working:
s3 = serial('COM3','BaudRate',115200);
s4 = serial('COM4','BaudRate',115200);
fopen(s3);
fopen(s4);
fwrite(s3, uint8([1, 2, 3, 4, 5]));
%fprintf(s3, '12345');
pause(0.1);
RxBuf = fread(s4, 5)
fclose(s3);
delete(s3);
clear s3
fclose(s4);
delete(s4);
clear s4
The output is:
RxBuf =
1
2
3
4
5
Bypassing the problem "it only stays for a single test session".
There is a problem when creating a pair of virtual ports using the software, it only stays for a single test session.
I guess it's a problem with the COM port emulation software.
The following solution, is not a good practice (and not a true solution).
Declare the serial object as global, keeping the object persistent.
Create the serial object only if it's not created.
Don't delete and don't clear the serial object.
See the following code sample:
global s3 s4
if isempty(s3)
s3 = serial('COM3','BaudRate',115200);
end
if isempty(s4)
s4 = serial('COM4','BaudRate',115200);
end
fopen(s3);
fopen(s4);
fwrite(s3, uint8([1, 2, 3, 4, 5]));
pause(0.1);
RxBuf = fread(s4, 5)
fclose(s3);
%delete(s3);
%clear s3
fclose(s4);
%delete(s4);
%clear s4
You can also look for a better virtual COM port software.
As Rotem suggested, if you need to communicate via serial line between 2 program of your PC you need a virtual COM port emulator.
It seems you are running on Windows OS so I would recommend a completely free emulator (not a trial one). For Windows I use com0com Null-modem emulator (from SourceForge).
In the example below I will show how to communicate with "another" device so Matlab will not handle both side of the communication. The other device will be simulated by a simple terminal. For windows I use RealTerm: Serial/TCP Terminal (also from SourceForge).
Setup:
Execute the setup of both program with all default options. by default com0com will create a virtual pair COM3/COM4 but if these port already exist on your system the program may assign other numbers. Check the numbers before you run the example. (it will also create a CNCA0/CNCB0 pair but you can ignore this one for now).
For RealTerm, once installed (don't forget to activate the server registration at the end of the setup, it should be ticked by default though), it will look like below. Keep all default options, just set the port number and the baud rate if they need to be changed.
Test MATLAB -> Terminal
You are ready to send Ascii characters or binary values from MATLAB to your device. The animation below shows you an example of both option:
you can click on the picture to see it full size. It is running in loop so you may want to wait until it restart from the beginning.
Test Terminal -> MATLAB
Below animation shows you how to test the communication in the other way:
Don't forget to tick [CR] [LF] on RealTerm when you send Ascii characters and want to use the '%s' format specifier on MATLAB, as it needs these characters to detect the end of the string.
Note:
If you have another terminal program that you are more used too, it
will work the same.
If the RealTerm option does not suit you, or if you want to handle
both sides of communication from Matlab, then you can use the code
provided by Rotem in his first answer. Just install com0com but
ignore all the RealTerm part.