Can anyone help me with my simple project? I’m very new on the OpenMV M7. I just need to move a mini servo depending on the text read on the QR Code.
I’ve used the sample QR Code and the text on the QR is printed on the “payload”. How can i extract the payload and use it as a variable to move the servo by a certain degrees?
import sensor, image, time
from pyb import Servo
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.skip_frames(time = 2000)
sensor.set_auto_gain(False) # must turn this off to prevent image washout...
clock = time.clock()
while(True):
clock.tick()
img = sensor.snapshot()
img.lens_corr(1.8) # strength of 1.8 is good for the 2.8mm lens.
for code in img.find_qrcodes():
img.draw_rectangle(code.rect(), color = (255, 0, 0))
print(code)
if (code == "LEFT"):
s1 = pyb.Servo(1)
s1.angle(45)
I’m pretty sure that the last if statement doesn’t work. How do I proceed with this? Your help is greatly appreciated.
codes = img.find_qrcodes()
for code in codes:
img.draw_rectangle(code.rect(), color = (255, 0, 0))
print(code)
if codes:
if code[0].payload == "LEFT":
s1 = pyb.Servo(1)
s1.angle(45)
This extracts the text for the first QR code seen.
The find QR codes method returns a list of objects, so, I put the list in a variable above, then look at the first object in the list and get the payload of it. I check to make sure the list is not empty first however.
Thanks for the help but I’ve come up into an error while trying the code you provided me. The error that appeared says "AttributeError: ‘int’ object has no attribute ‘payload’.
Can you help me again? Here’s the full code, and while it displays the error it highlights the line of the code: if code[0].payload == “LEFT”:
import sensor, image, time
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.skip_frames(time = 2000)
clock = time.clock()
while(True):
clock.tick()
img = sensor.snapshot()
img.lens_corr(1.8)
print(clock.fps())
codes = img.find_qrcodes()
for code in codes:
img.draw_rectangle(code.rect(), color = (255, 0, 0))
print(code)
if codes:
if code[0].payload == "LEFT":
s1 = pyb.Servo(1)
s1.angle(45)
Thank you very much. I’ve tested it before going, it works as expected. One more thing, I’ve printed some QR codes but the OpenMV Cam doesn’t immediately detect it unless on some certain conditions like when the background is white. Also can I use lists like the ones I’ve seen on online references to read multiple payloads?
like:
my_list = ["LEFT", "RIGHT"]
and replace the if codes with:
if code.payload() == "my_list"
will it not cause errors? I’m not at home currently for the next few days and I wanna know if my idea would be functional. Thanks again!
Qr codes require the background to be white. The scanning algorithm looks for certain attributes about the area around a QR code before decoding them. In particular, you absolutely need to have enough of a white border around the codes or the algorithm ignores the codes.
As for your second question… You’re asking how to compare against a list? This is a python question. Just a tip, if something seems like a core language problem google for it and the answer will be available on stack overflow. Just about anything you need to know about python has an answer out there. Anyway, do this:
if code.payload() in my_list:
Yes, python has a method to do what you want built-in.
I am pretty new to this camera and have big problems to get this code running.
I am copy your Code and included the Parens but getting always the Error
AttributeError: ‘int’ object has no attribute ‘payload’
I tryed to figure the error out for Hours but its not working
import sensor, image, time
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.skip_frames(time = 2000)
clock = time.clock()
while(True):
clock.tick()
img = sensor.snapshot()
img.lens_corr(1.8)
print(clock.fps())
codes = img.find_qrcodes()
for code in codes:
img.draw_rectangle(code.rect(), color = (255, 0, 0))
print(code)
if codes:
if code[0].payload() == "LEFT":
s1 = pyb.Servo(1)
s1.angle(45)
Accessing code[0] makes no sense. That variable isn’t in scope at that time in your code. However, since MP doesn’t garbage cleanup variables quickly you don’t get an error about accessing an out of scope variable… But, you are doing that.
Okay that works thanks but i have another Question i am playing arround a bit and try to figure out how i can acces maybe the second character of the payload i tryied differnt things but always with an error message.
On the internet i read something like this print(a[1])
and i tryed to do that with
if codes[0].payload([1]) == “LEFT”:
but then i get this errormessage
TyperError: function takes 1 positional arguments but 2 were given
I have a weird problem i use my code and hooked everything up to comunicate to an arduino uno. If i use the uart example in openmw it works that it outputs everything to the arduino serial monitor.
Now i have a more complex sketch in arduino were the given numbers read out by openmv make a servo move. But it is now only showing weird characters in the serial monitor if the openmv sends the numbers. Also it looks like that the arduino is also sending stuff to the openmv because i can see text that should be outputed in the arduino serial monitor in the serial monitor from openmv. Could you explane this
import sensor, image, time, pyb
from pyb import UART
red = pyb.LED(1)
green = pyb.LED(2)
blue = pyb.LED(3)
ir = pyb.LED(4)
uart = UART(3, 19200)
sensor.reset()
sensor.set_pixformat(sensor.GRAYSCALE)
sensor.set_framesize(sensor.VGA)
sensor.set_windowing((240, 240)) # look at center 240x240 pixels of the VGA resolution.
sensor.skip_frames(time = 2000)
sensor.set_auto_gain(False) # must turn this off to prevent image washout...
#clock = time.clock()
while(True):
#clock.tick()
img = sensor.snapshot()
#print(clock.fps())
codes = img.find_qrcodes()
for code in codes:
img.draw_rectangle(code.rect(), color = (255, 0, 0))
print(code)
if codes:
if codes[0].payload()[1] == "0":
uart.write(code[4])
if (uart.any()):
print(uart.read())
time.sleep(1000)
if codes[0].payload()[1] == "0":
uart.write(code[4])
if (uart.any()):
print(uart.read())
time.sleep(1000)
if codes[0].payload()[1] == "1":
uart.write(code[4])
if (uart.any()):
print(uart.read())
time.sleep(1000)
if codes[0].payload()[1] == "2":
uart.write(code[4])
if (uart.any()):
print(uart.read())
time.sleep(1000)
if codes[0].payload()[1] == "3":
uart.write(code[4])
if (uart.any()):
print(uart.read())
time.sleep(1000)
if codes[0].payload()[1] == "4":
uart.write(code[4])
if (uart.any()):
print(uart.read())
time.sleep(1000)
if codes[0].payload()[1] == "5":
uart.write(code[4])
if (uart.any()):
print(uart.read())
time.sleep(1000)
if codes[0].payload()[1] == "6":
uart.write(code[4])
if (uart.any()):
print(uart.read())
time.sleep(1000)
This is the openmv sketch
// zoomkat 12-13-11 serial servo (2) test
// for writeMicroseconds, use a value like 1500
// for IDE 1.0
// Powering a servo from the arduino usually DOES NOT WORK.
// two servo setup with two servo commands
// send eight character string like 15001500 or 14501550
// use serial monitor to test
#include <AccelStepper.h>
#include <AFMotor.h>
#include <Servo.h>
AF_Stepper motor1(200, 1);
String readString, servo1, servo2;
Servo myservo1; // create servo object to control a servo
Servo myservo2;
Servo myservo3;
int ir1 = 8;
int ir2 = 10;
int ir3 = 11;
int irstart = 4;// connect the starting ir to these pin
//Declare pin functions on RedBoard
#define stp 2
#define dir 3
//#define MS1 4
//#define MS2 5
//#define EN 6
//Declare variables for functions
char user_input;
int x;
int y;
int state;
void StepForwardDefault()
{
Serial.println("Moving forward at default step mode.");
digitalWrite(dir, LOW); //Pull direction pin low to move "forward"
// for (x = 0; x < 1000; x++) //Loop the forward stepping enough times for motion to be visible
for (;;)
{
digitalWrite(stp, HIGH); //Trigger one step forward
delay(1);
digitalWrite(stp, LOW); //Pull step pin low so it can be triggered again
delay(1);
}
}
void StopForwardDefault()
{
Serial.println("stopping to read default step mode.");
digitalWrite(dir, LOW); //Pull direction pin low to move "forward"
for (x = 0; x < 1000; x++) //Loop the forward stepping enough times for motion to be visible
{
digitalWrite(stp, LOW); //Trigger one step forward
delay(1);
digitalWrite(stp, LOW); //Pull step pin low so it can be triggered again
delay(1);
}
}
AccelStepper stepper;//(forwardstep, backwardstep); // use functions to step Defaults to AccelStepper::FULL4WIRE (4 pins) on 2, 3, 4, 5
void setup() {
pinMode(stp, OUTPUT);
pinMode(dir, OUTPUT);
pinMode(ir1, INPUT);
pinMode(ir2, INPUT);
pinMode(ir3, INPUT);
Serial.begin(19200);
myservo1.attach(6);
myservo2.attach(7); //the pin for the servo control
myservo3.attach(9);
stepper.setMaxSpeed(50);
stepper.setSpeed(50);
/*
myservo1.write(45);
// delay(30);
// myservo1.write(0);
delay(30);
myservo2.write(45);
//delay(30);
//myservo2.write(0);
delay(30);
myservo2.write(45);
//delay(30);
//myservo1.write(0);
delay(30);
*/
digitalWrite(ir1, LOW);
digitalWrite(ir2, LOW);
digitalWrite(ir3, LOW);
Serial.println("SORTING MACHINE");
Serial.println("CONFIGURINRATON DONE");
}
void loop() {
int ir1read = digitalRead(ir1);
int ir2read = digitalRead(ir2);
int ir3read = digitalRead(ir3);
////================================================
//=====================================================
if (Serial.available() > 0) {
StopForwardDefault();
mains();
}
else {
StepForwardDefault();
if (ir1read == HIGH) {
myservo1.write(45);
delay(30);
}
if (ir2read == HIGH) {
myservo3.write(45);
delay(30);
}
if (ir3read == HIGH) {
myservo3.write(45);
delay(30);
}
}
}
void mains()
{
while (Serial.available()) {
// StopForwardDefault();
delay(3); //delay to allow buffer to fill
if (Serial.available() > 0) {
char c = Serial.read(); //gets one byte from serial buffer
// Serial.println(c);
readString += c; //makes the string readString
}
}
if (readString.length() > 0) {
Serial.println(readString); //see what was received
// expect a string like 07002100 containing the two servo positions
servo1 = readString; //.substring(0, 2); //get the first four characters
// servo2 = readString.substring(4, 8); //get the next four characters
Serial.println("CONTROL THE SERVO :: ");
Serial.print(servo1); //print to serial monitor to see parsed results
// Serial.println(servo2);
if ( servo1 .startsWith("10")) {
myservo1.write(180);
delay(30);
Serial.println("SERVO 1 MOVED ");
}
else if ( servo1 .startsWith("11")) {
myservo2.write(180);
delay(30);
Serial.println("SERVO 2 MOVED ");
}
else if ( servo1 .startsWith("12")) {
myservo3.write(180);
delay(30);
Serial.println("SERVO 3 MOVED ");
}
readString = "";
}
}
Hi, with a quick look at your code I see that you are using the Serial Port for the Arduino to receive data and see it via the Serial Monitor…
So, your Arduino only has one hardware Serial Port. The OpenMV Cam is sending data to this serial port and then you are printing to this same serial port to the PC. What’s happening is that you are observing the device communication on your Serial Monitor.
You should create a second serial port using software serial to connect the camera to the Arduino…
…
I’ll look over your code in more detail in a bit to see what changes you can do to fix any issues…