I'm controlling several slave arduinos with my master arduino and from my master arduino i want to send commands like "M100" which moves the motor of the slave arduino to position 100. Sending the command works but with the interpretation of the receiver i have some problems
i don't know how to access the received argument ... can someone help me?
in the arduino serial monitor when the master sends "M100" i get "move command received with following argument: 100" but when the master sends for example "M9" i get "move command received with following argument: 9Â".
also it's not enough to display the argument the right way in the serial monitor but i need to convert it to int or something to pass it to my motor movement function
Replace:-
Serial.print(buff[1]);
with
Serial.print(buff[1], HEX);
then you can see exactly what bytes you are getting. You should see ASCII characters (if that is what you send). The is if you send ASCII 9 you will see the hex number 39 back.
//#include <math.h>
#include <Wire.h>;
#include <Stepper.h>;
// change this to the number of steps on your motor
#define STEPS 48
Stepper stepper(STEPS, 6, 9, 10, 11, 1);
void setup()
{
stepper.setSpeed(200);
stepper.step(48*3);
Wire.begin(4);
Wire.onReceive(receiveEvent);
}
void loop()
{
}
void receiveEvent(int howMany)
{
stepper.step(48*3);
}
the movement from setup() is done properly, but as soon as the slave receives the first data over Wire/I2C the motor TRIES to do one step (its more of a tiny microstep) and the arduino seems to freeze
There is nothing wrong with your pin assignments as they do not conflict with I2C communication (using analog 4 and 5).
The receiveEvent is an interrupt handler and you should not call any stepper library functions from within this handler. Rather you need to restrict yourself to collect the data (write to a global buffer) and then do the actuall processing of the data from within your loop function.
The receiveEvent is an interrupt handler and you should not call any stepper library functions from within this handler. Rather you need to restrict yourself to collect the data (write to a global buffer) and then do the actuall processing of the data from within your loop function.
thanks for the hint, did you mean something like that:
#include <Wire.h>;
#include <Stepper.h>;
// change this to the number of steps on your motor
#define STEPS 48
Stepper stepper(STEPS, 6, 7, 8, 9, 1);
int steps_to_make = 0;
void setup()
{
Serial.begin(9600);
Wire.begin(4);
Wire.onReceive(receiveEvent);
stepper.setSpeed(200);
}
void loop()
{
if( steps_to_make > 0)
{
stepper.step(steps_to_make);
steps_to_make = 0;
}
}
void receiveEvent(int howMany)
{
steps_to_make = 150;
}
when i run this sketch the motor does the full movement the FIRST time, but after that nothing happens although i'm still sending I2C data to the slave every 5 seconds...
Global variables modified within an interrupt handler need a volatile prefix. Otherwise the compiler may not add code to reload the variable and check that it actually changed.
Following your example, you need:
volatile int steps_to_make = 0;
You may also want to change "steps_to_make" to a byte quantity (as opposed to a 16-bit int) or else you are likely to run into a number of other issues.