这里会显示出您选择的修订版和当前版本之间的差别。
— | learing:examples:serialcallresponseascii [2023/06/07 04:23] (当前版本) – 创建 - 外部编辑 127.0.0.1 | ||
---|---|---|---|
行 1: | 行 1: | ||
+ | ====== Serial Call and Response (handshaking) with ASCII-encoded output ====== | ||
+ | |||
+ | This example demonstrates string-based communication from the Arduino or Genuino board to the computer using a call-and-response (handshaking) method. | ||
+ | |||
+ | The sketch sends an ASCII string on startup and repeats that until it gets a serial response from the computer. Then it sends three sensor values as ASCII-encoded numbers, separated by commas and terminated by a linefeed and carriage return, and waits for another response from the computer. | ||
+ | |||
+ | You can use the Arduino Software (IDE) serial monitor to view the sent data, or it can be read by Processing (see code below), Flash, PD, Max/MSP (see example below), etc. The examples below split the incoming string on the commas and convert the string into numbers again. | ||
+ | |||
+ | Compare this to the Serial call and response example. They are similar, in that both use a handshaking method, but this one encodes the sensor readings as strings, while the other sends them as binary values. While sending as ASCII-encoded strings takes more bytes, it means you can easily send values larger than 255 for each sensor reading. It's also easier to read in a serial terminal program. | ||
+ | |||
+ | ===== Hardware Required ===== | ||
+ | |||
+ | |||
+ | Arduino or Genuino Board | ||
+ | 2 analog sensors (potentiometer, | ||
+ | pushbutton | ||
+ | 3 10K ohm resistors | ||
+ | hook-up wires | ||
+ | breadboard | ||
+ | ==== Software Required ==== | ||
+ | |||
+ | |||
+ | Processing or | ||
+ | Max/MSP version 5 | ||
+ | Circuit | ||
+ | |||
+ | Connect analog sensors to analog input pin 0 and 1 with 10K ohm resistors used as voltage dividers. Connect a pushbutton or switch to digital I/O pin 2 with a 10K ohm resistor as a reference to ground. | ||
+ | |||
+ | click the image to enlarge | ||
+ | |||
+ | |||
+ | image developed using Fritzing. For more circuit examples, see the Fritzing project page | ||
+ | |||
+ | Schematic | ||
+ | |||
+ | click the image to enlarge | ||
+ | |||
+ | |||
+ | === Code === | ||
+ | |||
+ | |||
+ | <code cpp>/* | ||
+ | Serial Call and Response in ASCII | ||
+ | | ||
+ | |||
+ | This program sends an ASCII A (byte of value 65) on startup | ||
+ | and repeats that until it gets some data in. | ||
+ | Then it waits for a byte in the serial port, and | ||
+ | sends three ASCII-encoded, | ||
+ | | ||
+ | | ||
+ | |||
+ | | ||
+ | |||
+ | The circuit: | ||
+ | * potentiometers attached to analog inputs 0 and 1 | ||
+ | * pushbutton attached to digital I/O 2 | ||
+ | |||
+ | |||
+ | |||
+ | | ||
+ | by Tom Igoe | ||
+ | | ||
+ | by Tom Igoe and Scott Fitzgerald | ||
+ | |||
+ | This example code is in the public domain. | ||
+ | |||
+ | | ||
+ | |||
+ | */ | ||
+ | |||
+ | int firstSensor = 0; // first analog sensor | ||
+ | int secondSensor = 0; // second analog sensor | ||
+ | int thirdSensor = 0; // digital sensor | ||
+ | int inByte = 0; // incoming serial byte | ||
+ | |||
+ | void setup() { | ||
+ | // start serial port at 9600 bps and wait for port to open: | ||
+ | Serial.begin(9600); | ||
+ | while (!Serial) { | ||
+ | ; // wait for serial port to connect. Needed for Leonardo only | ||
+ | } | ||
+ | |||
+ | |||
+ | pinMode(2, INPUT); | ||
+ | establishContact(); | ||
+ | } | ||
+ | |||
+ | void loop() { | ||
+ | // if we get a valid byte, read analog ins: | ||
+ | if (Serial.available() > 0) { | ||
+ | // get incoming byte: | ||
+ | inByte = Serial.read(); | ||
+ | // read first analog input: | ||
+ | firstSensor = analogRead(A0); | ||
+ | // read second analog input: | ||
+ | secondSensor = analogRead(A1); | ||
+ | // read switch, map it to 0 or 255L | ||
+ | thirdSensor = map(digitalRead(2), | ||
+ | // send sensor values: | ||
+ | Serial.print(firstSensor); | ||
+ | Serial.print("," | ||
+ | Serial.print(secondSensor); | ||
+ | Serial.print("," | ||
+ | Serial.println(thirdSensor); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | void establishContact() { | ||
+ | while (Serial.available() <= 0) { | ||
+ | Serial.println(" | ||
+ | delay(300); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | </ | ||
+ | |||
+ | Processing code to run with this example: | ||
+ | |||
+ | <code cpp>// This example code is in the public domain. | ||
+ | |||
+ | import processing.serial.*; | ||
+ | Serial myPort; | ||
+ | |||
+ | float bgcolor; | ||
+ | float fgcolor; | ||
+ | float xpos, ypos; // Starting position of the ball | ||
+ | |||
+ | void setup() { | ||
+ | size(640, | ||
+ | |||
+ | // List all the available serial ports | ||
+ | // if using Processing 2.1 or later, use Serial.printArray() | ||
+ | println(Serial.list()); | ||
+ | |||
+ | // I know that the first port in the serial list on my mac | ||
+ | // is always my Arduino module, so I open Serial.list()[0]. | ||
+ | // Change the 0 to the appropriate number of the serial port | ||
+ | // that your microcontroller is attached to. | ||
+ | myPort = new Serial(this, | ||
+ | |||
+ | // read bytes into a buffer until you get a linefeed (ASCII 10): | ||
+ | myPort.bufferUntil(' | ||
+ | |||
+ | // draw with smooth edges: | ||
+ | smooth(); | ||
+ | } | ||
+ | |||
+ | void draw() { | ||
+ | background(bgcolor); | ||
+ | fill(fgcolor); | ||
+ | // Draw the shape | ||
+ | ellipse(xpos, | ||
+ | } | ||
+ | |||
+ | // serialEvent | ||
+ | // whenever the buffer reaches the byte value set in the bufferUntil() | ||
+ | // method in the setup(): | ||
+ | |||
+ | void serialEvent(Serial myPort) { | ||
+ | // read the serial buffer: | ||
+ | String myString = myPort.readStringUntil(' | ||
+ | // if you got any bytes other than the linefeed: | ||
+ | myString = trim(myString); | ||
+ | |||
+ | // split the string at the commas | ||
+ | // and convert the sections into integers: | ||
+ | int sensors[] = int(split(myString, | ||
+ | |||
+ | // print out the values you got: | ||
+ | for (int sensorNum = 0; sensorNum < sensors.length; | ||
+ | print(" | ||
+ | } | ||
+ | // add a linefeed after all the sensor values are printed: | ||
+ | println(); | ||
+ | if (sensors.length > 1) { | ||
+ | xpos = map(sensors[0], | ||
+ | ypos = map(sensors[1], | ||
+ | fgcolor = sensors[2]; | ||
+ | } | ||
+ | // send a byte to ask for more data: | ||
+ | myPort.write(" | ||
+ | } | ||
+ | |||
+ | </ | ||
+ | |||
+ | |||
+ | Processing Code | ||
+ | |||
+ | Copy the Processing sketch from the code sample above. As you change the value of the analog sensor, you'll get a ball moving onscreen something like this. The ball will appear only when you push the button: |