Hey! I need to send values collected from a sensor between 0 and 100000 by I2C between two arduinos. Can anybody help me? Tnks =)
Master Code:
#include <I2S.h>
#include <Wire.h>
void setup() {
// Open serial communications and wait for port to open:
// A baud rate of 115200 is used instead of 9600 for a faster data rate
// on non-native USB ports
SerialUSB.begin(115200);
Wire.begin(); // join i2c bus (address optional for master)
while (!SerialUSB) {
; // wait for serial port to connect. Needed for native USB port only
}
// start I2S at 16 kHz with 32-bits per sample
if (!I2S.begin(I2S_PHILIPS_MODE, 16000, 32)) {
//SerialUSB.println("Failed to initialize I2S!");
while (1); // do nothing
}
}
#define SAMPLES 128 // make it a power of two for best DMA performance
//byte x = 0;
int valorFinal;
void loop() {
// read a bunch of samples:
int samples[SAMPLES];
for (int i=0; i<SAMPLES; i++) {
int sample = 0;
while ((sample == 0) || (sample == -1) ) {
sample = I2S.read();
}
// convert to 18 bit signed
sample >>= 14;
samples[i] = sample;
}
// ok we hvae the samples, get the mean (avg)
float meanval = 0;
for (int i=0; i<SAMPLES; i++) {
meanval += samples[i];
}
meanval /= SAMPLES;
//Serial.print("# average: " ); Serial.println(meanval);
// subtract it from all sapmles to get a 'normalized' output
for (int i=0; i<SAMPLES; i++) {
samples[i] -= meanval;
//Serial.println(samples[i]);
}
// find the 'peak to peak' max
float maxsample, minsample;
minsample = 100000;
maxsample = -100000;
for (int i=0; i<SAMPLES; i++) {
minsample = min(minsample, samples[i]);
maxsample = max(maxsample, samples[i]);
}
//SerialUSB.println(maxsample - minsample);
valorFinal = maxsample - minsample;
x = (int)valorFinal;
SerialUSB.println(valorFinal);
Wire.beginTransmission(8); // transmit to device #4
Wire.write(valorFinal); // sends one byte
Wire.endTransmission(); // stop transmitting
//delay(500);
}
Slave Code:
// Wire Slave Receiver
// by Nicholas Zambetti <http://www.zambetti.com>
// Demonstrates use of the Wire library
// Receives data as an I2C/TWI slave device
// Refer to the "Wire Master Writer" example for use with this
// Created 29 March 2006
// This example code is in the public domain.
#include <Wire.h>
void setup() {
Wire.begin(8); // join i2c bus with address #8
Wire.onReceive(receiveEvent); // register event
Serial.begin(9600); // start serial for output
}
void loop() {
delay(100);
}
// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany) {
while (1 < Wire.available()) { // loop through all but the last
char c = Wire.read(); // receive byte as a character
Serial.print(c); // print the character
}
int x = Wire.read(); // receive byte as an integer
Serial.println(x); // print the integer
}
Why do you need to send data to a other Arduino board ? Can you do your project with a single Arduino board ? The I2C bus is a bad idea to communicate between Arduino boards.
How much data do you want to transfer ? The I2C bus is for maybe a few hundred bytes per second.
Which Arduino boards do you have ?
The I2C bus uses a number of bytes. The "Wire.write(valorFinal)" send a byte with a value of 0...255.
The explanation in the link given by sherzaad explains how to send more, but it is often easier to transfer a struct or an array and use pointers to them.
Do you know if your board supports the Slave mode ? Are there examples of working projects with that board in Slave mode ?
I know the Slave code is from the official example, but it is bad code. For example the "loop through all but the last" is confusing. What is wrong with the last byte ? If something is wrong with the last byte, then why would it be send over I2C ?
I need to send this data to another board because I send this data to a mobile application, via bluetooth. This sensor uses the unique RX/TX ports. I need to transfer data between 0-60,000. I'm working with a samd21 mini and a mega2560. I need to send this data in real time to the mega2560.
Sparkfun SAMD21 Mini: https://www.sparkfun.com/products/13664
The SAMD21G is also used on a Arduino MKR Zero board. That is a 3.3V chip with a 3.3V I2C bus.
The Arduino Mega board is a 5V board with a 5V I2C bus. It is also the only board with 10k pullup resistors to 5V on the board.
Besides the undefined behavior caused by using a union this way (it's been discussed here many times), this also demonstrates another reason for not doing this. A 'long' is 4 bytes.
Just use:
(I also agree that using "union" to sneakily cast a long into a byte[3] is just nasty, results in code that is intransparent, and the idea of using a byte[3] in the first place is already a great way to make your code just a little bit more chaotic for pretty much no gain, unless your I2C line is at its capacity limit. Just don't do it.)
If you asked that question as an attempt to sneakily imply that gfvalvo doesn't know how reinterpret_cast works, then I apologize for misreading your post and would recommend that you try using regular sentences instead of questions in the future.
bureaucratic
(adjective)
relating to a system of government in which most of the important decisions are taken by state officials rather than by elected representatives.