Strange behaviour with Arduino Yún Bridge - arduino

Recently, I've been writing an Arduino(Yún) sketch to get RGB values(0-255) from the bridge. I have Bridge.begin() in the setup and the following in the loop:
Bridge.get("r", r, 4);
Bridge.get("g", g, 4);
Bridge.get("b", b, 4);
Which should get the value from the bridge(1st argument) and set the local variable to it(2nd argument). The local variables r, g and b are defined with char r[4];(obviously each with the appropriate name). I understand all of this, however there is a problem:
The first Bridge.get() call always returns \u0001(Start of heading). I have solved this by adding a dummy bridge get to the beginning of the loop, however this seems weird to me because the first call returns the "Start of heading" in every loop.
Why is this and is there a better way to fix it?
EDIT:
The code is put to the bridge by a python script running on the Linux side of the Yún. The following is shortened because the code that works out the RGB values is fairly long, messy and shouldn't be part of the problem(famous last words :D).
#!/usr/bin/python
from sys import path
path.insert(0, '/usr/lib/python2.7/bridge')
from bridgeclient import BridgeClient
link = BridgeClient()
link.put("r", str(int(r)))
link.put("g", str(int(g)))
link.put("b", str(int(b)))
The arduino code(once again abridged) is as follows:
#include <Process.h>
char r[4];
char g[4];
char b[4];
void setup() {
Bridge.begin();
}
void loop() {
Process colo;
colo.runShellCommand("/mnt/sda1/colours.py");
while (colo.running());
Bridge.get("r", r, 4); //this command(whatever key it’s getting) always returns \u0001
Bridge.get("r", r, 4);
Bridge.get("g", g, 4);
Bridge.get("b", b, 4);
}

Related

Cut out part of the data shown in serial monitor of Arduino

I'm new member here and also a joiner in programming
i try to extract information from my vehicle using OBD-II cable adapter. I try simple code to read the RPM and successfully got it and print it in serial monitor but i face a simple problem. Serial monitor display the PID-Code + current value of RPM as shown below:
010C849 where 010C: refer to RPM-PID used and 849: current value of RPM
so can i cutout the HEX number from the result and just display the value of RPM such as (849)
i used the following code:
Here is an example of the result `
#include <OBD2UART.h>
COBD obd;
void setup()
{
pinMode(13, OUTPUT);
obd.begin();
while (!obd.init());
}
void loop()
{
int value;
if (obd.readPID(PID_RPM, value)) {
Serial.println(value);
delay(1000);
}
}
`
You could use Regex, to cut out a pattern, but Arduino (and, in general, C++) does not provide support for regular expression parsing.
Once you have the string, you can use indexOf() and substring() to extract substrings. Once you have a substring, you can use toCharArray() to extract the character array, and atoi() to convert that to an integer.
Once you have integer values you can print them out.

Code upload results in 'USB device has malfunctioned' Windows error

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);
}

Make a "virtual port" which consists of multiple ports on Arduino

I started using ports on Arduino instead of setting every pin low or high by hand.
This is very useful and a lot faster. I am on a project, where i need at least one full port (8 bits) and at least one Serial Port.
I wanted to use the Arduino UNO but it has only one full port, port D.
PD0 and PD1 are used for Serial communication. This means i can't use port D.
I was wondering if there is a possibility for me to merge multiple ports into a "virtual port". In the end i want something like this:
PORTX = 0b11111111; // the first 2 bits are PB0/PB1 and bit 3-8 are PD3-PD8
Is this possible in any way???
I would say 'yes' it is possible, but maybe not in the way you want it (or maybe I just don't know how to do so^^)
First of all, the PORTS are macros from Atmel. Your Arduino-Uno is based on the AtMega328p and therefore uses the AVR-Toolchain with all those PORTS under the hood.
If you were about to program your microcontroller without the arduino-bootloader and all the fancy arduino-library-stuff, you would address all your GPIOs that way.
If you have a look into the code of the Atmel-AVR Toolchain (that arduino is sitting on top of), you would see, that the PORTS are defined in iom328p.h and are only addresses of internal IO-registers within the microcontroller.
So, just declaring a virtual-Port is not that easy (maybe with a kind of memory mapping with something similar to std::mmap() but I've never tried this one).
Anyway you are a programmer, so there is a solution to almost everthing ;)
I personally would suggest, to create your own Port-Class:
this class holds your required Pins as members and you have a setter, that overwrites your member-Pins according to the number you pass to it
(this code is not meant to be the 'perfect' solution, just a quick hint into the direction)
I would recommend you to stay with the arduino-library for this approach. If you do it with the plain PORTS, you might mess up something somewhere. So for example if you init your SerialPort and afterwards do something like PORTD |= (1<<PD0), you wont be able to receive any data and don't know why.
class MyPort
{
private:
uint8_t m_pin[8];
public:
MyPort(uint8_t pins[8])
{
for(int i=0; i<8; ++i)
{
m_pin[i] = pins[i]; //copy from constructor-argument into member-variable
pinMode(pins[i], OUTPUT); //setting pin as OUTPUT
}
}
void operator =(uint8_t val)
{
for(int i=0; i<8; ++i)
{
digitalWrite(m_pin[i], (val >> i)&1);
}
}
};
// B0,B1,D2,D3,D4,D5,D6,D7
// v v v v v v v v
uint8_t pins[]{8, 9, 2, 3, 4, 5, 6, 7};
MyPort PORTX(pins);
void setup()
{
PORTX = 0b11001100;
}
void loop()
{
// put your main code here, to run repeatedly:
}
please note that you will have to override the other operators as well, if you want bitwise addressing on your own port too

Saving endless loop EKG data as .txt file

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.

reading an array in a function

I am trying using the arduino IDE to write a sketch. I have data in progmem and want to move the data with a function to a memory address allocated using malloc. My code is below:
const uint8_t Data_6 [256] PROGMEM = { 0x11, 0x39......};
void setup() {
Serial.begin(57600);
oddBallData (Data_6, 0x00, 256);
}
void main() {
}
void oddBallData(const uint8_t *data, uint8_t mem, uint16_t bytes) {
uint8_t *buff1 = (uint8_t*)malloc(sizeof(bytes));
if (buff1 = 0) {
Serial.println(F("FATAL ERROR - NO MEMORY"));
}
else {
for (uint16_t x = 0; x < 6; x++ ) {
buff1[x] = data[x]; //edited from data[0] to [x] made a mistake in post
Serial.println(buff1[x],HEX);
}
}
buff1[0] = data[0];
Serial.println(buff1[0],HEX);
free(buff1);
}
I have some data saved in progmem and want to write that data to a second device using i2c protocol. I have multiple constant arrays of data saved to my progmem, with different sizes. So I have used malloc to reserve some memory from the heap, inside of the function.
I have not been able to write the data from the progmem so I have stripped things back to so that I am just trying to point to the progmem data using malloc and then print it.
This is where I found a the problem. If I print a single array entry from the data constant. It prints the correct value. If I use a loop I get mixed results, the loop works as long as the condition check value is below 3 or sometimes below 6!!!...?
If above this value the entire print is just garbage. Can anyone explain what I am seeing?
The culprit is probably
uint8_t *buff1 = (uint8_t*)malloc(sizeof(bytes));
sizeof(bytes) returns the size of the variable (which is probably 2 bytes) so you are just allocating 2 bytes of memory. You should use the value directly, eg:
uint8_t* buff1 = malloc(bytes);
Mind that the cast is not required in C since a void* is convertible to any other pointer type directly.
Again - AVR PROGMEM is not directly accessible from memory space, it needs different instruction than access into the RAM. If you are using it like this, you'll get RAM content on passed address, not the FLASH one. You have to use special functions for this. For example memcpy_P(ram_buff,flash_ptr); makes a copy from flash into the ram. Or you can read one byte by pgm_read_byte(flash_ptr + offset)
BTW: If you are using Data_6[0] and it's working, it's just because compiler sees it as a constant and constant can be replaced by its value compile time.
I Guess you just forgot to flush()
try to do Serial.flushI() after Serial.println(buff1[x],HEX);
you can also check flush documentation

Resources