Olimex EKG-EMG arduino shield (linux monitor) - arduino

Recently I have started using an EKG/EMG arduino's shield from Olimex: EKG/EMG Shield
The documentation have references for Electric Guru software only, but this software is closed source and it doesn't works in Linux.
I searched in internet but I have not success results.
My question is: is there another monitor software or any example for plot the captured signals by the electrodes?

not as I would know.
whowever, looking at the source code that is turning at the arduino microcontroller the protocol is fairly simple. I mean this one: https://www.olimex.com/Products/Duino/Shields/SHIELD-EKG-EMG/resources/ShieldEkgEmgDemo.zip
if i remember well, it sends out the packets: the rotating packet counter [count], and array of measurements [data] separated by 0xa5 0x5a bytes.
struct Olimexino328_packet
{
uint8_t sync0; // = 0xa5
uint8_t sync1; // = 0x5a
uint8_t version; // = 2 (packet version)
uint8_t count; // packet counter. Increases by 1 each packet.
uint16_t data[6]; // 10-bit sample (= 0 - 1023) in big endian (Motorola) format.
uint8_t switches; // State of PD5 to PD2, in bits 3 to 0.
};
some time ago, I have written a small python script for interfacing that (which is not finished yet), where you could do whatever you wish with the data - plotting, cool calculations and machine learning, etc. If you are interested, I could search for, and send you the source code... best after march 15.
however so far for some reason it starts receiving the data only after starting the Electric Guru once.
cheers

Maybe this helps you a bit, im also trying to build an open source component
http://bakerdh.wordpress.com/2013/01/31/a-first-look-at-the-olimex-eeg-smt/

I am working on a Python package to capture data from the Olimex EKG/EMG shield.
https://pypi.python.org/pypi
I am currently working towards a pre-alpha release.
Update:
I just pushed up an alpha version of the package I mentioned before to PyPI.
https://pypi.python.org/pypi/olimex-ekg-emg/0.1.0

I have a github repo that contains a Processing 3 visualizer that might be helpful. Processing 3 is very similar to the Arduino IDE.
https://github.com/fractalbass/ekg_field_monitor/tree/master/processing/ECG_Display
I also have a blog post that goes into some detail about what is going on in that sample program...
https://pragmaticiot.wordpress.com/2016/04/13/i-got-rhythm/
In the end, all you really need to do with the shield is just read the values on pins A0-A5. They will contain values you can graph to get the waveforms.
Good Luck
Miles Porter
Mporter#paintedharmony.com

Arduino IDE now has inbuilt Serial Plotter under Tools menu. Olimex provides a good document for hooking everything up and this is their code:
const int analogInPin = A0;
void setup() {
Serial.begin(9600);
}
void loop() {
int sensorValue = analogRead(analogInPin);
Serial.println(sensorValue);
}

Related

Wire Library - just the first byte device address is being transmitted

I am starting to study the Wire library (no previous Arduino Wire library experience), I read some info taken from here.
As you all know, this really simple example changes the value of a AD5171 digital potentiometer via I2C. Written by Nicholas Zambetti and Shawn Bonkowski, demonstrates use of the Wire library.
I just copied and reduced the code below a little from the example. I am an experienced assembler and C/C++ programmer and hardware developer/designer. Although several I2C devices like DS3231 RTC, etc. work fine using standard Arduino libraries, the mentioned example doesn't work for me in my working NANO board. What am I doing wrong?
This code should transmit:
first the I2C protocol device address - Start / 8 + 1bits
test instruction data byte
variable 1 test byte constantly incremented
I2C Stop condition
The only byte I can see in my oscilloscope is just the first one (please see picture below). The 2 data bytes are not being transmitted. If I reduce the transmission to just the step #2 instruction single data byte, the same result is shown.
#include <Wire.h>
void setup()
{
Wire.begin(); // join i2c bus (address optional for master)
}
byte val = 0;
void loop()
{
Wire.beginTransmission(44); // transmit to device #44 (0x2c)
Wire.write(byte(0x55)); // sends instruction byte
Wire.write(val++); // sends potentiometer value byte
Wire.endTransmission(); // stop transmitting
delay(50); // some time delay for my oscilloscope
}
This is what this code produces:
I see transferred data as 01011000 1. I hope the is right decoded. Why you not zoom it more for better reading? It is hard see data levels on raising clock edges. This match to address 44, 0x2C . As you can also see that you get NACK on the end of address octet. So this means no device with transmitting address is on the bus.
You can get error code about sending process from endTransmission function as return int. Send this value to serial monitor.
Error codes you can see in arduino documentation
uint8_t err;
err= Wire.endTransmission(); // stop transmitting and get status
You can also use sketch i2c_scanner from arduino Wire examples to discovery right address of your device.

I2C between EEPROM and Arduino working, not with STM32

This is driving me nuts for a couple of days now, so maybe you guys can give me some insights into what is going wrong.
I'm trying to read some data from an EEPROM (24LC16B) with an STM32(F0), but it just doesn't let me. I've tried an Arduino, which worked and does still work, so I do know that the wiring is correct.
This is my function to read the EEPROM data. (It is cut down to the very basis, just for testing): (Pastebin of my I2C_setup function)
uint16_t readEEPROMData(uint16_t deviceAddress, int memAddress){
// Wait while I2C peripheral is not ready
I2C_WaitForFlag(I2C_ISR_BUSY);
// Start I2C write transfer for 2 bytes, do not end transfer (SoftEnd_Mode)
I2C_TransferHandling(I2C1, 0xA2, 2, I2C_SoftEnd_Mode, I2C_Generate_Start_Write);
I2C_WaitForFlag(I2C_ISR_TXIS);
// For testing purpose, be sure to generate a stop command...
I2C_TransferHandling(I2C1, 0xA2, 0, I2C_AutoEnd_Mode, I2C_Generate_Stop);
return I2C_COMM_STATUS;
}
Here's an pastebin of the Arduino library I used.
I've used a logic analyzer to see how the communication is going, and now I really don't understand it. Here's a printscreen of the working Arduino version:
And here's a printscreen of the STM32 communication:
Logic analyzer exports (viewable with Saleae Logic)
As you can see, I'm using the same address (although I had to use 0xA2 with the STM32), and there are no weird things happening, besides the NACK. So what could possible be wrong?
Confirm if all bus timing requirement are satisfied.
Confirm if their is adequate delay after every write cycle (5 mS)
Confirm is bus capacitance falls under permissible limit of I2C (400 pF - Theoretically).
Confirm if the correct VCC is supplied
As mentioned by you are interfacing EEPROM with MCU using cable you need to conform on capacitance.
You can use an oscilloscope to check if their are any distortion in waveform. You can use a LCR meter to check the capacitance.
Try reducing bus speed 25kHz to 50 kHz and check waveform.
Try increasing the strength of pull resister.
The problem with the wrong VCC capacity (4.2v instead of 5v for example) is, that the timing can be different to. (not fully verified, but it fixed the problem)

Interrupting with SoftwareSerial on Arduino

I'm using Bluetooth serial port profile to communicate with Arduino. The bluetooth module (HC-06) is connected to my digital pins 10 and 11 (RX, TX). The module is working properly, but I need an interrupt on data receive. I can't periodically check for incoming data as Arduino is working on a time-sensitive task (music-playing through a passive buzzer) and I need control signals to interrupt immediately on receive. I've looked through many documents including Arduino's own site, and they all explain how to establish regular communication using checking for serialPort.available() periodically. I've found one SO question Arduino Serial Interrupts but that's too complicated for my level. Any suggestions on reading realtime input through serial?
Note that the current version of SoftSerial actually uses PCINT to detect the individual bits. Hence I believe defining it again at the main loop would conflict with the SoftSerial's actual detection of bits.
I am reluctant to suggest this as it is modifying a core library. Which is difficult not to do when sharing interrupts. But if desperate, you could modify that routine, with your need.
within
\arduino-1.5.7\hardware\arduino\avr\libraries\SoftwareSerial\SoftwareSerial.cpp.
//
// The receive routine called by the interrupt handler
//
void SoftwareSerial::recv()
{
...
// if buffer full, set the overflow flag and return
if ((_receive_buffer_tail + 1) % _SS_MAX_RX_BUFF != _receive_buffer_head)
{
// save new data in buffer: tail points to where byte goes
_receive_buffer[_receive_buffer_tail] = d; // save new byte
_receive_buffer_tail = (_receive_buffer_tail + 1) % _SS_MAX_RX_BUFF;
#ifdef YOUR_THING_ENABLE
// Quickly check if it is what you want and DO YOUR THING HERE!
#endif
}
...
}
But beware your are still in a ISR and all Interrupts are OFF and you are blocking EVERYTHING. One should not lollygag nor dilly dally, here. Do you something quick and get out.

Arduino serial: inverted 7E1. Possible?

I'm trying to talk serial with an SDI-12 device, and it requires inverted seven data bits, even parity and one stop bit (7E1) serial at 1200 baud.
From the datasheet:
SDI-12 communication sends characters at 1200 bits per second. Each character has 1 start bit, 7 data bits (LSB first), 1 even parity bit, and 1 stop bit (Active low or inverted logic levels):
All SDI-12 commands and response must adhere to the following format on the data line. Both the command and response are preceded by an address and terminated by a carriage return line feed combination.
Is this possible with the Serial or SoftwareSerial libraries? I am trying to avoid additional hardware (beyond a levelshifter to 3.3 V), but I will do so if it is the only way.
I have seen that SoftwareSerial can do inverted, and Serial can do 7E1, but I can't find if either can do both.
I have access to a Arduino Mega (R2), and Arduino Uno (R3).
Here is the device I want to communicate with: http://www.decagon.com/products/sensors/soil-moisture-sensors/gs3-soil-moisture-temperature-and-ec/ and here, http://www.decagon.com/assets/Uploads/GS3-Integrators-Guide.pdf is the document explaining the protocol. Page 6 talks about its implementation of SDI.
I'm not familiar with Arduino, however the SDI-12 physical layer is inverted from the standard TTL levels - probably for two reasons:
Since the idle voltage is 0V, this results in lower standby power (due to nominal pull-down resistors in a typical SDI-12 sensor.
It facilitates simple bus 'sniffing' using a standard RS-232 serial port.
Short of bit-banging a 5V IO pin - yes, if using a standard microcontroller UART you will need an external inverter (or 2) and a 3-state buffer. Possibly requiring level shifting, depending on your hardware.
Thumbs down to the Wikipedia entry - SDI-12 uses entirely standard UART bit timings (very much like RS-232), just different signal levels (0 - 5V); see point #2. However, there are specific break sequences and strict timing requirements, which makes firmware development more difficult.
If you are serious about SDI-12 firmware development, you may want to invest in an SDI-12 Verifier. A thorough study of the specification is essential.
A little late... but better late than never
I have actually just written a library for exactly that (actually exactly that including the sensors ... so it should work exactly with the included examples )
https://github.com/joranbeasley/SDISerial (Arduino Library)
#include <SDISerial.h> //https://github.com/joranbeasley/SDISerial (Arduino Library)
#include <string.h>
#define DATA_PIN 2
SDISerial connection(DATA_PIN);
char output_buffer[125]; // just for uart prints
char tmp_buffer[4];
char sensor_info[]
//initialize variables
void setup(){
connection.begin();
Serial.begin(9600);//so we can print to standard uart
//small delay to let the sensor do its startup stuff
delay(3000);//3 seconds should be more than enough
char* sensor_info = connection.sdi_query("0I!",1000); // get sensor info for address 0
}
//main loop
void loop(){
//print to uart
Serial.println("Begin Command: ?M!");
//send measurement query (M) to the first device on our bus
char* resp = connection.service_request("0M!","0D0!");//Get Measurement from address 0
sprintf(output_buffer,"RECV: %s",resp?resp:"No Response Recieved!!");
Serial.println(output_buffer);
delay(10000);//sleep for 10 seconds before the next read
}

Two port receive using software serial on Arduino

i am having trouble getting data from two sensors using two software serial ports with an arduino board. I noticed a similar question might have been asked before but the answers suggest it can't be done and I know fully well it can based on the example here (http://arduino.cc/en/Tutorial/TwoPortReceive)!
I am using an arduino ethernet. The devices I am trying to get data from include a GPS and an IMU both from sparkfun.
I can get data from either devices using just on software serial port but as soon as I add the second software serial port, neither ports will work. I can't use the hardware serial port because that is being used byt another device.
My code is exactly similar to the example:
#include <SoftwareSerial.h>
SoftwareSerial portOne(7,8);
SoftwareSerial portTwo(5,6);
void setup()
{
Serial.begin(9600);
portOne.begin(9600);
portTwo.begin(9600);
}
void loop()
{
portOne.listen();
while (portOne.available() > 0) {
char inByte = portOne.read();
Serial.write(inByte);
}
delay(500);
portTwo.listen();
while (portTwo.available() > 0) {
char inByte = portTwo.read();
Serial.write(inByte);
}
Serial.println();
}
Anyone with any ideas?
This code will not work, or will work poorly if it works at all. SoftwareSerial only has one internal buffer. Yes, you can have multiple SoftwareSerial objects in existence, but only one of them controls the internal buffer. When any RX pin gets asserted, that generates an interrupt, but only the listen()ing RX pin gets checked for a start bit.
What's really needed is the ability to check on multiple pins when an interrupt comes along from the start bit. Then you'd have to set up pointers to the appropriate data structures. It would be complicated, but possible.
Or maybe just give up on interrupt-driven reception, and spin on checking both/all of the RX pins, and start the receive based on the pin you see. Be forwarned that this code has much hair, and you WILL need an oscilloscope to make it work.
I'm having a similar problem, which is why I found your sensor. After talking it over with my co-workers, we've decided to read our sensors in rotating order. Our sensors report the current state of the sensor, and not specific events, so it's okay if we lose some reports. So we'll read from port 1, then read from port 2, then port 1, etc. Our sensors spit out lines of text, so we know when to switch to the next sensor.
The referenced example only actively listens to one port at a time. The recommended solution would be to upgrade to an Arduino Mega (https://www.sparkfun.com/products/11061) which has 4 hardware serial ports.
In order to simultaneously support two software serial ports is going to require a lot of the CPU resources. It also be a difficult design and excessive programming time far outweighing the cost of $58 + shipping.
Looking at you code again it occurs to me that you are immediately checking for characters after your portOne.listen command. At 9600 baud it will take approximately 1ms for the first character to arrive, your while test will have been completed and the portTwo.listen command executed long before the first character arrives.
For testing purposes try adding a 1-2 ms delay after the portOne.listen command and see if you get a character.
As an example (untested and note, if port one is sending characters with no intercharacter gaps, the first while will never fail, preventing reading portTwo characters):
void loop()
{
portOne.listen();
delay(2);
while (portOne.available() > 0) {
char inByte = portOne.read();
Serial.write(inByte);
delay(1);
}
portTwo.listen();
delay(2);
while (portTwo.available() > 0) {
char inByte = portTwo.read();
Serial.write(inByte);
delay(1);
}
Serial.println();
}
Don't use while ......
Use:
{ portOne.listen();
if (PortOne.available() ) {
ricevo = myPort1.read(); }
// delay(2); // ridiculos waiting time
// delay(1); // extra ridiculos waiting time
Than 500 ms is a too big time for switching, no time.....

Resources