openmv和arduino通信
分析字符串会用到的函数:
isAlphaNumeric() // 判断是否为字母数字
isAlpha() // 判断是否为字母
isAscii() // 判断是否为 ASCII 码
isWhitespace() // 判断是否为空格符
isControl() // 判断是否为控制字符
isDigit() // 判断是否为数字
isGraph() // 判断是否为可打印的字符,不是空格
isLowerCase() // 判断是否为小写
isPrintable() // 判断是否为可打印的字符
isPunct() // 判断是否为标点符号
isSpace() // 判断是否为空格
isUpperCase() // 判断是否为大写
isHexadecimalDigit() // 判断是否为十六进制数字(i.e. 0 - 9, a - F, or A - F)
Arduino中处理字符串的常用方法:
charAt(n)----返回字符串中第n个字符
compareTo(S2)----和给的S2字符串比较
concat(S2)----返回字符串和字符串S2合并后的新字符串
endsWith(S2)----如果字符串是以S2结尾的就返回TRUE
equals(S2)----如果字符串和S2完全相符,就返回TRUE
equalsIgnoreCase(S2)----和equal一样,但是不限制大小写
getBytes(buffer,len)----拷贝提供的字符长度到字节缓冲中
indexOf(S)----返回提供的字符串的索引,如果没有就返回-1
lastIndexOf(S)----和indexOf()一样,但是从字符串尾部开始
length()----返回字符串中的字符数
replace(A,B)----用字符串B替换A
setCharAt(index,c)----把c存储在给定的字符串的索引位置
startsWith(S2)----如果字符串以S2开始就返回TRUE
substring(index)----返回一个从给定索引到结尾的新的字符串
substring(index,to)----同上,但是到给定的to为结束的新的字符串
toCharArray(buffer,len)----从字符串0长度开始到给定的缓冲长度拷贝
toInt()----返回字符串中数字为整数值
toLowerCase()----把字符串全部转化为小写
toUpperCase()----把字符串全部转化为大写
trim()----返回一个去前后空格的字符串
效果展示
接线
openmv ----- arduino
P4(TX) ----- RX
P5 (RX) ----- TX
还有屏幕的看这里:
arduino驱动SPI的FTF_LCD的ST7735屏幕
arduino代码:
#include <SPI.h>
#include "Ucglib.h"
volatile int flag;
String shuju;
bool stringComplete = false; //字符串是否完成
int CenterX;
int CenterY;
/*
Hardware SPI Pins:
Arduino Uno sclk=13, data=11
Arduino Due sclk=76, data=75
Arduino Mega sclk=52, data=51
*/
Ucglib_ST7735_18x128x160_SWSPI ucg(/*sclk=*/ 13, /*data=*/ 11, /*cd=*/ 9 , /*cs=*/ 10, /*reset=*/ 8);
void setup(void)
{
flag = 0;
shuju = "0";
Serial.begin(9600);
delay(1000);
//ucg.begin(UCG_FONT_MODE_TRANSPARENT); //字体模式透明
ucg.begin(UCG_FONT_MODE_SOLID); //立体字,有底字
ucg.clearScreen(); //清除屏幕
ucg.setColor(0, 120, 0, 0);
ucg.setColor(2, 0, 120, 0);
ucg.setColor(1, 120, 0, 120);
ucg.setColor(3, 0, 120, 120);
ucg.drawGradientBox(0, 0, ucg.getWidth(), ucg.getHeight()); //背景设置
}
void loop(void)
{
/*
for (int i = 0; i < 100; i++) {
ucg.drawPixel(i, 20); //画点
} //画线
*/
if (stringComplete) {
// Serial.print(shuju);
dataProcessing();
shuju = "";
stringComplete = false;
}
}
int foundStr(char Str) //找字符的位置
{
int founddata;
founddata = shuju.indexOf(Str); //'{'所在的位置
return founddata;
}
String shujuduan(int first, int last) //定义 数据段 函数
{
String Strdata;
Strdata = String(shuju).substring(first, last); //赋值Strdata是first到last的字符串
return Strdata;
}
void dataProcessing() //数据处理
{
int X_location; //X的位置
int Y_location; //Y的位置
int B_location; //Y的位置
String X_Str;
String Y_Str;
X_location = foundStr('X');
Y_location = foundStr('Y');
X_Str=shujuduan(X_location+1, Y_location); //X到Y的位置
X_location = foundStr('Y');
B_location = foundStr('B');
Y_Str=shujuduan(Y_location+1, B_location); //Y到B的位置
/*
Serial.print("X_Str:");
Serial.print(X_Str);
Serial.print(" Y_Str:");
Serial.println(Y_Str);
*/
CenterX=X_Str.toInt();
CenterY=Y_Str.toInt(); //转成可以用的整型
Serial.print("CenterX:");
Serial.print(CenterX);
Serial.print(" CenterY:");
Serial.println(CenterY);
}
void serialEvent() {
while (Serial.available()) {
//获取新的字节
char inChar = (char)Serial.read();
shuju += inChar;
if (inChar == '\n') {
stringComplete = true;
}
}
}
openmv代码:
import sensor, image, time
from pid import PID
from pyb import Servo
from pyb import UART
uart = UART(3, 9600) #P4 TX P5 RX
green_threshold = (35, 60, 76, 15, 5, 70)
sensor.reset() # Initialize the camera sensor.
sensor.set_pixformat(sensor.RGB565) # use RGB565. 128*160
sensor.set_framesize(sensor.QQVGA) # use QQVGA for speed.
sensor.skip_frames(10) # Let new settings take affect.
sensor.set_auto_whitebal(False) # turn this off.
clock = time.clock() # Tracks FPS.
def find_max(blobs):
max_size=0
for blob in blobs:
if blob[2]*blob[3] > max_size:
max_blob=blob
max_size = blob[2]*blob[3]
return max_blob
while(True):
clock.tick() # Track elapsed milliseconds between snapshots().
img = sensor.snapshot() # Take a picture and return the image.
blobs = img.find_blobs([green_threshold])
if blobs:
max_blob = find_max(blobs)
img.draw_rectangle(max_blob.rect()) # rect
img.draw_cross(max_blob.cx(), max_blob.cy()) # cx, cy
#print("X:",max_blob.cx(),"Y:",max_blob.cy())
X_error = max_blob.cx()-img.width()/2 #底的误差为最大色块所在的X轴-宽(宽固定=160 /2=80)我理解为取XY中心点
Y_error = max_blob.cy()-img.height()/2
X_error = int(X_error)
Y_error = int(Y_error)
print("X:",X_error,"Y:",Y_error)
#uart.write("X:",X_error,"Y:",Y_error+'\r\n')
'''
图像大小为160*120
所以中心点是(80,60)
160/2-现在的位置=X
120/2-现在的位置=Y
'''
uart.write("A")
uart.write("X"+str(X_error))
uart.write("Y"+str(Y_error))
uart.write("B")
uart.write("\r\n")