Join GitHub today
GitHub is home to over 36 million developers working together to host and review code, manage projects, and build software together.Sign up
I2C NXTCam-v5 Python program #1007
I would like to communicate with my NXTCam-v5 via I2C to receive the coordinates of multiple objects. I am using ev3dev with Python and I am wondering whether someone has implemented I2C communication between the EV3 and the NXTCam-v5 (or any similar sensor) in Python and could provide some code? That would be great - thank you.
Image file: ev3dev-jessie-ev3-generic-2017-09-14
This is NOT ev3dev-lang-python, but here is something I was playing around with...
#!/usr/bin/env micropython """Sample program using EXPLOR3R""" from uev3dev import * # init display display = Display() fbuf, fbuf_data = display.framebuffer() # init motors left_motor = LargeMotor('B') right_motor = LargeMotor('C') # fun with I2C in4 = EV3InputPort('4') in4.mode = 'other-i2c' bus4 = SMBus('/dev/i2c-in4') bus4.set_address(0x01) firmware = bytes(bus4.read_i2c_block_data(0x00, 8)).decode().strip() vendor = bytes(bus4.read_i2c_block_data(0x08, 8)).decode().strip() product = bytes(bus4.read_i2c_block_data(0x10, 8)).decode().strip() debug_print(firmware, vendor, product) if vendor != 'mndsnsrs' or product != 'NXTcam5': raise ValueError('Wrong sensor') # functions def scale(x1, y1, x2, y2): """Convert points from NXTCam to screen rectangle""" x1 = x1 * display.width // 240 y1 = y1 * display.height // 160 x2 = x2 * display.width // 240 y2 = y2 * display.height // 160 return x1, y1, x2 - x1, y2 - y1 # Main loop bus4.write_byte_data(0x41, 0x46) # set face tracking mode while True: n = bus4.read_byte_data(0x42) fbuf.fill(1) for i in range(0, n): data = bus4.read_i2c_block_data(0x43 + i * 5, 5) color = data x1 = data y1 = data x2 = data y2 = data x, y, w, h = scale(x1, y1, x2, y2) fbuf.rect(x, y, w, h, 0) display.update(fbuf_data) speed = n and ((x1 + x2 // 2) - 128) // 4 left_motor.run_unregulated(-speed) right_motor.run_unregulated(speed)
You should be able to copy the I2C commands along with
I had an algorithm for reading multiple objects, but I don't think I saved it. Basically, in the while loop I would read one byte from 0x42, which tells the number of objects then
I2C register definitions are in the User's Manual if you haven't found that already: http://www.mindsensors.com/pdfs/NXTCam5-User-Guide.pdf
thank you for the reply - it helped me a lot and since then I've been playing around with the camera a lot. This is the ev3dev-lang-python code I used to implement the communication (just a single read):
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 if num == 0: raise RuntimeError("Zero objects detected.") for i in range(0, num): data = bus.read_i2c_block_data(address, 0x43 + i * 5, 5) # print information on detected objects (rectangles) print("color: ", data) print("x coordinate upper left corner: ", data) print("y coordinate upper left corner: ", data) print("x coordinate lower right corner: ", data) print("x coordinate lower right corner: ", data)
One thing I still couldn't figure out though is how to automatically set the mode of the input port to
I further tried a solution similar to the one you have implemented above:
port = LegoPort(INPUT_2) port.mode = 'other-i2c'
However, if I execute this before opening the SMBus for the I2C communication, I always receive the same permission error as above. Remark: In both cases the mode of the input port is correctly changed from
Do you (or anybody else) have an idea what the problem might be and how I could achieve what I am trying to do? Thank you for your help and any kind of further assistance!