Shop Learn P1 Docs P2 Docs
FlexBASIC P2 rtc WiFi — Parallax Forums

FlexBASIC P2 rtc WiFi

When I load this and run it, for some reason the 'input #2, inBuff', is not working as expected.

I am using a telnet client program (putty) to access the P2 WiFi, and for some reason when I try the getdate or getime command, it is not waitng for the input, it just does a CR. Is there something wrong with input #2, or is there something weird with the telnet client program.

Ray

' rtc_wifi.bas

    dim cr2 as class using "spin/SmartSerial.spin"

    cr2.startx(63, 62, 0, 115200)
    open SendRecvDevice(@cr2.tx,@cr2.rx) as #2

dim inBuff as string

' hours, minutes, seconds: 00-23, 00-59, 00-59
    dim as ubyte hours, mins, secs
    ' month, day in month: 1-12, 1-31
    dim as ubyte MM, DD
    ' year: 4 digits
    dim as integer YYYY
    dim s$ as string
    dim date as string
    dim time as string
    dim tmpYYYY, tmpMM, tmpDD, tmpHOURS, tmpMINS, tmpSECS as ulong

    dim stack_rtc(10)       
dim cpuID_3 as long
cpuID_3 = cpu(updateClock, @stack_rtc(1))

do
    print #2, "> ";
    input #2, inBuff
        if inBuff = "setdate" then
        input #2, "Enter year, month and day as YYYY-MM-DD ",s$
        s$ = ltrim$(rtrim$(lcase$(s$)))
        if len(s$) <> 10 then
            print #2, "Illegal date format: Date should be YYYY-MM-DD"
        else
            YYYY = val(left$(s$, 4))
            MM = val(mid$(s$, 6, 2))
            DD = val(right$(s$, 2))
        end if
    else if inBuff = "settime" then
        input #2, "Enter time as HH:MM:SS ",s$
        s$ = ltrim$(rtrim$(lcase$(s$)))
        if len(s$) <> 8 then
            print #2, "Illegal time format: Should be HH:MM:SS!"
        else
            HOURS = val(left$(s$, 2))
            MINS = val(mid$(s$, 4, 2))
            SECS = val(right$(s$, 2))
        end if
    else if inBuff = "getdate" then
        getdate()
    else if inBuff = "gettime" then
        gettime()   
    else
        print #2, "??"
    end if  
loop

end

'' RTC 
'' helper subroutine; return number of days in month
''
function daysInMonth() as uinteger
  ' february special case
  if MM = 2 then
    if (YYYY mod 4 = 0) then
      if (YYYY mod 100 <> 0) or (YYYY mod 1000 = 0) then
        return 29
      endif
    endif
    return 28
  endif
  if (MM = 4) or (MM=6) or (MM=9) or (MM=11) return 30
  return 31
end function
'''''''''''''''   
'' RTC
'' routine to keep the clock up to date
''
sub updateClock
  dim nextSecond
  dim FREQUENCY

  FREQUENCY = clkfreq
  nextSecond = getcnt() + FREQUENCY
  do
    waitcnt(nextSecond)
    nextSecond = nextSecond + FREQUENCY
    secs = secs + 1
    if (secs >= 60) then
      secs = 0
      mins = mins + 1
      if (mins >= 60) then
        mins = 0
    hours = hours + 1
    if (hours >= 24) then
      hours = 0
      DD = DD + 1
    endif
      endif
    endif
    if (DD > daysInMonth()) then
      DD = 1
      MM = MM + 1
      if (MM > 12) then
        MM = 1
    YYYY = YYYY + 1
      endif
    endif
  loop
end sub
'''''''''''''''
sub getdate
    print #2, "Current date: ";
    print #2, using "%%/%%/%%%%"; MM; DD; YYYY
end sub
'''''''''''''''
sub gettime
    print #2, "Current time: ";
    print #2, using "%%:%%:%%"; hours; mins; secs
end sub
''''''''''''''' 

Comments

  • JRoarkJRoark Posts: 1,103

    My bet is the terminal program is putting a CRLF at the end of the line. Set the terminal program to emit only a CR at the end of the line and see what happens.

    Also: you can replace rtrim$(ltrim$(X$)) with just trim$(). And for integer-only inputs to val() you can more efficiently use val%()

  • RsadeikaRsadeika Posts: 3,685

    I have access to putty and TeraTerm programs.

    In putty I could not find the correct CRLF control for the program to work with my program. It looks like that control has to be done on the FlexBASIC side, somehow.

    In TeraTerm, it has more control on the CRLF, but what is offered is not the correct combination for making it work with FlexBASIC. So....

    Not sure which way to go, in order to resolve this issue, any ideas? I was playing around with Python code using socket, but did not make to much headway with that. I noticed there is code examples for Python telnet program, not sure if that would be any different then the socket stuff.

    Ray

  • iseriesiseries Posts: 1,273

    I saw the same issue. The nice think about the Wifi module is you can connect two devices at the same time.

    I was not able to get putty to work.
    Telnet from the command line on windows works just fine though.

    I see flex props telnet session does not echo characters.

    I tried simpleIDE terminal session and that also works just fine.

    Mike

  • JRoarkJRoark Posts: 1,103

    You could write a character-by-character handler. Have it inspect each char as it comes in, toss the char if its a control code or an LF, and append whatever is “normal” text it to a buffer. When you get a CR, process the string as you would have if it came from an INPUT. Sort of your own version of “input” if you will.

  • RsadeikaRsadeika Posts: 3,685

    I cobbled together a Python program to verify that I can connect to the P2 WiFi, to access the P2 FlexBASIC rtc program. It seems to be working as expected.

    I tried out the setdate and settime commands, working as expected. I added a connect2 command, which provides some data about the WiFi card? The next thing, I guess, would be, is to set up the program so I could get the internet time and date, and have inserted into the P2 FlexBASIC rtc program.

    Ray

    # newone.py
    import socket
    import sys  
    
    
    host = '192.168.xx.xxx'
    
    port2 = 80  # web
    port = 23 # WiFi
    
    global s
    
    def connect1():
    # create socket
        print('# Creating socket')
        try:
            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        except socket.error:
            print('Failed to create socket')
            sys.exit()
    
        print('# Getting remote IP address') 
        try:
            remote_ip = socket.gethostbyname( host )
        except socket.gaierror:
            print('Hostname could not be resolved. Exiting')
            sys.exit()
    
    # Connect to remote server
        print('# Connecting to server, ' + host + ' (' + remote_ip + ')')
        s.connect((remote_ip , port))
    
    def connect2():
        print('# Creating socket')
        #s.quit()
        try:
            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            #s.close()
            #s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        except socket.error:
            print('Failed to create socket')
            sys.exit()
    
        print('# Getting remote IP address') 
        try:
            remote_ip = socket.gethostbyname( host )
        except socket.gaierror:
            print('Hostname could not be resolved. Exiting')
            sys.exit()
    
    # Connect to remote server
        print('# Connecting to server, ' + host + ' (' + remote_ip + ')')
        s.connect((remote_ip , port2))
    
    def send_data2():
        remote_ip = socket.gethostbyname( host )
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect((remote_ip , port2))
        request = "GET / HTTP/1.0\r\n\r\n"
        try:
            s.sendall(request.encode("utf-8"))
        except socket.error:
            print('Send failed')
            sys.exit()
    # Receive data
        print('# Receive data from server')
        reply = s.recv(4096)
        print(reply.decode("utf-8"))
    
    def send_data(indata):
        remote_ip = socket.gethostbyname( host )
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect((remote_ip , port))   
        # Send data to remote server
        print('# Sending data to server')
        print('\n')
    #request = "GET / HTTP/1.0\r\n\r\n"
    
        request = indata
    
        try:
            s.sendall(request.encode("utf-8"))
        except socket.error:
            print('Send failed')
            sys.exit()
    
    # Receive data
        print('# Receive data from server')
        reply = s.recv(4096)
        print(reply.decode("utf-8"))
    
    
    while True:
            inBuff = input(": ")
            if inBuff == "connect":
                connect1()
            elif inBuff == "connect2":
                connect2()
                send_data2()
            elif inBuff == "gettime":
                send_data("gettime\n")
            elif inBuff == "setdate":
                send_data("setdate\n")
                setdate=input()
                send_data(setdate + "\n")
    
            elif inBuff == ("settime"):
                send_data("settime\n")
                settime=input()
                send_data(settime + "\n")
            elif inBuff == "getdate":
                send_data("getdate\n")
            else:
                print("??")
    
    
  • iseriesiseries Posts: 1,273

    How about using an NTP server on the internet to get the time.

    Here is an example I made some time ago that explains it not very good but should work with your Wifi board.

    getting-the-date-and-time-with-parallax-wifi-module

    Mike

  • dgatelydgately Posts: 1,524

    @iseries, is there a simple way to set up 2 Parallax WiFi Modules in a pass-through mode like a pair of XBees? Can we avoid all the SEND/GET web style code and just connect 2 modules and have them act as serial interfaces? As Ray has done, we can easily connect to 1 WiFi module from a PC via Python or another language. Can we do the same between 2 WiFi modules hooked up to our P2s (or P1s)?

    dgately

  • iseriesiseries Posts: 1,273

    @dgately ,

    The simple answer is no. For telent to work between two units or more is that one has to be the host and the other the client. In this case the host is the Wifi unit and it is listening on port 23. The client end is using some random port that is assigned when the connection is started.

    You can however setup to Wifi modules to talk to each other with very simple code that is explained in this discussion.

    what can I do with a parallax-wx module

    Mike

  • dgatelydgately Posts: 1,524

    THx Mike! Had not read that posting...

  • RsadeikaRsadeika Posts: 3,685

    The reason that I chose Python for this experiment was, there is greater flexibility for expanding the scope of the project, via Python. The P2 is a powerful little chip, but it has its limitations. Basically, you will need a more robust assistant system if you want to go on to bigger things.

    Like I mentioned earlier, having the P2 rtc (software) updated by the internet clock; now that I thought about it, it should be very easy to do, I may end up regretting what I just said.

    Another thing that I am thinking about is, I have an interest in AI/Machine Learning. The P2 may be able to do that on a very small scale, by itself, but I think a better option is to have a PC do the hard work, and funnel the data down to the P2, when needed. Just a couple of things to think about.

    Now I am wondering if I can turn the Python program into a GUI presentation.

    Ray

  • RsadeikaRsadeika Posts: 3,685

    The below Python code now has a GUI component. It is not professional quality, but you should get a good idea of how Python works.

    In the GUI, the top left side, white space, you enter your wifi address, then hit the 'Get text' button. That makes the wifi address available for the program to work. I use Geany, so a little terminal opens up, and the GUI part shows up. The 'Set Date' and 'Set Time' buttons now load the internet time and date to the rtc program.

    You can use the rtc P2 FlexBASIC code, from my first post. On my set up this is working as expected. I hope somebody finds this useful.

    Ray

    # newtwo.py
    # March 14, 2022
    import socket
    import sys
    #import datetime
    from datetime import datetime
    
    import tkinter as tk
    from tkinter import *
    from tkinter import ttk  
    
    
    root = Tk()
    
    # Use the get_text button to insert host wifi address
    #host = '192.168.35.111'
    
    port2 = 80  # web
    port = 23 # WiFi
    
    global s
    global host
    
    def connect1():
    # create socket
        print('# Creating socket')
    
        try:
            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        except socket.error:
            print('Failed to create socket')
            sys.exit()
    
        print('# Getting remote IP address') 
        try:
            remote_ip = socket.gethostbyname( host )
        except socket.gaierror:
            print('Hostname could not be resolved. Exiting')
            sys.exit()
    
    # Connect to remote server
        print('# Connecting to server, ' + host + ' (' + remote_ip + ')')
        s.connect((remote_ip , port))
    
    def connect2():
        print('# Creating socket')
        try:
            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            #s.close()
            #s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        except socket.error:
            print('Failed to create socket')
            sys.exit()
    
        print('# Getting remote IP address') 
        try:
            remote_ip = socket.gethostbyname( host )
            myinputvalue(remote_ip)
        except socket.gaierror:
            print('Hostname could not be resolved. Exiting')
            sys.exit()
    
    # Connect to remote server
        print('# Connecting to server, ' + host + ' (' + remote_ip + ')')
        s.connect((remote_ip , port2))
    
    def send_data2():
        remote_ip = socket.gethostbyname( host )
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect((remote_ip , port2))
        request = "GET / HTTP/1.0\r\n\r\n"
        try:
            s.sendall(request.encode("utf-8"))
        except socket.error:
            print('Send failed')
            sys.exit()
    # Receive data
        print('# Receive data from server')
        reply = s.recv(4096)
        myinputvalue(reply)
        print(reply.decode("utf-8"))
    
    
    def send_data(indata):
    
        remote_ip = socket.gethostbyname( host )
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect((remote_ip , port))   
        # Send data to remote server
        print('# Sending data to server')
        print('\n')
    #request = "GET / HTTP/1.0\r\n\r\n"
    
        request = indata
    
        try:
            s.sendall(request.encode("utf-8"))
        except socket.error:
            print('Send failed')
            sys.exit()
    
    # Receive data
        print('# Receive data from server')
        reply = s.recv(4096)
        print(reply.decode("utf-8"))
        newdata = reply.decode("utf-8")
        myinputvalue(newdata)
    
    def myinputvalue(indata):
        result = indata
        myTKtext.delete("1.0","end")  # Clears the text box
        #myTKtext.insert(END, result + '\n')
        myTKtext.insert(END, result) 
    
    def Set_date():
        #print("debug")
        send_data("setdate\n")
        now = datetime.now()
        date_val = now.strftime("%Y-%m-%d")
        send_data(date_val+"\n")
    
    def Set_time():
        send_data("settime\n")
        now = datetime.now()
        time_val = now.strftime("%H:%M:%S")
        send_data(time_val + "\n")
    
    def Getp2_date():
        send_data("getdate\n")
    
    def Getp2_time():
        send_data("gettime\n")
    
    ## GUI portion
    ##############
    def Get_MyInputValue(): 
        result = MyEntryBox.get()  #Gets the entry
        myTKtext.insert(END, result + '\n')  #Inserts in Text window with a CR
        global host
        host = result
    
    
    # Create Tkinter Entry Widget
    MyEntryBox = Entry(root, width=20)
    MyEntryBox.place(x=5, y=6)
    
    #myTKtext window
    myTKtext = Text(root, height = 22,
                  width = 40,
                  bg = "light cyan")
    myTKtext.place(x=4, y=62)
    
    
    #command will call the defined function
    MyTkButton = Button(root, height=1, width=10, text="Get text", \
    command=Get_MyInputValue)
    MyTkButton.place(x=200, y=6)
    
    MyTkButton2 = Button(root, height=1, width=10, text="Set Date", \
    command=Set_date)
    MyTkButton2.place(x=400, y=6)
    
    MyTkButton3 = Button(root, height=1, width=10, text="Set Time", \
    command=Set_time)
    MyTkButton3.place(x=550, y=6)
    
    MyTkButton4 = Button(root, height=1, width=10, text="Get P2 Date", \
    command=Getp2_date)
    MyTkButton4.place(x=400, y=40)
    
    MyTkButton5 = Button(root, height=1, width=10, text="Get P2 Time", \
    command=Getp2_time)
    MyTkButton5.place(x=550, y=40)
    
    ## End of GUI portion
    #####################
    
    
    if __name__ == "__main__":
        #root = tk.Tk()
        root.title("tkTERM ")
        root.geometry("800x500")
    
    
    
        #root.mainloop()
    
        while True:
            inBuff = input(": ")
            if inBuff == "connect":
                connect1()
            elif inBuff == "connect2":
                connect2()
                send_data2()
            elif inBuff == "gettime":
                send_data("gettime\n")
            elif inBuff == "setdate":
                send_data("setdate\n")
                ## manual input ##
                #setdate=input()
                #send_data(set_date + "\n")
                ##
                ## Auto input ##
                now = datetime.now()
                date_val = now.strftime("%Y-%m-%d")
                send_data(date_val+"\n")
                ##
    
            elif inBuff == ("settime"):
                send_data("settime\n")
                ## Manual input ##
                #settime=input()
                #send_data(settime + "\n")
                ##
                ## Auto input ##
                now = datetime.now()
                time_val = now.strftime("%H:%M:%S")
                send_data(time_val + "\n")
                ##
            elif inBuff == "getdate":
                send_data("getdate\n")
            elif inBuff == "testit":
                myinputvalue()
            else:
                print("??")
    
    
        root.mainloop()
    
    
  • RsadeikaRsadeika Posts: 3,685

    @dgately
    " is there a simple way to set up 2 Parallax WiFi Modules in a pass-through mode like a pair of XBees?"
    I was browsing through the Parallax wifi firmware pdf, and it shows a possible way of connecting two wifi's, and maybe having a sort of serial connection. I think if you setup the wifi's in AP mode, that might get you what you are looking for. Not sure how simple that would be to do, but that might be an interesting way to go.

    My theory, if you have two P2 wifi's, you set one up in STA-AP, that creates an address. On the second P2 wifi, you set that up with a link to the first ones address. Since both would have a hard serial connect to the respective P2, hopefully the wifi firmware would allow a connection between the two P2's, in a pseudo serial manner. Now using a serial program, on each P2, maybe that should be able to talk too each other. This sounds way to simple, maybe dgately can give it a try. I do not have two P2's or two wifi's, to try this out myself.

    Ray

  • dgatelydgately Posts: 1,524

    Thanks Ray!

    Yes, that's basically what I'm working on. I've got the start of a connection between 2 WiFI Modules using Mike's "what can I do with a parallax-wx module" and Clock Loop's code from this post: https://forums.parallax.com/discussion/comment/1520117/#Comment_1520117. I'm converting that code to Spin2 and am starting to have success! Once I have good results I'll post to the PASM2/SPin2 (P2) discussions...

Sign In or Register to comment.