Driver for SIM800 SIM808

Discuss development of drivers for external hardware and components, such as LCD screens, sensors, motor drivers, etc.
Target audience: Users and developers of drivers.
Post Reply
jartieda
Posts: 2
Joined: Fri Aug 14, 2020 9:58 am

Driver for SIM800 SIM808

Post by jartieda » Wed Aug 26, 2020 9:57 am

Hi
I have implemented a socket class for sim808.
This allows the use of sim808 with other micropython clases such as mqtt or even ssl
It is still very untested and have a lot of things that are needed to fix.
I just want to post it here to receive some feedback and contributions.
Also I think that might serve as example for other client socket implementations.
Best Regards
Jorge

Code: Select all


import pyb
from time import sleep
import io

def getaddrinfo(host, port, af=0, type=0, proto=0, flags=0):
  canonname=flags
  family=(af, (host,port))
  return [family, type, proto, canonname, host]
  
class socket(io.IOBase):
  rx_buf = ""
  rx_bufb = bytearray()
  ok = False
  uart2IRQ = None
  def __init__(self):
    self.gsm = pyb.UART(1, 9600, timeout_char=100, read_buf_len=1000)
    print("sent", self.gsm.write('AT'+'\r\n'))
    self._wait_for_str("OK")

  def _wait_for_str(self, strtowait):
    rec = ""
    while not strtowait in rec:
      rec=self.gsm.read(100)
      print("waiting rec:",rec)
      if rec is None:
        rec = ""
      sleep(1)

  def irq_fun(self,orig):
    rec_bytes=self.gsm.read(self.gsm.any())
    #print("rec:",rec_bytes)
    if rec_bytes is not None:
      self.rx_bufb += bytearray(rec_bytes)

  def irq_fun_OLD(self,orig):
    rec_bytes=self.gsm.read()
    rec = rec_bytes.decode("ascii")
    print(rec)
    self.rx_buf = self.rx_buf + rec
    self.rx_bufb = self.rx_bufb + rec_bytes
    if "\r\n" in self.rx_buf:
      lines = self.rx_buf.split("\r\n")
      for l in lines: 
        if "OK" in l:
          print("ok received")
          self.ok = True
          continue
        
      if self.rx_buf.endswith("\r\n"):
        self.rx_buf = ""
      else:
        self.rx_buf = lines[-1]
      
    
  def close(self):
    self.gsm.write('AT+CIPCLOSE'+'\r\n')
    sleep(1)
    print(self.gsm.read(100))
    
  
  def bind(self, address):
    print("bind not implemented")
    #no se muy bien (sera una variable)
    
  def listen(self, backlog=0):
    print("listen not implemented")
    #no se (probablmente un semaforo)
  
  def accept(self):
    print("accept not implemented")
    #tiene que estar bind y escuchando 
  
  def connect(self, address):
    
    self.gsm.write('AT+CIPSTART="TCP","'+address[0]+'","'+str(address[1])+'"'+'\r\n')
    self._wait_for_str("CONNECT")
    
    self.uart2IRQ = self.gsm.irq(trigger = pyb.UART.IRQ_RXIDLE, 
                            handler = self.irq_fun,
                            hard=False)
    
  def send(self, bytes):
    #len=len(bytes)
    #self.gsm.write('AT+CIPSEND='+len+'\r\n')
    #sleep(1)
    sent = self.gsm.write(bytes)
    return sent
    
  def recv(self, bufsize):
    res = self.rx_bufb
    self.rxbufb =""
    return res 
    
  def sendto(self, bytes, address):
    self.gsm.write('AT+CIPSTART="TCP","'+address+'","'+self.port+'"'+'\r\n')
    sleep(1)
    #print(self.gsm.read(100))
    len=len(bytes)
    self.gsm.write('AT+CIPSEND='+len+'\r\n')
    sleep(1)
    self.gsm.write(bytes)
    
  def read(self, size=None):
    if size is None:
      res = self.rx_bufb
      self.rxbufb =""
      return res 
    else:
      while len(self.rx_bufb)<size:
        print("not enough data for read:",size,"current", len(self.rx_bufb), "any", self.gsm.any())
        sleep(1)
      res = self.rx_bufb[:size]
      self.rx_bufb = self.rx_bufb[size:]
      print("read:",res)
      return res
  
  def write(self, buf, size=None):
    if size is None:
      length=len(buf)
      self.gsm.write(buf)
      #print("write:",buf)
    else:
      length=size
      self.gsm.write(buf[:size])
      #print("write:",buf[:size])
    return length
  
  def readinto(self, buf, nbytes=None): 
    if nbytes is None:
      nbytes = len(buf)
    
    while len(self.rx_bufb)<nbytes:
      if self.gsm.any() > 0: 
        self.irq_fun(self.gsm)
      #print("needed:",nbytes,"current", len(self.rx_bufb), "any", self.gsm.any())
      sleep(1)
    
    buf[:] = self.rx_bufb[:nbytes]
    self.rx_bufb = self.rx_bufb[nbytes:]
    #print("read_into:",buf)
    return nbytes
    
  def setblocking(self, flag):
    if flag is True:
      print("modo bloqueante")
    else:
      print("modo no bloqueante")
  


jartieda
Posts: 2
Joined: Fri Aug 14, 2020 9:58 am

Re: Driver for SIM800 SIM808

Post by jartieda » Thu Aug 27, 2020 10:44 am

I have added some corrections and UDP support (tested with ntp)

Code: Select all

import pyb
from time import sleep
import io

AF_INET=2
AF_INET6=10

SOCK_DGRAM=2
SOCK_RAW=3
SOCK_STREAM=1


def getaddrinfo(host, port, af=0, type=0, proto=0, flags=0):
  canonname=flags
  family=(af, (host,port))
  return [family, type, proto, canonname, host]
  
class socket(io.IOBase):
  rx_buf = ""
  rx_bufb = bytearray()
  ok = False
  timeout=30
  uart2IRQ = None
  def __init__(self, af=AF_INET, type=SOCK_STREAM):
    self.af=af
    self.type=type
    self.gsm = pyb.UART(1, 9600, timeout_char=100, read_buf_len=1000)
    print("sent", self.gsm.write('AT'+'\r\n'))
    self._wait_for_str("OK")

  def _wait_for_str(self, strtowait):
    rec = ""
    while not strtowait in rec:
      rec=self.gsm.read(100)
      print("waiting rec:",rec)
      if rec is None:
        rec = ""
      sleep(1)

  def irq_fun(self,orig):
    rec_bytes=self.gsm.read(self.gsm.any())
    #print("rec:",rec_bytes)
    if rec_bytes is not None:
      self.rx_bufb += bytearray(rec_bytes)

  def irq_fun_OLD(self,orig):
    rec_bytes=self.gsm.read()
    rec = rec_bytes.decode("ascii")
    print(rec)
    self.rx_buf = self.rx_buf + rec
    self.rx_bufb = self.rx_bufb + rec_bytes
    if "\r\n" in self.rx_buf:
      lines = self.rx_buf.split("\r\n")
      for l in lines: 
        if "OK" in l:
          print("ok received")
          self.ok = True
          continue
        
      if self.rx_buf.endswith("\r\n"):
        self.rx_buf = ""
      else:
        self.rx_buf = lines[-1]
      
    
  def close(self):
    self.gsm.write('AT+CIPCLOSE'+'\r\n')
    sleep(1)
    print(self.gsm.read(100))
      
  def bind(self, address):
    print("bind not implemented")
    #no se muy bien (sera una variable)
    
  def listen(self, backlog=0):
    print("listen not implemented")
    #no se (probablmente un semaforo)
  
  def accept(self):
    print("accept not implemented")
    #tiene que estar bind y escuchando 
  
  def connect(self, address):
    if self.type == SOCK_STREAM:
      self.gsm.write('AT+CIPSTART="TCP","'+address[0]+'","'+str(address[1])+'"'+'\r\n')
    else: # self.type == SOCK_DGRAM:
      self.gsm.write('AT+CIPSTART="UDP","'+address[0]+'","'+str(address[1])+'"'+'\r\n')

    self._wait_for_str("CONNECT") 
    self.uart2IRQ = self.gsm.irq(trigger = pyb.UART.IRQ_RXIDLE, 
                          handler = self.irq_fun,
                          hard=False)
    
  def send(self, bytes):
    #len=len(bytes)
    #self.gsm.write('AT+CIPSEND='+len+'\r\n')
    #sleep(1)
    sent = self.gsm.write(bytes)
    return sent
    
  def recv(self, bufsize):
    res = self.read(bufsize)
    return res 
    
  def sendto(self, bytes, address):
    if self.type == SOCK_STREAM:
      self.gsm.write('AT+CIPSTART="TCP","'+address[0]+'","'+str(address[1])+'"'+'\r\n')
    else: # self.type == SOCK_DGRAM:
      self.gsm.write('AT+CIPSTART="UDP","'+address[0]+'","'+str(address[1])+'"'+'\r\n')
    self._wait_for_str("CONNECT") 
    self.uart2IRQ = self.gsm.irq(trigger = pyb.UART.IRQ_RXIDLE, 
                          handler = self.irq_fun,
                          hard=False)
    #len=len(bytes)
    #self.gsm.write('AT+CIPSEND='+len+'\r\n')
    #sleep(1)
    self.gsm.write(bytes)
    
  def read(self, size=None):
    if size is None:
      res = self.rx_bufb
      self.rxbufb =""
      return res 
    else:
      count=self.timeout
      while len(self.rx_bufb)<size and count > 0:
        print("not enough data for read:",size,"current", len(self.rx_bufb), "any", self.gsm.any())
        sleep(1)
        count = count - 1
      if len(self.rx_bufb)>=size:
        res = self.rx_bufb[:size]
        self.rx_bufb = self.rx_bufb[size:]
        print("read:",res)
        return res
      else:
        return None
  
  def write(self, buf, size=None):
    if size is None:
      length=len(buf)
      self.gsm.write(buf)
      #print("write:",buf)
    else:
      length=size
      self.gsm.write(buf[:size])
      #print("write:",buf[:size])
    return length
  
  def readinto(self, buf, nbytes=None): 
    if nbytes is None:
      nbytes = len(buf)
    count = self.timeout
    while len(self.rx_bufb)<nbytes and count>0:
      if self.gsm.any() > 0: 
        self.irq_fun(self.gsm)
      #print("needed:",nbytes,"current", len(self.rx_bufb), "any", self.gsm.any())
      sleep(1)
      self.timeout = self.timeout-1 
    if len(self.rx_bufb)<nbytes: 
      nbytes = len(self.rx_bufb)
    buf[:] = self.rx_bufb[:nbytes]
    self.rx_bufb = self.rx_bufb[nbytes:]
    #print("read_into:",buf)
    return nbytes
    
  def setblocking(self, flag):
    if flag is True:
      print("modo bloqueante")
    else:
      print("modo no bloqueante")
  
  def settimeout(self, value):
    self.timeout=value
  


Post Reply