Grove Vision AI V2 with micropython

Hello from Argentina!, I am trying to use the Grove Vision AI V2 with the Arduino Alvik robot (Arduino Nano ESP32 running micropython). I connected the Grove vision to the robot using the I2C Grove plug.
I adapted part of the SSCMA library (Seeed_Arduino_SSCMA/src/Seeed_Arduino_SSCMA.cpp at main · Seeed-Studio/Seeed_Arduino_SSCMA · GitHub) to Micropython but it’s not working correctly.

When I connect the Grove vision v2, press reset, run the code down below I am getting this output:

raw REPL; CTRL-B to exit
>OKb'AT+NAME?\n\r'
b'\x00\xe8'
232
buffer: bytearray(b'\r{"type": 1, "name": "INIT@SENSOR", "code": 0, "data": {"sensor": {"id": 1, "type": 1, "state": 1, "opt_id": 0, "opt_detail": "240x240 Auto"}}}\n\r{"type": 0, "name": "INIT@STAT?", "code": 0, "data": {"boot_count": 0, "is_ready": 1}}\n').

It’s not AT+NAME but, at least, I get something, but, when I run it again, I always get:

raw REPL; CTRL-B to exit
>OKb'AT+NAME?\n\r'
b'\x00\x00'
0
b'\x00\x00'
0
b'\x00\x00'
0
>

0 from the available function. It seems it’s ignoring the AT command I am sending.The first time it runs I get something, but it’s not AT+NAME, it’s a kind of status, but it’s not what I need.
When I press reset on the Grove Vision V2, I am getting again the json with the status message.

Don’t know if someone can give me a lead.

Many thanks!
Fernando Gonzalez Sidders

from machine import I2C,SoftI2C
from machine import Pin
import utime
import sys

I2CADDRESS = 0x62
wait_delay=100

#i2c = I2C(1, scl=Pin(12, Pin.OUT), sda=Pin(11, Pin.OUT))
i2c = SoftI2C(scl=Pin(12, Pin.OUT), sda=Pin(11, Pin.OUT))
i2c.start()

def available():
  utime.sleep_ms(wait_delay)
  i2c.writeto(I2CADDRESS,bytearray([0x10,0x03,0x00,0x00,0x00,0x00]))
  utime.sleep_ms(wait_delay)
  buf = i2c.readfrom(I2CADDRESS,2)
  print(buf)
  return (buf[0] << 8) | buf[1]

def write(data):
  length=len(data)
  utime.sleep_ms(wait_delay)
  i2c.write(bytearray([0x10]))
  i2c.write(bytearray([0x02]))
  i2c.write(bytearray([length >> 8]))
  i2c.write(bytearray([length & 0xFF]))
  i2c.write(data)
  i2c.write(bytes([0x00]))
  i2c.write(bytes([0x00]))


def read(size):
  utime.sleep_ms(wait_delay)
  i2c.writeto(I2CADDRESS,bytearray([0x10,0x01,size >> 8,size & 0xFF,0x00,0x00]))
  utime.sleep_ms(wait_delay)
  buf = bytearray(size)
  i2c.readfrom_into(I2CADDRESS, buf)
  utime.sleep_ms(wait_delay)
  return buf

command = "AT+NAME?"
data ='{}\n\r'.format(command).encode('utf-8')
print(data)
write(data)
deadline = utime.ticks_add(utime.ticks_ms(), 500)
while utime.ticks_diff(deadline, utime.ticks_ms()) > 0:
  out=available()
  print(out)
  if 0<out<65535:
    break;
    
utime.sleep_ms(wait_delay)
if 0<out<65535 :
  buf = read(out)
  print(f'buffer: {buf}.')

i2c.stop()

One more thing, if I connect the Grove VIsion to my notebook (usb-c) and run minicom in Ubuntu, the AT commands are replied correctly.

May be a silly question. But does the “\n\r” look correct? Generally AT Commands require a “\r\n”.

You may need to reset the I2C interface (or the sensor) before each attempt. This can be done using the i2c.deinit() and i2c.init() methods in MicroPython to reset the communication line.

i2c.deinit()  # Reset the I2C bus
utime.sleep_ms(100)  # Wait a moment for the reset
i2c.init(SoftI2C, scl=Pin(12, Pin.OUT), sda=Pin(11, Pin.OUT))  # Reinitialize the bus

Yes, correct! my mistake!, I fixed it but still the AT command is not executed :frowning:

Many thanks for the tip.

I tried but deinit() works only for CC3200/WiPy. I will try to reset the interface in a different way, thanks for the advice!

I have solved it!!! The problem was in the function write, I was sending the headers in a write command and then, the at string in another one. I put the headers and the at command in only one byte array, used only a write and it’s working now!

The modified function:

def write(data):
  size=len(data)
  utime.sleep_ms(wait_delay)
  arr = bytes([0x10,0x02,size >> 8,size & 0xFF]) + data 
  i2c.writeto(I2CADDRESS,arr)
  utime.sleep_ms(wait_delay)
1 Like