From 2928dc68a5768bb729b93c31c194cca283f12a5d Mon Sep 17 00:00:00 2001 From: Gipsonek Date: Sun, 1 Jan 2017 18:01:18 +0100 Subject: [PATCH] Add Processing app source codes --- processing/ardupodRemote/ardupodRemote.pde | 244 +++++++++++++++++++ processing/ardupodRemote/guiElements.pde | 268 +++++++++++++++++++++ 2 files changed, 512 insertions(+) create mode 100644 processing/ardupodRemote/ardupodRemote.pde create mode 100644 processing/ardupodRemote/guiElements.pde diff --git a/processing/ardupodRemote/ardupodRemote.pde b/processing/ardupodRemote/ardupodRemote.pde new file mode 100644 index 0000000..f98b427 --- /dev/null +++ b/processing/ardupodRemote/ardupodRemote.pde @@ -0,0 +1,244 @@ +import processing.serial.*; +import controlP5.*; + +ControlP5 cp5; + +Serial port; +String[] comList; +int portNum; +boolean selected = false, connected = false, firstScan = false; + +int[] scanResults = new int[180]; +boolean startScan = false; +int posScan = 0; +int posLine = 90; +int lastAngleSliderValue = 90; + +void setup() { + size(960, 480); + background(#888888); + frameRate(120); + comList = Serial.list(); + guiSetup(); +} + +public void serialInput(String s) { + output(11, 9, s); + if(s.equals("version") || s.equals("v")) { + output(11, 8, version); + } +} + +public void serialOutput(String s) { + //tab size fix + s = s.replaceAll("\t", " "); +} + +public void angleSlider(int angle) { + posLine = angle; +} + +public void portsList(int n) { + selected = true; + portNum = n; +} + +void mouseReleased() { + if(angleSlider.isMouseOver() && (lastAngleSliderValue != (int)angleSlider.getValue()) && !(startScan)) { + lastAngleSliderValue = (int)angleSlider.getValue(); + output(11, 10, "Turning sensor: " + (int)angleSlider.getValue() + "°"); + if(connected) { + port.write("t" + str((int)angleSlider.getValue())); + } + } +} + +long lastKey; +void keyPressed() { + switch(key) { + case 'w': + if(!inputField.isFocus()) { + moveW.setColorBackground(color(0x00, 0xAA, 0xFF)); + moveW.lock(); + if(millis()-lastKey >= 1000) { + lastKey = millis(); + output(11, 10, "Walk forward"); + if(connected){port.write("w");} + } + } + break; + case 'a': + if(!inputField.isFocus()) { + moveA.setColorBackground(color(0x00, 0xAA, 0xFF)); + moveA.lock(); + if(millis()-lastKey >= 1000) { + lastKey = millis(); + moveA.setOn(); + output(11, 10, "Turn left"); + if(connected){port.write("a");} + } + } + break; + case 's': + if(!inputField.isFocus()) { + moveS.setColorBackground(color(0x00, 0xAA, 0xFF)); + moveS.lock(); + if(millis()-lastKey >= 1000) { + lastKey = millis(); + moveS.setOn(); + output(11, 10, "Walk backward"); + if(connected){port.write("s");} + } + } + break; + case 'd': + if(!inputField.isFocus()) { + moveD.setColorBackground(color(0x00, 0xAA, 0xFF)); + moveD.lock(); + if(millis()-lastKey >= 1000) { + lastKey = millis(); + moveD.setOn(); + output(11, 10, "Turn right"); + if(connected){port.write("d");} + } + } + break; + } +} + +void keyReleased() { + switch(key) { + case 'w': + moveW.setColorBackground(color(0x00, 0x2D, 0x5A)); + moveW.unlock(); + break; + case 'a': + moveA.setColorBackground(color(0x00, 0x2D, 0x5A)); + moveA.unlock(); + break; + case 's': + moveS.setColorBackground(color(0x00, 0x2D, 0x5A)); + moveS.unlock(); + break; + case 'd': + moveD.setColorBackground(color(0x00, 0x2D, 0x5A)); + moveD.unlock(); + break; + } +} + +long lastMouse; +public void controlEvent(ControlEvent theEvent) { + switch(theEvent.getController().getName()) { + case "scanButton": + scanButton.setLabel("scanning..."); + if(connected){port.write("n");} + posScan = 0; + posLine = 0; + break; + case "measureButton": + if(connected){port.write("m");} + break; + case "connectButton": + if(selected) { + try { + if(!connected) { + port = new Serial(this, Serial.list()[portNum], 9600); + connected = true; + output(11, 8, "Connected to " + Serial.list()[portNum]); + } + } catch(Exception e) { + output(11, 6, "Unable to connect to " + Serial.list()[portNum]); + output(11, 6, e.toString()); + connected = false; + } + } else { + output(11, 6, "Select appropriate COM port"); + } + break; + case "disconnectButton": + if(connected) { + output(11, 8, "Disconnected from " + Serial.list()[portNum]); + port.stop(); + connected = false; + } + break; + case "W": + if(millis()-lastMouse >= 1000) { + lastMouse = millis(); + output(11, 10, "Step forward"); + if(connected){port.write("ws");} + } + break; + case "A": + if(millis()-lastMouse >= 1000) { + lastMouse = millis(); + output(11, 10, "Step left"); + if(connected){port.write("as");} + } + break; + case "S": + if(millis()-lastMouse >= 1000) { + lastMouse = millis(); + output(11, 10, "Step backward"); + if(connected){port.write("ss");} + } + break; + case "D": + if(millis()-lastMouse >= 1000) { + lastMouse = millis(); + output(11, 10, "Step right"); + if(connected){port.write("ds");} + } + break; + } +} + +void receiveData() { + String input = port.readStringUntil('\n'); + String payload; + int code1, code2; + if (input != null && input.charAt(0) != 0) { + code1 = (int)input.charAt(0)-48; + code2 = (int)input.charAt(1)-48; + payload = trim(input.substring(2)); + if((code1 == 4) && (code2 == 0)) { + if(payload.equals("s")) { + startScan = true; + scanButton.lock(); + angleSlider.lock(); + } else { + int distance = Integer.parseInt(trim(payload)); + if((distance < 200) && (distance > 0)) { + scanResults[posLine] = distance; + } else { + scanResults[posLine] = 200; + } + drawScan(posLine); + angleSlider.setValueLabel(str(posLine)); + posLine++; + if(posLine == 180) { + firstScan = true; + startScan = false; + scanButton.unlock(); + scanButton.setLabel("scan"); + angleSlider.unlock(); + } + } + } else if((code1 == 4) && (code2 == 1)) { + distanceArea.setText(payload + " cm"); + } else { + output(code1, code2, payload); + } + } +} + +void draw() { + background(#666666); + CP5AddOns(); + drawRefreshLine(posLine); + + if(connected) { + receiveData(); + } +} \ No newline at end of file diff --git a/processing/ardupodRemote/guiElements.pde b/processing/ardupodRemote/guiElements.pde new file mode 100644 index 0000000..6c5f8ca --- /dev/null +++ b/processing/ardupodRemote/guiElements.pde @@ -0,0 +1,268 @@ +Textarea outputArea, distanceArea; +Textlabel angle0Label, angle180Label, distanceLabel, m0Label, m1Label, m2Label, m3Label, m4Label; +Textfield inputField; +Button scanButton, measureButton, connectButton, disconnectButton, moveW, moveA, moveS, moveD; +Slider angleSlider; +ScrollableList portsList; +String version = "0.0.0-alpha-1"; + +public void guiSetup() { + cp5 = new ControlP5(this); + /*default ControlP5 colors + borders: 0074D9 + fill/inactive: 002D5A + active: 00AAFF*/ + + //serial output: 70-12=58 chars wide + outputArea = cp5.addTextarea("serialOutput") + .setPosition(20, 20) + .setSize(480, 440) + .setFont(createFont("consolas", 12)) + .setLineHeight(14) + .setColor(#FFFFFF) + .setColorBackground(#444444) + .setScrollBackground(#222222); + + //serial input + inputField = cp5.addTextfield("serialInput") + .setPosition(20, 440) + .setSize(480, 20) + .setAutoClear(true) + .setLabel("") + .setFocus(true); + + //distance output + distanceArea = cp5.addTextarea("distance") + .setPosition(585, 282) + .setSize(130, 16) + .setFont(createFont("consolas", 12)) + .hideScrollbar() + .setColor(#FFFFFF) + .setColorBackground(#444444) + .setScrollBackground(#222222) + .setText("0"); + + //labels + angle0Label = cp5.addTextlabel("angle0") + .setText("0") + .setPosition(505, 215) + .setColorValue(255); + + angle180Label = cp5.addTextlabel("angle180") + .setText("180") + .setPosition(920, 215) + .setColorValue(255); + + distanceLabel = cp5.addTextlabel("distanceLabel") + .setText(" DISTANCE") + .setPosition(525, 285) + .setColorValue(255); + + m0Label = cp5.addTextlabel("m0Label") + .setText("2 m") + .setPosition(510, 242) + .setColorValue(255); + + m1Label = cp5.addTextlabel("m1Label") + .setText("1 m") + .setPosition(610, 242) + .setColorValue(255); + + m2Label = cp5.addTextlabel("m2Label") + .setText("0 m") + .setPosition(710, 242) + .setColorValue(255); + + m3Label = cp5.addTextlabel("m3Label") + .setText("1 m") + .setPosition(810, 242) + .setColorValue(255); + + m4Label = cp5.addTextlabel("m4Label") + .setText("2 m") + .setPosition(910, 242) + .setColorValue(255); + + //scan + scanButton = cp5.addButton("scanButton") + .setPosition(825, 280) + .setSize(90, 20) + .setLabel("scan"); + + //sensor turning + angleSlider = cp5.addSlider("angleSlider") + .setPosition(525, 255) + .setSize(390, 10) + .setRange(0, 180) + .setLabel("") + .setSliderMode(Slider.FLEXIBLE) + .setNumberOfTickMarks(181) + .showTickMarks(false) + .snapToTickMarks(true) + .setValue(92); + angleSlider.getValueLabel().align(ControlP5.CENTER, ControlP5.TOP_OUTSIDE).setPaddingY(40); + + //measure distance + measureButton = cp5.addButton("measureButton") + .setPosition(725, 280) + .setSize(90, 20) + .setLabel("measure"); + + //COM port selection + portsList = cp5.addScrollableList("portsList") + .setPosition(525, 310) + .setSize(190, 100) + .setBarHeight(20) + .setItemHeight(20) + .setItems(comList) + .setLabel(" COM ports") + .close(); + + //COM port connect + connectButton = cp5.addButton("connectButton") + .setPosition(725, 310) + .setSize(90, 20) + .setLabel("connect"); + + //COM port disconnect + disconnectButton = cp5.addButton("disconnectButton") + .setPosition(825, 310) + .setSize(90, 20) + .setLabel("disconnect"); + + //movement buttons + moveW = cp5.addButton("W") + .setPosition(800, 350) + .setSize(40, 40); + moveW.getCaptionLabel().align(ControlP5.CENTER, ControlP5.CENTER); + + moveA = cp5.addButton("A") + .setPosition(750, 400) + .setSize(40, 40); + moveA.getCaptionLabel().align(ControlP5.CENTER, ControlP5.CENTER); + + moveS = cp5.addButton("S") + .setPosition(800, 400) + .setSize(40, 40); + moveS.getCaptionLabel().align(ControlP5.CENTER, ControlP5.CENTER); + + moveD = cp5.addButton("D") + .setPosition(850, 400) + .setSize(40, 40); + moveD.getCaptionLabel().align(ControlP5.CENTER, ControlP5.CENTER); +} + +/*void output(String s) { + outputArea.append(trim(s) + "\n"); +}*/ + +void output(int code1, int code2, String s) { + /*in packet structure: char# desc. + 0 code1 + 1 code2 + 2->n code-dependent payload + reserved codes: 40 continous scanning data + 41 single distance measurement + out packet structure: char# desc. + 0 command + 1 payload*/ + /*commands: t[deg] turn sensor to [deg] + m measure distance + n scan + w walk forward + a turn left + s walk backward + d turn right*/ + //codes 0 1 2 3 4 5 6 7 8 9 10 11 + String[] codes = {" ", "[ECHO] ", "[SETUP]", "[TRACE]", "[SR04] ", "[PWM] ", "[ERROR]", "[WARN] ", "[INFO] ", " > ", "[CMD] ", "[APP] "}; + + String[] splitted = split(s, ' '); + int i = 0; + int remaining = s.length(); + if(remaining < 58) { + outputArea.append(codes[code1] + " " + codes[code2] + " " + trim(s) + "\n"); + } else { + while(remaining > 58) { + String line; + if(i == 0) { + line = codes[code1] + " " + codes[code2]; + } else { + line = " "; + } + while(line.length() <= 58) { + line += " " + splitted[i++]; + } + outputArea.append(line + "\n"); + remaining -= line.length() - 15; + } + String end = s.substring(s.length()-remaining); + outputArea.append(" " + end + "\n"); + } +} + +void CP5AddOns() { + //auto-update available COM ports on every redraw + comList = Serial.list(); + cp5.get(ScrollableList.class, "portsList").setItems(comList); + + //ultrasonic scan + stroke(255); + + line(720, 230, 720-210, 230); + line(720, 230, 720-182, 230-105); + line(720, 230, 720-105, 230-182); + line(720, 230, 720, 20); + line(720, 230, 720+105, 230-182); + line(720, 230, 720+182, 230-105); + line(720, 230, 720+210, 230); + + int lineHeight = 2; + for (int i=-200; i<=200; i+=10) { + if(i % 100 == 0) { + lineHeight = 8; + } else if(i % 50 == 0) { + lineHeight = 4; + } else { + lineHeight = 2; + } + line(720+i, 230, 720+i, 230+lineHeight); + } + + fill(#002D5A); + stroke(#0074D9); + arc(720, 230, 400, 400, PI, TWO_PI, CHORD); + arc(720, 230, 300, 300, PI, TWO_PI, CHORD); + arc(720, 230, 200, 200, PI, TWO_PI, CHORD); + arc(720, 230, 100, 100, PI, TWO_PI, CHORD); + fill(#FFFFFF); + stroke(#FFFFFF); + arc(720, 230, 8, 8, PI, TWO_PI, CHORD); + + if(firstScan) { + drawScan(180); + } + + //distance output + fill(#444444); + noStroke(); + rect(583, 280, 132, 20); + + fill(#FFFFFF); + stroke(#000000); +} + +void drawScanLine(int distance, int angle) { + stroke(#0074D9); + line(720-distance*cos(angle*DEG_TO_RAD), 230-distance*sin(angle*DEG_TO_RAD), 720-199*cos(angle*DEG_TO_RAD), 230-199*sin(angle*DEG_TO_RAD)); +} + +void drawRefreshLine(int angle) { + stroke(#FFFFFF); + line(720, 230, 720-199*cos(angle*DEG_TO_RAD), 230-199*sin(angle*DEG_TO_RAD)); +} + +void drawScan(int i) { + for(int j=0; j