Network, serial setup at boot

Questions and discussion about The WiPy 1.0 board and CC3200 boards.
Target audience: Users with a WiPy 1.0 or CC3200 board.
User avatar
arikb
Posts: 5
Joined: Fri Oct 09, 2015 11:45 pm

Network, serial setup at boot

Post by arikb » Fri Oct 09, 2015 11:57 pm

Hello folks,

I've received my WiPy + dev board, it is functioning. Just so I can play with it better, I'm trying to achieve the following on boot (in boot.py):

1. On boot, go on my home network and obtain an IP address via DHCP
2. Print the IP address to UART 0 (the serial-to-USB)
3. Duplicate the REPL on the serial port

So far I was able to print to the serial port and use it for REPL, but for some reasons a sequence of commands I'm using interactively successfully isn't working for me when I put it in the boot.py. Here is my boot.py:

Code: Select all

from machine import UART
from network import WLAN
import os

SSID = 'my-home-network-ssid'
AUTH = (WLAN.WPA2, 'hunter2')


# enable the UART on the USB-to-serial port
uart = UART(0, baudrate=115200)
uart.write(b'UART initialised\n')

# login to the local network
uart.write(b'Initialising WLAN in station mode... ')
wlan = WLAN(WLAN.STA)
uart.write(b'done.\nConnecting to WiFi network...')
wlan.connect(ssid=SSID, auth=AUTH)
while not wlan.isconnected():
    uart.write(b'.')
uart.write(b'done.\nRequesting an IP from a DHCP server... ')
wlan.ifconfig(config='dhcp')
uart.write(b'done.\n')

# print
ip, mask, gateway, dns = wlan.ifconfig()
uart.write(b'IP address: ' + bytearray(ip) + '\n')
uart.write(b'Netmask:    ' + bytearray(mask) + '\n')
uart.write(b'Gateway:    ' + bytearray(gateway) + '\n')
uart.write(b'DNS:        ' + bytearray(dns) + '\n')

# start the terminal on the UART
os.dupterm(uart)
Just to reiterate, if I input these commands into the serial port one by one, I get an IP address on my network - but in boot.py I don't.

Also, how can I run the telnet and/or the FTP daemon in station mode?

Thanks,

-- Arik

User avatar
danicampora
Posts: 342
Joined: Tue Sep 30, 2014 7:20 am
Contact:

Re: Network, serial setup at boot

Post by danicampora » Sat Oct 10, 2015 6:38 am

Hello Arik,

The issue is that when you do

Code: Select all

wlan.ifconfig(config='dhcp')
the ip has to be renegotiated and that can take up to a few seconds. When you do it via the REPL, it is slow enough to work, but via boot.py is so fast that you get the new if configuration while the ip is being renegotiated. Two remarks:

1. DHCP is the default config, so no need to explicitly set it unless you had a static config before, but after power up, DHCP will always be enabled.
2. It's preferable to set the IP configuration before connecting, that way the IP is only negotiated once. For instance:

Code: Select all

wlan.ifconfig(config='dhcp')
wlan.connect(ssid=SSID, auth=AUTH)
3. If you still want to do the interface configuration after being connected, then check for isconnected() again after that. Example:

Code: Select all

wlan.connect(ssid=SSID, auth=AUTH)
while not wlan.isconnected():
    uart.write(b'.')
uart.write(b'done.\nRequesting an IP from a DHCP server... ')
wlan.ifconfig(config='dhcp')
while not wlan.isconnected():
    uart.write(b'.')uart.write(b'done.\n')

# print
ip, mask, gateway, dns = wlan.ifconfig()
uart.write(b'IP address: ' + bytearray(ip) + '\n')
uart.write(b'Netmask:    ' + bytearray(mask) + '\n')
uart.write(b'Gateway:    ' + bytearray(gateway) + '\n')
uart.write(b'DNS:        ' + bytearray(dns) + '\n')
    
Also, how can I run the telnet and/or the FTP daemon in station mode?
The daemons are always enabled unless you disable them yourself (API for this exists but will be changed in the next release). So simply (in a unix shell for instance):

Code: Select all

telnet <new_ip_adddress_in_station_mode>
ftp <new_ip_adddress_in_station_mode>

Damien
Site Admin
Posts: 545
Joined: Mon Dec 09, 2013 5:02 pm

Re: Network, serial setup at boot

Post by Damien » Sat Oct 10, 2015 8:40 am

Shouldn't you be able to use os.dupterm right at the start just after creating the UART object, and then use print instead of uart.write?

User avatar
danicampora
Posts: 342
Joined: Tue Sep 30, 2014 7:20 am
Contact:

Re: Network, serial setup at boot

Post by danicampora » Sat Oct 10, 2015 11:25 am

Yes Damien is right, do os.dupterm() at the start and then print from that point on.

User avatar
arikb
Posts: 5
Joined: Fri Oct 09, 2015 11:45 pm

Re: Network, serial setup at boot

Post by arikb » Sat Oct 10, 2015 2:04 pm

Thank you Dani and Damien.

I've integrated both of your comments and this code is working as expected now:

Code: Select all

# boot.py -- run on boot-up

from machine import UART
from network import WLAN
from os import dupterm
from time import sleep_ms

SSID = 'my-ssid'
AUTH = (WLAN.WPA2, 'hunter2')

# enable the UART on the USB-to-serial port
uart = UART(0, baudrate=115200)
# duplicate the terminal on the UART
dupterm(uart)
print('UART initialised')

# login to the local network
print('Initialising WLAN in station mode...', end=' ')
wlan = WLAN(WLAN.STA)
print('done.\nConnecting to WiFi network...', end='')
wlan.ifconfig(config='dhcp')
wlan.connect(ssid=SSID, auth=AUTH)
while not wlan.isconnected():
    sleep_ms(500)
    print('.', end='')
print(' done.\n')

# print
ip, mask, gateway, dns = wlan.ifconfig()
print('IP address: ', ip)
print('Netmask:    ', mask)
print('Gateway:    ', gateway)
print('DNS:        ', dns)
So I get my IP address on the serial port followed by a terminal, just like I wanted:

Code: Select all

arikb@home:~$ miniterm.py -b 115200 /dev/ttyUSB0 
--- Miniterm on /dev/ttyUSB0: 115200,8,N,1 ---
--- Quit: Ctrl+]  |  Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---
UART initialised
Initialising WLAN in station mode... done.
Connecting to WiFi network....... done.

IP address:  192.168.179.73
Netmask:     255.255.255.0
Gateway:     192.168.179.1
DNS:         192.168.179.1
Micro Python v1.4.6-21-gff736d6 on 2015-09-27; WiPy with CC3200
Type "help()" for more information.
>>> 
The reason I thought that the telnet, FTP daemons are not running was that I wasn't able to reach the device because I gave it the credentials of my guest network while my machine was on my internal network... so that is also working now.

Thank you both for your help! I'd say the documentation is a bit challenging at the moment but this is looking like a great little device!

-- Arik

[edited for typo]

User avatar
danicampora
Posts: 342
Joined: Tue Sep 30, 2014 7:20 am
Contact:

Re: Network, serial setup at boot

Post by danicampora » Sat Oct 10, 2015 4:30 pm

Thanks for your feedback. I agree 100%, docs suck at the moment, we had it quite complete but then the new API came in, and we just couldn't keep up, but I promise the it'll be addressed soon!

pilhuhn
Posts: 1
Joined: Mon Oct 26, 2015 9:07 pm

Re: Network, serial setup at boot

Post by pilhuhn » Mon Oct 26, 2015 9:25 pm

Is the above syntax still correct with os 1.1 ?

User avatar
danicampora
Posts: 342
Joined: Tue Sep 30, 2014 7:20 am
Contact:

Re: Network, serial setup at boot

Post by danicampora » Mon Oct 26, 2015 10:18 pm

Yes, it is.

lucien2k
Posts: 24
Joined: Sun Oct 11, 2015 5:34 pm

Re: Network, serial setup at boot

Post by lucien2k » Tue Oct 27, 2015 1:50 pm

I updated my wipy yesterday with the onewire fix, but having trouble with wlan now.

I had it configured to connect to my wifi on boot using basically the same code here, but now it doesn't work.

I tried doing it separately but now I get:

>>> from network import WLAN
>>> from os import dupterm
>>> from time import sleep_ms
>>> wlan = WLAN(WLAN.STA)
>>> wlan.scan()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OSError: the requested operation is not possible

Same problem with wlan.connect(ssid=SSID, auth=AUTH) etc.

Any thoughts?

User avatar
danicampora
Posts: 342
Joined: Tue Sep 30, 2014 7:20 am
Contact:

Re: Network, serial setup at boot

Post by danicampora » Tue Oct 27, 2015 1:59 pm

Hi Lucien, there's a small mistake in your code:

Code: Select all

wlan = WLAN(mode=WLAN.STA)
or

Code: Select all

wlan = WLAN(0, WLAN.STA)  # wlan id 0
Those are the correct forms, before it was working for you just by chance, but the API has been that way since 1.0.0. All hardware peripherals need an ID in the constructor. If this ID is omitted, the ID 0 is selected, but in order to omit it, you need to pass keyword arguments, this is standard Python behavior.

The init method of an object doesn't need the ID, since it's already constructed.

Post Reply