I want to do the simplest thing to plot a graph from the serial port of Arduino with the Processing software. I use Eclipse.
I did as the tutorials say about the plugins. I also copied the code from the Arduino site which is this:
import processing.serial.*;
Serial myPort; // The serial port
int xPos = 1; // Horizontal position of the graph
void setup () {
// Set the window size:
size(400, 300);
// List all the available serial ports
println(Serial.list());
// I know that the first port in the serial list on my mac
// is always my Arduino, so I open Serial.list()[0].
// Open whatever port is the one you're using.
myPort = new Serial(this, Serial.list()[0], 9600);
// Don't generate a serialEvent() unless you get a newline character:
myPort.bufferUntil('\n');
// Set the initial background:
background(0);
}
void draw () {
// Everything happens in the serialEvent()
}
void serialEvent (Serial myPort) {
// Get the ASCII string:
String inString = myPort.readStringUntil('\n');
if (inString != null) {
// Trim off any whitespace:
inString = trim(inString);
// Convert to an int and map to the screen height:
float inByte = float(inString);
inByte = map(inByte, 0, 1023, 0, height);
// Draw the line:
stroke(127, 34, 255);
line(xPos, height, xPos, height - inByte);
// At the edge of the screen, go back to the beginning:
if (xPos >= width) {
xPos = 0;
background(0);
}
else {
// Increment the horizontal position:
xPos++;
}
}
}
There is a problem that the bufferUntil('\n') does not trigger the serialevent.
I know that there was a bug. In case you try to set an 8-bit int to a 32-bit int, it goes to hell.
The Processing IDE works great though. Eclipse does not trigger at all. Is there a solution?
Note that bufferUntil('\n') takes an integer value. You're giving it a char. At the very least try bufferUntil(10) just to see if there's some oddness going on there, but it might be worth simply printing the values see coming in on myPort and see what comes by when you send a newline.
Related
I downloaded the latest version of VS Code with PlatformIO, i also downloaded the library Mouse.h from PlatformIO Library Manager, and even so, after i upload the code to my Micro Pro the mouse does not respond to the joystick!
But the same code works when i upload via Arduino IDE!
I compared the Mouse.h from .platformio/lib with the Mouse.h from program files\Arduino\libraries
I compared the Mouse.cpp from .platformio/lib with the Mouse.cpp from program files\Arduino\libraries
And they have exactly the same code!
This is my code for my MICRO PRO 32u4 5v:
/* HID Joystick Mouse Example
by: Jim Lindblom
date: 1/12/2012
license: MIT License - Feel free to use this code for any purpose.
No restrictions. Just keep this license if you go on to use this
code in your future endeavors! Reuse and share.
This is very simplistic code that allows you to turn the
SparkFun Thumb Joystick (http://www.sparkfun.com/products/9032)
into an HID Mouse. The select button on the joystick is set up
as the mouse left click.
*/
#include <Arduino.h>
#include <Mouse.h>
int horzPin = A0; // Analog output of horizontal joystick pin
int vertPin = A1; // Analog output of vertical joystick pin
int selPin = 9; // select button pin of joystick
int vertZero, horzZero; // Stores the initial value of each axis, usually around 512
int vertValue, horzValue; // Stores current analog output of each axis
const int sensitivity = 200; // Higher sensitivity value = slower mouse, should be <= about 500
int mouseClickFlag = 0;
void setup()
{
pinMode(horzPin, INPUT); // Set both analog pins as inputs
pinMode(vertPin, INPUT);
pinMode(selPin, INPUT); // set button select pin as input
digitalWrite(selPin, HIGH); // Pull button select pin high
delay(1000); // short delay to let outputs settle
vertZero = analogRead(vertPin); // get the initial values
horzZero = analogRead(horzPin); // Joystick should be in neutral position when reading these
}
void loop()
{
vertValue = analogRead(vertPin) - vertZero; // read vertical offset
horzValue = analogRead(horzPin) - horzZero; // read horizontal offset
//delay(3000);
if (vertValue != 0)
Mouse.move(0, vertValue/sensitivity, 0); // move mouse on y axis
if (horzValue != 0)
Mouse.move((horzValue/sensitivity) *-1, 0, 0); // move mouse on x axis
if ((digitalRead(selPin) == 0) && (!mouseClickFlag)) // if the joystick button is pressed
{
mouseClickFlag = 1;
Mouse.press(MOUSE_LEFT); // click the left button down
}
else if ((digitalRead(selPin))&&(mouseClickFlag)) // if the joystick button is not pressed
{
mouseClickFlag = 0;
Mouse.release(MOUSE_LEFT); // release the left button
}
}
Did you restart VS Code after installing the lib?
For me it fix this kind of problems in some cases.
Edit: Did you "rebuild IntelliSense Index" by press "Ctrl + shift + p"?
Is there a callback function for p5.js’ createCapture function fails? (i.e. when user permission is denied or video camera stream is unsupported by user browser).
I notice in the src there is a success callback, but can’t seem to find one for failure.
In the browser console, p5 also reports ‘DOMException: Permission denied’, however, I would like to handle this in a more user-friendly fashion.
If there is no callback, what is the best practice for handling media failure with createCapture as it doesn’t seem to be discussed in the docs.
Ok so this answer is more than a year late but posting this as it may be useful for others stuck on the same issue. Rather than error testing the capture itself as suggested in comments below or perhaps reworking createCapture() (best done through opening an issue request if you feel it should be changed) I suggest testing the pixels array of the capture and only if it has been set then proceeding with doing whatever your script does. This could be done simply like so:
//load pixel data of webcam capture
cap.loadPixels();
//all values in the pixel array start as zero so just test if they are
//greater than zero
if (cap.pixels[1] > 0)
{
//put the rest of your script here
}
A full example of this in action is below:
var canvas;
var cap;
var xpos = 0;
function setup()
{
canvas = createCanvas(windowWidth, windowHeight);
canvas.style("display", "block");
background("#666666");
//create an instance of the webcam
cap = createCapture(VIDEO);
cap.size(640, 480);
cap.hide();
}
function draw()
{
//load pixel data of webcam capture
cap.loadPixels();
//if the first pixel's R value is set continue with the rest of the script
if (cap.pixels[1] > 0)
{
var w = cap.width;
var h = cap.height;
copy(cap, w/2, 0, 10, h, xpos, (height / 2) - (h / 2), 10, h);
xpos = xpos + 1;
if (xpos > width) xpos = 0;
}
}
I believe you can use a try and catch to detect when you get an error. Something like this:
try{
capture = createCapture(VIDEO);
}
catch(error){
// error handling here
}
More info on W3Schools and MDN.
My setup method looks like below, I want to read one location file(City names with x and y co-ordinates) and then I am creating one hash-map of all cities so that I can draw(Will make points) them all on canvas
public void setup(){
background(0);
PFont title = createFont("Georgia", 16);
textFont(title);
text("This is a visualization of A* algorithm", 240, 20);
stroke(255);
line(0,25,800,25);
selectInput("Select a file for Locations:", "locFileSelected");
}
locFileSelected method(locFilePath is a global variable used):
public void locFileSelected(File locFile) {
locFilePath = locFile.toString();
this.readLocFileAndDraw();
}
Now control is transferred to readLocFileAndDraw (Each line in file has space separated 3 words, 1st is city name followed by x and y co-ordinates:
private void readLocFileAndDraw() {
try (Stream<String> lines = Files.lines(Paths.get(locFilePath))) {
for (String line : (Iterable<String>) lines::iterator){
// Last line in file is END, skip it
if(!line.equalsIgnoreCase("END")) {
List<Double> list = new ArrayList<Double>();
String[] arr= line.split(" ");
// adding coordinates into the list
list.add(Double.valueOf(arr[1]));
list.add(Double.valueOf(arr[2]));
// adding the list into the map with key as city name
locationsMap.put(arr[0], list);
}
}
} catch (IOException e) {
e.printStackTrace();
System.exit(0);
}
// Draw cities on map
// Draw graph of all cities
int w=1, h=1;
Set<Entry<String, List<Double>>> locationKeyEntries = locationsMap.entrySet();
for(Entry<String, List<Double>> currEntry: locationKeyEntries) {
String currCity = currEntry.getKey();
List<Double> currLocationList = currEntry.getValue();
int x = currLocationList.get(0).intValue();
int y = currLocationList.get(1).intValue();
stroke(255);
ellipse(x, y, w, h);
if(x>755)
x = x-(8*currCity.length());
if(y>755)
y=y-(8*currCity.length());
text(currCity, x,y);
}
return;
}
I tried to debug it, control is going to ellipse method but nothing is getting drew. Any idea? As far as I understand, I am missing passing reference of PApplet but I don't know how to do it...
Like you've mentioned, you really need to debug your program. Verifying that you're calling the ellipse() function is a great first step, but now you should be asking yourself more questions:
What is the value of x, y, w, and h being passed into the ellipse() function?
What is the value of currEntry in the for loop? What is the value of line when you're reading it in?
What are the fill, stroke, and background colors when you're drawing?
Note that I'm not asking you to tell me the answer to these questions. I'm pointing out these questions because they're what you should be asking yourself when you debug your program.
If you still can't figure it out, I really recommend breaking your problem down into smaller pieces and approaching each of those steps one at a time. For example, can you just show a single circle at a hard-coded point? Then work your way up from there. Can you read a single point in from a file and draw that to the screen? Then read two points. Work your way forward in small incremental steps, and post a MCVE if you get stuck. Good luck.
I have this kind of problem: I want to show the message "Hello!" near the centre of the Allegro screen before the game starts. Don't know why there is always only full window white colour after I compile the program not message "Hello!". I don't know why it doesn't show message "Hello!" . But if I erase the code between comment lines //***** program show the message "Hello!" well. Can someone can tell me how to solve this problem?
#include<allegro5\allegro5.h>
#include<allegro5\allegro_native_dialog.h>
#include<allegro5\allegro_font.h>
#include<allegro5\allegro_ttf.h>
#include<allegro5\allegro_primitives.h>
#include<iostream>
using namespace std;
int main(){
int ScreenWidth = 800, ScreenHeight = 600;
if (!al_init())
{
al_show_native_message_box(NULL, NULL, NULL, "Could not initialize Allegro 5", NULL, NULL);
return -1;
}
al_set_new_display_flags(ALLEGRO_WINDOWED);
ALLEGRO_DISPLAY *display = al_create_display(ScreenWidth, ScreenHeight);//creating window with dimensions: 800:600 px
al_set_window_position(display, 200, 100);//place from left top positioning the frame of display
al_set_window_title(display, "Try to catch me!");
if (!display)//show this message if sth wrong with display
{
al_show_native_message_box(display, "Sample Title", "Display Settings", "Display window was not created succesfully", NULL, ALLEGRO_MESSAGEBOX_ERROR);
return -1;
}
al_init_font_addon();//initialization font addon
al_init_ttf_addon();//initialization ttf(true type font) addon
//INTRO
ALLEGRO_FONT *fontOrbionBlack36 = al_load_font("fonts/Orbitron Black.ttf", 36, NULL);
al_draw_text(fontOrbionBlack36, al_map_rgb(44, 117, 255), ScreenWidth / 2, ScreenHeight / 2, ALLEGRO_ALIGN_CENTRE, "Hello!" );
al_rest(5.0);
//********************************************************************************
al_init_primitives_addon();
al_install_keyboard();
ALLEGRO_COLOR electricBlue = al_map_rgb(44, 117, 255);
ALLEGRO_EVENT_QUEUE *event_queue = al_create_event_queue();
al_register_event_source(event_queue, al_get_keyboard_event_source());
bool done = false;
int x = 10, y = 10;
int moveSpeed = 5;
while (!done)
{
ALLEGRO_EVENT events;
al_wait_for_event(event_queue, &events);
if (events.type = ALLEGRO_EVENT_KEY_DOWN)
{
switch (events.keyboard.keycode)
{
case ALLEGRO_KEY_DOWN:
y += moveSpeed;
break;
case ALLEGRO_KEY_UP:
y -= moveSpeed;
break;
case ALLEGRO_KEY_ESCAPE:
done = true;
break;
}
}
al_draw_rectangle(x, y, x + 20, y + 20, electricBlue, 2.0);
al_flip_display();
al_clear_to_color(al_map_rgb(0, 0, 0));
}
//*****************************************************************************************
al_flip_display();
al_rest(10.0);//rest is very simmilar to Sleep() it is waitg function, waiting 3s then close the allegro display
//al_destroy_font(fontOrbionBlack18);
al_destroy_font(fontOrbionBlack36);
al_destroy_display(display);//destroy the display at the end of the programm
return 0;
}
There are a few problems here that are preventing you from seeing the text.
You've set up a 'wait-for-event then draw' loop that is normally associated with the use of a timer, but you have no timer. This means that unless you trigger some sort of event (e.g. by pressing a keyboard key), al_wait_for_event will stall indefinitely and your program will never reach the call to al_flip_display. You can read more about timers here, but for the time being just know you will have to press a keyboard key to get this program to progress.
The ordering of your clear/draw/flip calls is a bit confusing.
Try something like this within your main loop:
al_clear_to_color(al_map_rgb(0, 0, 0));`
al_draw_rectangle(x, y, x + 20, y + 20, electricBlue, 2.0);
al_draw_text(fontOrbionBlack36, al_map_rgb(44, 117, 255), ScreenWidth / 2, ScreenHeight / 2, ALLEGRO_ALIGN_CENTRE, "Hello!" );
al_flip_display();
In other words, clear first, then draw, then flip. Currently you only draw the text once (before your main loop). This means that clearing the screen will clear the text -- you need to draw the text every frame after clearing the screen but before flipping the display.
If you change those two things, you should be able to see the text after pressing a keyboard button. However, there are a few other changes that might help:
I'd remove those calls to al_rest unless they serve a useful purpose. Currently they just make you wait 5 seconds before you start your main loop (meaning you won't be able to see the text immediately even if you do press a key).
There's no reason to flip the display after your main loop exits, although I guess this was left over from your earlier experiments with showing text.
When checking the event type, use events.type == ALLEGRO_EVENT_KEY_DOWN instead of events.type = ALLEGRO_EVENT_KEY_DOWN. Currently, you're actually assigning the value ALLEGRO_EVENT_KEY_DOWN to events.type, overwriting whatever its original value was. Your compiler may (and probably should) have warned you about this.
Currently I am trying to get a sketch working where the Arduino will read a series of characters as a command, and do something based on the series of characters sent from an iDevice. I am using an iPhone 3GS that is jailbroken to send characters to the Arduino. The method that sends the serial characters looks like the following,
- (IBAction)blinkFlow_A_LED:(id)sender {
// Method to blink the Flow_A LED on the kegboard-mini Arduino shield (<https://github.com/Kegbot/kegboard>).
NSLog(#"blink Flow_A btn pressed");
// Open serial port / interface
[serial open:B2400];
NSLog(#"%c", [serial isOpened]);
// Send serial data (TX)
char buffer [7];
buffer[0] = '{';
buffer[1] = 'b';
buffer[2] = 'l';
buffer[3] = 'i';
buffer[4] = 'n';
buffer[5] = 'k';
buffer[6] = '}';
[serial write:buffer length:7];
}
I have created a simple sketch that blinks the LED on the shield I am using, but I want the LED to blink conditionally when the button is clicked in the iOS app. The sketch that blinks the LED looks like the following,
/*
Blink
Turns on an LED on for one second, then off for one second, repeatedly.
This sketch is specific to making the kegboard-mini shield.
http://arduino.cc/forum/index.php?topic=157625.new;topicseen#new
This example code is in the public domain.
*/
// Pin D4 - should be connected to the flow_A LED
// Give it a name
int led = 4;
// The setup routine runs once when you press reset:
void setup() {
// Initialize the digital pin as an output.
pinMode(led, OUTPUT);
}
// The loop routine run over and over again forever:
void loop() {
digitalWrite(led, HIGH); // Turn the LED on (HIGH is the voltage level)
delay(1000); // Wait for one second
digitalWrite(led, LOW); // Turn the LED off by making the voltage LOW
delay(1000); // Wait for a second
}
That is a simple sketch!
You may want to begin with looking at the Arduino reference page: Serial
In setup(), you need at least Serial.begin(2400);.
Now, I'll suggest that reading and decoding the string "{blink}" seems like overkill. Let me suggest you send one character (for example 'b'), and detect one character, at least to start. Check out .available() and .read() on the Serial reference page. With these you can determine if a character has arrived at the Arduino and read in a single character.
You can then use these if you want to build a string of characters one at a time and compare it to String("{blink}"). This is a bit more complicated, especially if you take into account exceptions (like lost or damaged characters).
You can easily test your program using the Serial monitor tool -- just be advised that you have to hit "send" to make the characters go out.
I ended putting a simple sketch together like this which allows me to store an array of serial bytes into a String thanks to the SerialEvent example.
The sketch I am currently working with looks like the following,
/*
* kegboard-serial-simple-blink07
* This code is public domain
*
* This sketch sends a receives a multibyte String from the iPhone
* and performs functions on it.
*
* Examples:
* http://arduino.cc/en/Tutorial/SerialEvent
* http://arduino.cc/en/Serial/read
*/
// Global variables should be identified with "_"
// flow_A LED
int led = 4;
// relay_A
const int RELAY_A = A0;
// Variables from the sketch example
String inputString = ""; // A string to hold incoming data
boolean stringComplete = false; // Whether the string is complete
void setup() {
Serial.begin(2400); // Open a serial port. Sets data rate to 2400 bit/s
Serial.println("Power on test");
inputString.reserve(200);
pinMode(RELAY_A, OUTPUT);
}
void open_valve() {
digitalWrite(RELAY_A, HIGH); // Turn RELAY_A on
}
void close_valve() {
digitalWrite(RELAY_A, LOW); // Turn RELAY_A off
}
void flow_A_blink() {
digitalWrite(led, HIGH); // Turn the LED on (HIGH is the voltage level)
delay(1000); // Wait for one second
digitalWrite(led, LOW); // Turn the LED off by making the voltage LOW
delay(1000); // Wait for a second
}
void flow_A_blink_stop() {
digitalWrite(led, LOW);
}
void loop() {
// Print the string when newline arrives:
if (stringComplete) {
Serial.println(inputString);
// Clear the string:
inputString = "";
stringComplete = false;
}
if (inputString == "{blink_Flow_A}") {
flow_A_blink();
}
}
// SerialEvent occurs whenever a new data comes in the
// hardware serial RX. This routine is run between each
// time loop() runs, so using delay inside loop can delay
// response. Multiple bytes of data may be available.
void serialEvent() {
while(Serial.available()) {
// Get the new byte:
char inChar = (char)Serial.read();
// Add it to the inputString:
inputString += inChar;
// If the incoming character is a newline, set a flag
// so the main loop can do something about it:
if (inChar == '\n') {
stringComplete = true;
}
}
}