I'm trying to read data from a photocell resistor and my Arduino Diecimila and then graph it in real-time with Processing.
It should be painfully simple; but it’s growing into a little bit of a nightmare for me.
The code I'm running on my Arduino:
int photoPin;
void setup(){
photoPin = 0;
Serial.begin(9600);
}
void loop(){
int val = int(map(analogRead(photoPin), 0, 1023, 0, 254));
Serial.println(val); // Sending data over Serial
}
The code I'm running in Processing:
import processing.serial.*;
Serial photocell;
int[] yvals;
void setup(){
size(300, 150);
photocell = new Serial(this, Serial.list()[0], 9600);
photocell.bufferUntil(10);
yvals = new int[width];
}
void draw(){
background(0);
for( int i = 1; i < width; i++ ){
yvals[i - 1] = yvals[i];
}
if(photocell.available() > 0){
yvals[width - 1] = photocell.read();
}
for(int i = 1; i < width; i++){
stroke(#ff0000);
line(i, yvals[i], i, height);
}
println(photocell.read()); // For debugging
}
I've tested both bits of code separately, and I know that they work. It's only when I try to have the input from the Arduino going to Processing that the problems start.
When I view the data in Arduino's "Serial Monitor", I get a nice constant flow of data that seems to look valid.
But when I read that same data through Processing, I get a repeating pattern of random values.
After a closer look at the resources at hand, I realized that the problem had already been solved for me by the folks over at http://arduino.cc
http://arduino.cc/en/Tutorial/Graph
Oh how much time I could have saved if I had seen that earlier.
You could transmit that data with the Plotly Arduino API, which along with the documentation and setup is available here. Basic idea: you can continuously stream data from your Arduino, or transmit a single chunk.
Then, if you want to embed it into a site, you'll want to grab the URL and use this snippet:
<iframe id="igraph"
src="https://plot.ly/~abhishek.mitra.963/1/400/250/"
width="400"
height="250"
seamless="seamless"
scrolling="no"></iframe>
You can change the width/height dimensions in that snippet. Note: you need to swap in your own URL there to get it stream through.
Here's an example of how it looks to stream Arduino data
Full disclosure: I work for Plotly.
Related
I am new to Arduino programming and was trying to make an IR-controlled WS2812 led strip light, everything works fine apart from when I try to stop the for-loop when my IR receiver gets a new decoded value. It does get the job done but the received values are different every time. when I tested the same controller with a simple IR receiver program everything worked fine.
switch(value){
case 16720095:
delay (200);
irrecv.resume();
for (int i = 0; i <= 182; i++) {
leds[i] = CRGB (0,0,0);
FastLED.show();
if (irrecv.decode(&results))
{
value = results.value;
Serial.println(value);
break;
}
delay(40);
}
}
}
and the serial outputs:
first time:
16720095
-1572362453
second time:
16720095
-1406992986
third time:
16720095
811035822
It looks like you need to call "irrecv.resume()" within the if (irrecv.decode(&results)) block in order to tell the driver to keep looking for signals. The second values you are getting are garbage because you are asking it to provide data it hasn't received/ prepared.
I am having the same problem as described in this post on the Arduino forums. I have a slight deviation in that I am using an Arduino Leonardo, but otherwise the core problem is the same.
Trying to upload a sketch to my board results in Windows stating my 'USB device has malfunctioned and Windows does not recognize it'. The COM port used for the board then disappears, as with the post above.
I tried the solution posted by Louis Davis in the linked post, which allowed me to successfully reset the board and upload a known good sketch. When this is completed, the board is able to be recognised by Windows again, and the COM port reappears; the board can be used without issue.
I have two Leonardos and I have confirmed by replicating steps across both that it is my specific code which is causing the Windows error to appear, not down to a hardware issue.
Could anyone offer pointers on what in the below code is causing this? (Code is fully commented to describe purpose/methods used)
//Code including basic setup/loop and a function I created, asking for readings to be taken from 3 sensors
//when called, and to then assign the results to global variables
//The loop function should then print the global variables in question and wait for a while before repeating
//the process
#include <Wire.h> //using an I2C breakout (accelerometer)
#include "SparkFun_MMA8452Q.h" //accelerometer breakout's library
MMA8452Q accel; //create an instance of this accelerometer
int FSR_pin = A1; //force resistor pin
const int PHOTO_pin = A0; //phototransistor pin
//declare variables to use to take a base reading, to later measure against for changes
int base_PHOTO = 0;
int base_FSR = 0;
byte base_ORIEN = 0; //using the method recommended in the accelerometer's startup page to get orientation
//readings, which they say is passed back as a byte; section 'Reading Portrait/Landscape'
//on this page https://learn.sparkfun.com/tutorials/mma8452q-accelerometer-breakout-hookup-guide
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
Wire.begin();
}
void baseReading() {
base_FSR = analogRead(FSR_pin);
base_PHOTO = analogRead(PHOTO_pin);
base_ORIEN = accel.readPL();
}
void loop() {
// put your main code here, to run repeatedly:
baseReading(); //call my own function to get base readings
Serial.println(base_FSR);
Serial.println(base_PHOTO);
Serial.println(base_ORIEN);
delay(5000);
}
int takeReading() {
}
I have taken readings from each sensor individually using test sketches from the component manufacturers; the problem only appeared when I tried to combine them into one bit of code. Here's a hyperlink to the accelerometer breakout guide referenced in the above code.
Solved: The code was missing the line accel.init(); from the setup function.
I first ruled out the FSR & phototransistor I was using, as running code for only these components performed as expected. That left the MMA8452Q's code to look at.
I'd been using the manufacturer's guide as linked above for the accelerometer, and Example #3 (orientation reading) from its library to write my code out; I managed to drop the init and assumed the problem was with the new .readPL method I had put in.
The example code uses .begin instead of .init, and also uses this as part of a print statement, so I didn't immediately catch on that the purpose of its inclusion was the same.
The fixed code is as follows:
//Code including basic setup/loop and a function I created, asking for readings to be taken from 3 sensors when called and assigned to global variables
//The loop function should then print the global variables in question and wait for a while before repeating the process
#include <Wire.h>
#include "SparkFun_MMA8452Q.h"
MMA8452Q accel;
int FSR_pin = A1;
const int PHOTO_pin = A0;
//variables to use to take a base reading, to later measure against for changes
int base_PHOTO = 0;
int base_FSR = 0;
byte base_ORIEN = 0;
void setup() {
Serial.begin(9600);
Wire.begin();
accel.init(); //The new line, which allows this to run as intended
}
void baseReading() {
base_FSR = analogRead(FSR_pin);
base_PHOTO = analogRead(PHOTO_pin);
base_ORIEN = accel.readPL();
}
void loop() {
baseReading();
Serial.println(base_FSR);
Serial.println(base_PHOTO);
Serial.println(base_ORIEN);
delay(5000);
}
I am trying to build a simple FLASH memory programmer (for 39SF020A) using my arduino mega. I wrote the C code and Python script to send the data over (And it all works as expected).
I need to transfer about 32k of hexadecimal data, but with my settings only 10k of data took about 4 minutes (115200 BAUD), which i found unnecessary long. Currently, i am sending over serial (from Python) my value with a terminator (i chose '$'), so for exmple '3F$'. adresses are calulated on the arduino, so no need to send them.
In my arduino code, i have
String received_string = Serial.readStringUntil('$');
and after programming every byte to teh FLASH using arduino, it sends back a '\n' to let the Python know, that it is ready to receive next byte (the python is waiting for receiving a 'line' and then continues). I am not really sure if this is a way to do it, if sending only one byte at the time is good idea and if not, how many and how do i parse them on the arduino? Is the feedback loop useful?
Thanks.
Python Code:
('file' contains all data)
for item in file[1:]:
ser.write((item + "$").encode("ascii"))
line = ser.readline()
i += 1
if i >= top:
break
elif (i % 100) == 0:
print(i)
Arduino code (just part of it)
if (Serial.available() > 0){
String received_string = Serial.readStringUntil('$');
programData(received_string.toInt(),program_adress);
program_adress++;
}
void programData(char data_in, unsigned long adress)
{
digitalWrite(OE,HIGH);
digitalWrite(CE,LOW);
writeByte(0xAA, 0x5555);
writeByte(0x55, 0x2AAA);
writeByte(0xA0, 0x5555);
writeByte(data_in, adress);
Serial.print("\n"); // Feedback for Python
delayMicroseconds(30); // Just to be on the safe side
}
void writeByte(char data_in, unsigned long adress)
{
setDataAs(OUTPUT);
digitalWrite(OE,HIGH);
digitalWrite(WE,HIGH);
setAdress(adress);
setData(data_in);
digitalWrite(WE,LOW);
delayMicroseconds(1);
digitalWrite(WE,HIGH);
}
// Sets data BUS to input or output
void setDataAs(char dir){
for (unsigned int i = 0; i < data_size ;i++) pinMode(data[i],dir);
}
// Sets data to specific values
void setData(char data_i){
setDataAs(OUTPUT);
for (int i = 0; i < data_size;i++) { digitalWrite(data[i],bitRead(data_i,i)); }
}
void setAdress(long adr){
// Set all adresses
for (int i = 0; i < adresses_size;i++)
digitalWrite(adresses[i],bitRead(adr,i));
}
I have been trying to store data (real time, gas sensor data) into a .txt file so as to make graphs.
This is my arduino code:
const int gasPin = A0; //Gas sensor output pin to Arduino analog A0 pin
void setup()
{
Serial.begin(9600); //Initialize serial port - 9600 bps
}
void loop()
{
Serial.println(analogRead(gasPin));
delay(1000); // Print value every 1 sec.
}
And this is my Processing code:
import processing.serial.*;
Serial mySerial;
PrintWriter output;
void setup() {
mySerial = new Serial(this, "COM3", 9600);
output = createWriter( "data.txt" );
}
void draw() {
if (mySerial.available() > 0 ) {
String value = mySerial.readString();
if ( value != null ) {
output.println( value );
}
}
}
void keyPressed() {
output.flush();
output.close();
exit();
}
This doesn't work. I always get an empty data.txt file.
You should get into the habit of breaking your problem down into smaller steps and then taking those steps on one at a time.
For example, can you create a simple example sketch that stores a value in a file? Don't worry about Arduino yet. Just store a single value in a file.
Then make it so you store a bunch of values in the file. Maybe the value returned from millis(), or the mouse position. Again, don't worry about Arduino yet. Get this working perfectly before moving on.
Separately from that, can you make an Arduino program that sends values to a Processing sketch that simply prints those values to the console?
When you have those working separately, then you can combine them into a single program.
Right now, there's no way to know which part of your code is failing: is it the Arduino code? Is it the file storage? So you need to isolate those pieces so we (you) can test them by themselves.
If you still can't figure it out, then post a MCVE of just a single step in a new question post, and we'll go from there. Good luck.
I am using Olimex EKG Shield with Arduino Uno.
void setup() {
// put your setup code here, to run once:
// initialize serial communication at 9600 bits per second:
Serial.begin(115200);
}
void loop() {
// put your main code here, to run repeatedly:
// read the input on analog pin 0:
int sensorValue = analogRead(A0);
// Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V):
float value = sensorValue * (5.0 / 1023.0);
// print out the value you read:
Serial.println(value);
}
With this code provided here, I am getting a voltage value from 0-5V.
Since its a loop, the data keep shows in the serial monitor until it is disconnected.
So, what I am trying to do is that measure ECG for a certain amount of time (let's say 5 min) or data points (let's say a million points), and then save this data into a .txt file.
//From Arduino to Processing to Txt or cvs etc.
//import
import processing.serial.*;
//declare
PrintWriter output;
Serial udSerial;
void setup() {
udSerial = new Serial(this, Serial.list()[0], 115200);
output = createWriter ("data.txt");
}
void draw() {
if (udSerial.available() > 0) {
String SenVal = udSerial.readString();
if (SenVal != null) {
output.println(SenVal);
}
}
}
void keyPressed(){
output.flush();
output.close();
exit();
}
I found this processing code that imports data from Arduino serial monitor and saves as a .txt file, but it doesn's work somehow.
I think I need to make some change to the code on Arduino side and also on Processing side.
If anyone can help with me, I would really appreciate.
Thank you.
You need to be more specific than saying "it doesn't work somehow" - we have no idea what that means. What exactly did you expect this code to do? What exactly does it do instead?
You also need to split this up into smaller problems.
Can you create a simple example program that simply sends the values to Processing? Just print them to the console for now.
Can you create a separate example program that stores values in a text file? Just use hard-coded values or random values for now- don't worry about the arduino yet.
When you have both of those working perfectly, then you can think about combining them into one program that does both: sends values from the arduino and saves those values to a text file.
You can't just "find code" and expect it to work. You have to break your problem down and then approach each individual step by itself. Then if you get stuck on a specific step, you can post a MCVE and we can go from there. Good luck.