首先登渣,這篇文章主要是討論processing和arduino之間串口通訊的噪服。不解釋,做過arduino+processing的一定都遇到過這樣的問題胜茧,arduino/processing想要給對方發(fā)送數(shù)據(jù)粘优,或者從對方接收到數(shù)據(jù),各種函數(shù)不知道要怎么寫呻顽。雹顺。
先列一下二者串口的函數(shù)。廊遍。
processing
讀取
read()
readChar()
readBytes()
readBytesUntil()
readString()
readStringUntil()
寫入
write()
arduino
讀取
read()
readBytes()
readBytesUntil()
readString()
readStringUntil()
寫入
print()
println()
write()
下面根據(jù)使用場景列一下代碼
arduino給processing發(fā)送一個0-255的數(shù)字
arduino:
serial.write();
processing:
serial.read();
arduino給processing發(fā)送一個字符
processing
import processing.serial.*;
Serial myPort; // Create object from Serial class
int val; // Data received from the serial port
void setup()
{
size(200, 200);
// I know that the first port in the serial list on my mac
// is always my FTDI adaptor, so I open Serial.list()[0].
// On Windows machines, this generally opens COM1.
// Open whatever port is the one you're using.
String portName = Serial.list()[1];
myPort = new Serial(this, portName, 9600);
}
void draw()
{
if ( myPort.available() > 0) { // If data is available,
val = myPort.read(); // read it and store it in val
print(val);
}
}
void keyPressed(){
int i = 2;
myPort.write('2');
delay(100);
}
arduino
// Wiring/Arduino code:
// Read data from the serial and turn ON or OFF a light depending on the value
int val; // Data received from the serial port
int ledPin = 13; // Set the pin to digital I/O 4
void setup() {
Serial.begin(9600); // Start serial communication at 9600 bps
}
void loop() {
if (Serial.available()) { // If data is available to read,
val = Serial.read(); // read it and store it in val
if(val == '2'){
Serial.write('0');
}else
Serial.print(val);
}
}
arduino給processing發(fā)送一個大于255的數(shù)字
arduino
processing
Serial.println(number);
processing
String inString = myPort.readStringUntil('\n');
inString = inString.trim();
int number = int(inString);
arduino 連接串口攝像頭嬉愧,獲取照片信息,然后通過串口發(fā)送給processing
arduino
// File SerialCamera_DemoCode_CJ-OV528.ino
// 8/8/2013 Jack Shao
// Demo code for using seeeduino or Arduino board to cature jpg format
// picture from seeed serial camera and save it into sd card. Push the
// button to take the a picture .
// For more details about the product please check http://www.seeedstudio.com/depot/
#include <SPI.h>
#include <arduino.h>
#include <SD.h>
#define PIC_PKT_LEN 128 //data length of each read, dont set this too big because ram is limited
#define PIC_FMT_VGA 7
#define PIC_FMT_CIF 5
#define PIC_FMT_OCIF 3
#define CAM_ADDR 0
#define CAM_SERIAL Serial1
#define PIC_FMT PIC_FMT_VGA
File myFile;
const byte cameraAddr = (CAM_ADDR << 5); // addr
unsigned long picTotalLen = 0; // picture length
/*********************************************************************/
void setup()
{
Serial.begin(115200);
CAM_SERIAL.begin(115200);
// Serial.println("Initializing SD card....");
pinMode(10,OUTPUT); // CS pin of SD Card Shield
if (!SD.begin(10))
{
// Serial.print("sd init failed");
return;
}
// Serial.println("sd init done.");
initialize();
}
/*********************************************************************/
void loop()
{
if (Serial.available()) { // If data is available to read,
int val = Serial.read(); // read it and store it in val
if(val == '2'){
preCapture();
Capture();
GetData();
sendData();
}
}
}
/*********************************************************************/
void clearRxBuf()
{
while (CAM_SERIAL.available())
{
CAM_SERIAL.read();
}
}
/*********************************************************************/
void sendCmd(char cmd[], int cmd_len)
{
for (char i = 0; i < cmd_len; i++) CAM_SERIAL.print(cmd[i]);
}
/*********************************************************************/
void initialize()
{
char cmd[] = {0xaa,0x0d|cameraAddr,0x00,0x00,0x00,0x00} ;
unsigned char resp[6];
CAM_SERIAL.setTimeout(500);
while (1)
{
//clearRxBuf();
sendCmd(cmd,6);
if (CAM_SERIAL.readBytes((char *)resp, 6) != 6)
{
continue;
}
if (resp[0] == 0xaa && resp[1] == (0x0e | cameraAddr) && resp[2] == 0x0d && resp[4] == 0 && resp[5] == 0)
{
if (CAM_SERIAL.readBytes((char *)resp, 6) != 6) continue;
if (resp[0] == 0xaa && resp[1] == (0x0d | cameraAddr) && resp[2] == 0 && resp[3] == 0 && resp[4] == 0 && resp[5] == 0) break;
}
}
cmd[1] = 0x0e | cameraAddr;
cmd[2] = 0x0d;
sendCmd(cmd, 6);
// Serial.println("\nCamera initialization done.");
}
/*********************************************************************/
void preCapture()
{
char cmd[] = { 0xaa, 0x01 | cameraAddr, 0x00, 0x07, 0x00, PIC_FMT };
unsigned char resp[6];
CAM_SERIAL.setTimeout(100);
while (1)
{
clearRxBuf();
sendCmd(cmd, 6);
if (CAM_SERIAL.readBytes((char *)resp, 6) != 6) continue;
if (resp[0] == 0xaa && resp[1] == (0x0e | cameraAddr) && resp[2] == 0x01 && resp[4] == 0 && resp[5] == 0) break;
}
}
void Capture()
{
char cmd[] = { 0xaa, 0x06 | cameraAddr, 0x08, PIC_PKT_LEN & 0xff, (PIC_PKT_LEN>>8) & 0xff ,0};
unsigned char resp[6];
CAM_SERIAL.setTimeout(100);
while (1)
{
clearRxBuf();
sendCmd(cmd, 6);
if (CAM_SERIAL.readBytes((char *)resp, 6) != 6) continue;
if (resp[0] == 0xaa && resp[1] == (0x0e | cameraAddr) && resp[2] == 0x06 && resp[4] == 0 && resp[5] == 0) break;
}
cmd[1] = 0x05 | cameraAddr;
cmd[2] = 0;
cmd[3] = 0;
cmd[4] = 0;
cmd[5] = 0;
while (1)
{
clearRxBuf();
sendCmd(cmd, 6);
if (CAM_SERIAL.readBytes((char *)resp, 6) != 6) continue;
if (resp[0] == 0xaa && resp[1] == (0x0e | cameraAddr) && resp[2] == 0x05 && resp[4] == 0 && resp[5] == 0) break;
}
cmd[1] = 0x04 | cameraAddr;
cmd[2] = 0x1;
while (1)
{
clearRxBuf();
sendCmd(cmd, 6);
if (CAM_SERIAL.readBytes((char *)resp, 6) != 6) continue;
if (resp[0] == 0xaa && resp[1] == (0x0e | cameraAddr) && resp[2] == 0x04 && resp[4] == 0 && resp[5] == 0)
{
CAM_SERIAL.setTimeout(1000);
if (CAM_SERIAL.readBytes((char *)resp, 6) != 6)
{
continue;
}
if (resp[0] == 0xaa && resp[1] == (0x0a | cameraAddr) && resp[2] == 0x01)
{
picTotalLen = (resp[3]) | (resp[4] << 8) | (resp[5] << 16);
// Serial.print("picTotalLen:");
Serial.println(picTotalLen);
break;
}
}
}
}
/*********************************************************************/
void GetData()
{
unsigned int pktCnt = (picTotalLen) / (PIC_PKT_LEN - 6);
if ((picTotalLen % (PIC_PKT_LEN-6)) != 0) pktCnt += 1;
char cmd[] = { 0xaa, 0x0e | cameraAddr, 0x00, 0x00, 0x00, 0x00 };
unsigned char pkt[PIC_PKT_LEN];
char picName[] = "pic.jpg";
if (SD.exists(picName))
{
SD.remove(picName);
}
myFile = SD.open(picName, FILE_WRITE);
if(!myFile){
// CAM_SERIAL.println("myFile open fail...");
}
else{
CAM_SERIAL.setTimeout(1000);
for (unsigned int i = 0; i < pktCnt; i++)
{
cmd[4] = i & 0xff;
cmd[5] = (i >> 8) & 0xff;
int retry_cnt = 0;
retry:
delay(10);
clearRxBuf();
sendCmd(cmd, 6);
uint16_t cnt = CAM_SERIAL.readBytes((char *)pkt, PIC_PKT_LEN);
unsigned char sum = 0;
for (int y = 0; y < cnt - 2; y++)
{
sum += pkt[y];
}
if (sum != pkt[cnt-2])
{
if (++retry_cnt < 100) goto retry;
else break;
}
myFile.write((const uint8_t *)&pkt[4], cnt-6);
//if (cnt != PIC_PKT_LEN) break;
}
cmd[4] = 0xf0;
cmd[5] = 0xf0;
sendCmd(cmd, 6);
}
myFile.close();
}
void sendData(){
File photoFile = SD.open("pic.jpg");
if (photoFile) {
while (photoFile.position() < photoFile.size()) {
Serial.write(photoFile.read());
}
}else{
Serial.println("open photoFile failed");
}
photoFile.close();
}
processing
import processing.serial.*;
Serial myPort;
OutputStream output;
int flag = 0;
int count = -1;
String inString = "0";
int pic_number;
PImage img;
void setup() {
size(800, 600);
//println( Serial.list() );
myPort = new Serial( this, Serial.list()[2], 115200);
myPort.clear();
}
void draw() {
while ( myPort.available () > 0 ) {
if (flag == 0) {
inString = myPort.readStringUntil('\n');
inString = trim(inString);
pic_number = int(inString);
println("pic_number: "+pic_number);
flag = 1;
}else {
try {
output.write(myPort.read());
}
catch (IOException e) {
e.printStackTrace();
}
count++;
if (count == pic_number) {
try {
output.flush(); // Writes the remaining data to the file //<>//
output.close(); // Finishes the file
}
catch (IOException e) {
e.printStackTrace();
}
img = loadImage("pic.jpg");
image(img, 0, 0);
break;
}
}
}
}
void keyPressed() {
if(key == 'a'){
output = createOutput("pic.jpg");
myPort.write('2');
flag = 0;
count = 0;
println("taking a photo");
}
}
Tips:
這個函數(shù)很吊昧碉,trim()可以把兩邊的特殊符號去掉
用arduino自帶的串口調(diào)試軟件發(fā)送東西的時候相當于serial.println();所以會在內(nèi)容后面帶上\t\n所以用serial.read的話是不能完全讀完的英染,像這樣
while(Serial.available() > 0){
int temp = Serial.readString();
}
會得到奇怪的東西揽惹,這樣就可以了被饿。。搪搏。
while(Serial.available() > 0){
String temp = Serial.readString();
}
一個神奇的函數(shù)
可以節(jié)省很多代碼狭握,來源是arduino樣例代碼里面的SerialCallResponse
split()
processing讀取大量數(shù)據(jù)
最近遇到一個問題,就是processing和arduino通訊傳輸大量數(shù)據(jù)然后發(fā)現(xiàn)有點問題疯溺。论颅。我發(fā)現(xiàn)可能processing3.0對串口一些變化?因為這段代碼我以前是可以工作的
temp = myPort.readChar();
while( temp == 0xffff)
temp = myPort.readChar();
但是現(xiàn)在我一定要在while里面有個delay(1);才能工作囱嫩。而且時間很長恃疯,要用幾百ms才能查詢到數(shù)據(jù)。墨闲。今妄。
目前還不知道為什么。。