ev3dev / ev3dev-lang-python

Pure python bindings for ev3dev
MIT License
422 stars 146 forks source link

Object tracking with NXT Cam V4 for LEGO Mindstorms #792

Open gara-3004 opened 1 year ago

gara-3004 commented 1 year ago

Hello,

I am trying to program an object tracking robot with lego mindstorms using the python language. However I am not able to communicate with the NXT cam.

#!/usr/bin/env pybricks-micropython
from pybricks.hubs import EV3Brick
from pybricks.ev3devices import (Motor, TouchSensor, ColorSensor,
                                 InfraredSensor, UltrasonicSensor, GyroSensor)
from pybricks.parameters import Port, Stop, Direction, Button, Color
from pybricks.tools import wait, StopWatch, DataLog
from pybricks.robotics import DriveBase
from pybricks.media.ev3dev import SoundFile, ImageFile

# This program requires LEGO EV3 MicroPython v2.0 or higher.
# Click "Open user guide" on the EV3 extension tab for more information.

# Create your objects here.
ev3 = EV3Brick()

# Write your program here.
ev3.speaker.beep()

import ev3dev2
from ev3dev2 import sensor
from ev3dev2.sensor import lego
from ev3dev2.sensor.lego import I2C

# Set up the I2C port on the EV3 for communication with the NXTCam-v4
i2c_port = ev3dev2.get_current_i2c_bus()
i2c_address = 0x01 # NXTCam-v4 I2C address
i2c_sensor = lego.I2C(i2c_port, i2c_address)

# Turn on the camera
i2c_sensor.mode = lego.I2C.MODE_RAW # Set I2C mode to RAW
i2c_sensor.write(0x01, 0x00) # Write 0x00 to register 0x01 to turn on the camera

# Read data from the camera
while True:
    i2c_sensor.write(0x00, 0x00) # Write 0x00 to register 0x00 to trigger a new frame
    data = i2c_sensor.read(8, lego.I2C.REPEAT) # Read 8 bytes of data from the camera
    # Process the data as needed

I tried this code but it keeps bringing up the error : no module named 'ev3dev2'

dlech commented 1 year ago

Pybricks is not the same as ev3dev-lang-python. You can't use both at the same time. To use ev3dev-lang-python, change the shebang to #!/usr/bin/env python3 and replace all of the Pybricks code with the ev3dev-lang-python equivalent.

gara-3004 commented 1 year ago
from ev3dev2.sensor import INPUT_1, INPUT_2, INPUT_3, INPUT_4
from ev3dev2.sensor.lego import TouchSensor, ColorSensor, InfraredSensor, UltrasonicSensor, GyroSensor
from ev3dev2.motor import OUTPUT_A, OUTPUT_B, OUTPUT_C, OUTPUT_D, LargeMotor, MediumMotor
from ev3dev2.sound import Sound
from ev3dev2.display import Display
from time import sleep

do you mean like this?

dlech commented 1 year ago

Yes, that looks right.

gara-3004 commented 1 year ago

I gave it another try with your correction, now it shows ImportError: cannot import name 'I2C'.

dlech commented 1 year ago

Where did you get the code? There is no I2C class. Maybe you meant I2CSensor?

gara-3004 commented 1 year ago

My main problem is that I am struggling to set up a communication with NXT cam since there is only poor information on the internet. Now I tried this code:

#!/usr/bin/env python3

from ev3dev2.sensor import INPUT_1, INPUT_2, INPUT_3, INPUT_4
from ev3dev2.motor import LargeMotor, OUTPUT_A, OUTPUT_B, OUTPUT_C, OUTPUT_D
from ev3dev2.port import LegoPort
from time import sleep
i= 1

from smbus import SMBus
bus = SMBus(4) # NXTCam-v5 plugged into input port 2, /dev/i2c-in2 -> i2c-4
address = 0x01
bus.write_byte_data(address, 0x41, 0x42)  # set object tracking mode
num = bus.read_byte_data(address, 0x42)  # get number of tracked objects
data = bus.read_i2c_block_data(address, 0x43 + i * 5, 5)

print("color: ", data[0])
print("x coordinate upper left corner: ", data[1])
print("y coordinate upper left corner: ", data[2])
print("x coordinate lower right corner: ", data[3])
print("x coordinate lower right corner: ", data[4])

But it shows up the following error:

Traceback (most recent call last):
  File "/home/robot/anothercamtest/main.py", line 13, in <module>
    bus.write_byte_data(address, 0x41, 0x42)  # set object tracking mode
OSError: [Errno 16] Device or resource busy
----------
Exited with error code 1.
dlech commented 1 year ago

To be able to use SMBus with an I2C sensor, you must set the mode of the port to "i2c-other" first.

gara-3004 commented 1 year ago

I am just trying to realize a simple program where for example a motor is being moved, when the teached object is detected by the camera. Just to check if the camera is even working. I didn't find any information do you maybe experimented with the camera?