I am stuck trying to get data from one arduino to another. This article on serial communication was extremely helpful, but am currently on receiving 0's. Other attempts had 255 for both high/low bytes.
TL;DR Objective: Master arduino defines an interval (in micros) for Slaves to trigger stepper motors.
Longer Desc.: 1 Master arduino defines 10x slave arduino's "target step interval" (in micros). At various points of time the master sets a new target for each slave, and each slave slowly adjusts its current step-interval to reach its target interval.
NOTE:
I have omitted the slave's "speed adjustment" code to focus on the issue above/li]
Stepper motor desired step-interval is ~500-520 micros without microstepping (half or quarter of this if microstepping).
I chose to transfer by binary as I suspect it may be the fastest. I am concerned time wasted on receiving commands via serial may affect stepper motors accuracy and potentially mis-step/stall
Should i be using a different method or 'receiveEvent' / interrupt type approach?
Any help is greatly appreciated. Thanks
MASTER CODE:
/*
* MASTER SPEED CONTROLL / Test changing Target RPS every X Seconds
* Need 1 timer, every X ms change RPSmicros by X
*/
#include <Wire.h>
unsigned long prevMillis = 0;
unsigned long intervalMillis = 4000; //how long to trigger send to slaves. 1000=1s
int RPSmicros = 500; //motor target speed (no microsteps)
void setup() {
Wire.begin(8); // join i2c bus with address #8
Serial.begin(9600);
}
void loop() {
unsigned long curMillis = millis();
if (curMillis - prevMillis >= intervalMillis) {
prevMillis = curMillis;
// RPSmicros += 10;
Wire.beginTransmission(8); // transmit to device #8
Wire.write('*'); //attempt at writing a flag for start
Wire.write(highByte(RPSmicros)); //send remainder
Wire.write(lowByte(RPSmicros));
Wire.endTransmission(); // stop transmitting
Serial.println('*');
Serial.println(highByte(RPSmicros));
Serial.println(lowByte(RPSmicros));
// intValue = RPSmicros;
}
else {
// prevMillis = curMillis;
}
}
SLAVE CODE:
#include <Wire.h>
int RPSmicros;
byte b[2]; // byte array
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() {
memset(b, '\0', 2);
if (Serial.available() > 0) { // only loop the serial structure if its serialing
char inbyte = '\0'; // null?
inbyte = Serial.read(); // change the inbyte to the waiting byte
if (inbyte == '*') { // this means its the start of a number
for (int i=0; i<2; i++) {
b[i] = Serial.read();
}
}
}
RPSmicros = b[0] * 256 + b[1];
Serial.println(b[0]);
Serial.println(b[1]);
Serial.println(RPSmicros);
Serial.println();
}
//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
// }
// byte b[0] = Serial.read();
// byte b[1] = Serial.read();
// RPSmicros = b[0] * 256 + b[1];
// Serial.println(b1);
// Serial.println(b2);
// Serial.println();
// x = Wire.read(); // receive byte
//}
Thank you for taking the time to reply. I believe I2C. Now that you've asked there is a glaring issue ask may be crossing methods. The A4 A5 pins and ground are connected.
Which would you recommend based on the timing details above?
Your slave code has a problem. If one byte has arrived (Serial.avaliable() > 0) and that byte is a '*', read two more bytes that might not have arrived yet.
Remember, serial is slow compared to the processor.
You have mixed up I2C Serial Communication with UART Serial Communication. From your codes, it appears that you are using I2C Bus for data exchange between two Arduinos. Please, revise your hardware connection and software routines as per following recommendations and report the results.
A: I2C Bus connection between 2 Arduinos
B: Master Codes:
#include <Wire.h>
unsigned long prevMillis = 0;
unsigned long intervalMillis = 4000; //how long to trigger send to slaves. 1000=1s
int RPSmicros = 500; //0x01F4 motor target speed (no microsteps)
void setup()
{
Wire.begin();//begin(8); // join i2c bus with address #8
Serial.begin(9600);
}
void loop()
{
//unsigned long curMillis = millis();
if (millis() - prevMillis >= intervalMillis)
{
prevMillis = millis(); //curMillis;
// RPSmicros += 10;
Wire.beginTransmission(8); // transmit to device #8
Wire.write('*'); //attempt at writing a flag for start
Wire.write(highByte(RPSmicros)); //send remainder
Wire.write(lowByte(RPSmicros));
Wire.endTransmission(); // stop transmitting
Serial.println('*');
Serial.println(highByte(RPSmicros), HEX); //0x01; upper byte of 500
Serial.println(lowByte(RPSmicros), HEX); //0xF4; lower byte of 500
}
}
C: Slave Codes:
#include <Wire.h>
int RPSmicros;
byte b[3];//b[2]; // byte array
bool flag1 = LOW;
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()
{
if (flag1 == HIGH)
{
if (b[0] == '*')
{
// RPSmicros = b[0] * 256 + b[1];
Serial.println(b[0]); //shows: *
Serial.println(b[1], HEX); //show 0x01; upper byte of 500
Serial.println(b[2], HEX); //shows: 0xF4; lower byte of 500
RPSmicros = (b[1] << 8) | b[2];
Serial.println(RPSmicros, DEC);//shows: 500
flag1 = LOW;
}
}
}
void receiveEvent(int howMany)
{
for (int i = 0; i < howMany; i++)
{
b[i] = Wire.read();
}
flag1 = HIGH;
}
Thanks so much! This is great.
I haven't seen bitshifts before. Is there a reason why you chose it over "b[1] * 256 + b[2]"?
Any input on whether I should be using this method given the slave's responsibility of driving stepper motors at 250-500 micros per step? I'm going to start testing now, but want to ensure I don't miss steps and stall a motor.
jingleby:
Thanks so much! This is great. 1. I haven't seen bitshifts before. Is there a reason why you chose it over "b[1] * 256 + b[2]"?
2. Any input on whether I should be using this method given the slave's responsibility of driving stepper motors at 250-500 micros per step? I'm going to start testing now, but want to ensure I don't miss steps and stall a motor.
Thanks for breaking that out
I intended to ask whether there was a higher likeliness of having pulse accuracy issues with one method of communication over another (i2c/serial/etc). No need to reply, I'm quite pleased the code is working.