Servo motors not working when called upon using I2C - arduino

So I'm using this movement() function inside the slave Arduino Uno, which basically handles two stepper motors and one servo motors, when I call this function through the serial read of the Arduino Uno it works perfectly, both the steppers and the servo.
But I have a master Arduino Mega interfaced with the Uno (mentioned above) when I send a wire message from the mega to Arduino to run the movement function in the Uno, the steppers work fine, but the servo does not work, although again I mention that when the function is called upon using the serial read of the Uno it works absolutely fine.
I'm using an Adafruit motor shield on the Arduino Uno as well.
Ok so this is the Uno (slave code)
void setup()
{
servo1.attach(9);
Serial.begin(9600);
Wire.begin(5);
Wire.onReceive(receiveEvent);
Serial.begin(9600);
}
void loop()
{
//other stuff
}
void receiveEvent(int howMany)
{
while(Wire.available())
{
char c = Wire.read();
int From = Wire.read();
int To = Wire.read();
int x = 0;
movement(From,To);
}
}
int movement(int from,int to)
{
int X_From = from / 10;
int X_To = to/10;
int Y_From = from % 10;
int Y_To = to % 10;
/* First we have to get the motor position and move the motor to the from position */
/* === START === */
int diff_X = X_From - motor_X;
int diff_Y = Y_From - motor_Y;
int Y_Value = abs(diff_Y * Y_Steps);
servoDown();
if(diff_X != 0)
{
if(diff_X > 0)
{
/* Positive value means the X_Axis motor will move in the forward direction */
int X_Value = abs(diff_X * X_Steps);
X_Forward(X_Value);
}
else
if(diff_X < 0)
{
/* Negative value means the X_Axis motor will move in the backward direction */
int X_Value = abs(diff_X * 400);
X_Backwards(X_Value);
}
}
//Serial.println(X_Value); Serial.println(Y_Value);
if(diff_Y != 0)
{
if(diff_Y > 0)
{
Y_Forward(Y_Value);
}
else
if(diff_Y < 0)
{
Y_Backwards(Y_Value);
}
}
Serial.println("Motor movement done");
/* === END === */
motor_X = X_From;
motor_Y = Y_From;
int diff_X_2 = X_To - motor_X;
int diff_Y_2 = Y_To - motor_Y;
int Y_Value2 = abs(diff_Y_2 * Y_Steps);
servoUp();
if(diff_X_2 != 0)
{
if(diff_X_2 > 0)
{
/* Positive value means the X_Axis motor will move in the forward direction */
int X_Value2 = abs(diff_X_2 * X_Steps);
X_Forward(X_Value2);
}
else
if(diff_X_2 < 0)
{
/* Negative value means the X_Axis motor will move in the backward direction */
int X_Value2 = abs(diff_X_2 * 400);
X_Backwards(X_Value2);
}
}
if(diff_Y_2 != 0)
{
if(diff_Y_2 > 0)
{
Y_Forward(Y_Value2);
}
else
if(diff_Y_2 < 0)
{
Y_Backwards(Y_Value2);
}
}
//Serial.println(X_Value2); Serial.println(Y_Value2);
motor_X = X_To;
motor_Y = Y_To;
Serial.println("piece movement done");
return 1;
}
void servoUp()
{
for (i = 100; i >= 0; i--)
{
servo1.write(i);
// delay(20);
}
}
void servoDown()
{
for (i = 0; i < 100; i++)
{
servo1.write(i);
//delay(20);
}
}
This is the master Mega code
void setup()
{
Wire.begin();
}
void loop()
{
//check if a condition appeared from sensor and then send the data to uno to run the movement function through sendData()
sendData(From,To);
}
void sendData(int From,int To)
{
Wire.beginTransmission(5);
Wire.write('f');
Wire.write(From);
Wire.write(To);
Wire.endTransmission();
}
Any suggestions?

Looks like the servo movement does not depend no the data transmitted. Did you check if the intended values are actually received? One thing to keep in mind: read() reads a single byte. Are you trying to transmit a value larger than 255?

Related

Send and read the button state via CAN bus using Arduino

I'm intending to read the change of button input using 2 separate Arduino that connected via CAN bus (MP2515). The transmitter will connect to button with internal pulldown resistor, that pin will act as external interrupt. My reference is coming from here. By not assign any value to data frame (canMsg1 and canMsg2 in the code below), is that enough for the receiver to understand the input pin state?
The origin code using digitalRead(pin) to read and later write state of the button by single Arduino.
transmitter of CAN massage
#include <SPI.h>
#include <mcp2515.h>
struct can_frame canMsg1;
struct can_frame canMsg2;
MCP2515 mcp2515(10);
int incPin(2);
int decPin(3);
unsigned long current_time = 0;
unsigned long previous_time = 0;
void setup() {
Serial.begin(9600);
SPI.begin();
mcp2515.reset();
mcp2515.setBitrate(CAN_500KBPS, MCP_8MHZ);
mcp2515.setNormalMode();
canMsg1.can_id = 0xAA;
canMsg1.can_dlc = 1;
canMsg2.can_id = 0xBB
canMsg2.can_dlc = 1;
pinMode(incPin, INPUT_PULLUP);
pinMode(decnPin, INPUT_PULLUP);
attachInterrupt(incpPin, inc, FALLING);
attachInterrupt(decPin, dec, FALLING);
}
void loop() {}
void inc() {
current_time = millis();
if (current_time - previous_time > 200) { //debouncing for 0.2s
mcp2515.sendMessage(&canMsg1);
}
previous_time = current_time;
}
void dec() {
current_time = millis();
if (current_time - previous_time > 200) { //debouncing for 0.2s
mcp2515.sendMessage(&canMsg2);
}
previous_time = current_time;
}
receiver/reader of CAN massage
#include <SPI.h>
#include <mcp2515.h>
struct can_frame canMsg1;
struct can_frame canMsg2;
MCP2515 mcp2515(10);
int pos = 0;
int up;
int down;
void setup() {
Serial.begin(9600);
SPI.begin();
mcp2515.reset();
mcp2515.setBitrate(CAN_500KBPS, MCP_8MHZ);
mcp2515.setNormalMode();
}
void loop() {
if (mcp2515.readMessage(&canMsg1) == MCP2515::ERROR_OK) { //read CAN increment button message
if (canMsg1.can_id==0xAA) {
up = canMsg1.data[0];
if (up == LOW) {
pos++;
} else {}
}
}
if (mcp2515.readMessage(&canMsg2) == MCP2515::ERROR_OK) { //read CAN decrement button message
if (canMsg2.can_id==0xBB) {
down = canMsg2.data[0];
if (down == LOW) {
pos--;
} else {}
}
}
}
You are right, your CAN events do not require any data. But then, why do you set can_dlc to 1? No data is 0 bytes.
You can try this:
Get rid of:
struct can_frame canMsg1; // these only hog global memory for no practical use.
struct can_frame canMsg2;
Change your interrupt routines to:
void inc() {
current_time = millis();
if (current_time - previous_time > 200) { //debouncing for 0.2s
mcp2515.beginPacket(0xAA);
mcp2515.endPacket();
}
previous_time = current_time;
}
void dec() {
current_time = millis();
if (current_time - previous_time > 200) { //debouncing for 0.2s
mcp2515.beginPacket(0xBB);
mcp2515.endPacket();
}
previous_time = current_time;
}
I could not figure out what canMsg7 and canMsg8 were. Nor why you'd need several message structures in global memory to receive one CAN message at a time... I really don't think that's necessary. Since your packets have no data, receiving gets streamlined as well:
int loop() {
if (mcp2515.parsePacket() != 0) { // != 0 => we have fully received a packet.
switch (mcp2515.packetId()) {
case 0xAA:
// inc switch was pressed
// ...
break;
case 0xBB:
// dec switch was pressed
// ...
break;
}
}
}

Arduino script throws error "X was not declared in this scope"

Code and scheme from this link: https://www.makerspaces.com/15-simple-arduino-uno-breadboard-projects/
I'm a total beginner. I just started and I had some difficulties with the board, my PC isn't recognising the board and I wanted to create a simple circuit to test some commands, to see if I solved the problem
Full code:
// Pin assignement
#define btnPin 7
#define led1Pin 8
#define led2Pin 9
#define led3Pin 10
enum fcnMode {
OFF,
LED1,
LED2,
LED3,
FADE1,
ALL,
BLINK,
NBSTATE
}; // OFF = 0 and NBSTATE=7
int ledState1 = LOW,ledState2 = LOW,ledState3 = LOW; // ledState used to set the LED
unsigned long buttonState = 0;
int funcState=0;
unsigned long currentMillis1,currentMillis2,currentMillis3; // will store current time
unsigned long previousMillis1,previousMillis2,previousMillis3; // will store last time LED was updated
const long interval1 = 100; // interval at which to blink (milliseconds)
const long interval2 = 300;
const long interval3 = 500;
/******************************************************************\
* PRIVATE FUNCTION: setup
*
* PARAMETERS:
* ~ void
*
* RETURN:
* ~ void
*
* DESCRIPTIONS:
* Initiate inputs/outputs
*
\******************************************************************/
void setup(){
Serial.begin(9600); // initialize serial port
pinMode(btnPin,INPUT_PULLUP);
pinMode(led1Pin,OUTPUT);
pinMode(led2Pin,OUTPUT);
pinMode(led3Pin,OUTPUT);
}
/******************************************************************\
* PRIVATE FUNCTION: loop
*
* PARAMETERS:
* ~ void
*
* RETURN:
* ~ void
*
* DESCRIPTIONS:
* Main Function of the code
\******************************************************************/
void loop(){
buttonPressed();
setMode();
}
/******************************************************************
* SUBFUNCTIONS
\******************************************************************/
void buttonPressed() {
buttonState = pulseIn(btnPin,HIGH,1000000);
if (buttonState > 50){
funcState += 1;
Serial.print("Button state n: ");
Serial.println(funcState);
}
funcState=funcState%NBSTATE;
}
void setMode() {
// All Off
digitalWrite(led1Pin,LOW);
digitalWrite(led2Pin,LOW);
digitalWrite(led3Pin,LOW);
Serial.print("Function : ");
Serial.println(funcState);
switch(funcState){
case OFF:
break;
case LED1:
digitalWrite(led1Pin,HIGH);
break;
case LED2:
digitalWrite(led2Pin,HIGH);
break;
case LED3:
digitalWrite(led3Pin,HIGH);
break;
case FADE1:
fade1();
break;
case ALL:
digitalWrite(led1Pin,HIGH);
digitalWrite(led2Pin,HIGH);
digitalWrite(led3Pin,HIGH);
break;
case BLINK:
blinkLed1();
blinkLed2();
blinkLed3();
break;
}
}
void fade1(){
int brightness = 0;
int fadeAmount = 5;
for (brightness=0;brightness<=255;brightness+=fadeAmount){
analogWrite(led1Pin, brightness);
delay(30);
}
for (brightness=255;brightness>=0;brightness-=fadeAmount){
analogWrite(led1Pin, brightness);
delay(30);
}
}
void blinkLed1(){
currentMillis1 = millis();
if (currentMillis1 - previousMillis1 >= interval1) {
// save the last time you blinked the LED
previousMillis1 = currentMillis1;
// if the LED is off turn it on and vice-versa:
if (ledState1 == LOW) {
ledState1 = HIGH;
} else {
ledState1 = LOW;
}
// set the LED with the ledState of the variable:
digitalWrite(led1Pin, ledState1);
}
}
void blinkLed2(){
currentMillis2 = millis();
if (currentMillis2 - previousMillis2 >= interval2) {
// save the last time you blinked the LED
previousMillis2 = currentMillis2;
// if the LED is off turn it on and vice-versa:
if (ledState2 == LOW) {
ledState2 = HIGH;
} else {
ledState2 = LOW;
}
// set the LED with the ledState of the variable:
digitalWrite(led2Pin, ledState2);
}
}
void blinkLed3(){
currentMillis3 = millis();
if (currentMillis3 - previousMillis3 >= interval3) {
// save the last time you blinked the LED
previousMillis3 = currentMillis3;
// if the LED is off turn it on and vice-versa:
if (ledState3 == LOW) {
ledState3 = HIGH;
} else {
ledState3 = LOW;
}
// set the LED with the ledState of the variable:
digitalWrite(led3Pin, ledState3);
}
}
Error:
sketch_may09b.cpp: In function 'void setup()':
sketch_may09b:38: error: 'INPUT_PULLUP' was not declared in this scope
Your file extension is .cpp. I think it should be .ino if you are in Arduino IDE. If it doesn't help try just INPUT and add a pullup resistor to your button.

I2C between RPI and Arduino using Processing

Posted here is my code for my RPi master and Arduino slave project. I have an analog sensor connected to the Arduino and i am reading this data with Processing on the RPi. I am using Processing because I intend on generating a graph and waveform with the data. The code below seems to work, however, any slight movement of setup "disconnects" the slave device because I get the following message. "The device did not respond. Check the cabling and whether you are using the correct address." I have narrowed the problem down and found out that it always disconnects at the i2c.read();function. My question is whether there is some type of break function so that when this does happen processing moves on and tries again in the next iteration? Or if it is stuck in a loop is it waiting for some signal from the slave device? Does anyone have any suggestions on how to approach this?
Processing Code
import processing.io.*;
I2C i2c;
int val = 0;
void setup()
{
i2c = new I2C(I2C.list()[0]);
}
void draw ()
{
if (I2C.list() != null)
{
i2c.beginTransmission(0x04);
i2c.write(8);
byte[] in = i2c.read(1);
int accel = in[0];
println (accel);
}
}
Arduino Code
#include <Wire.h>
#define SLAVE_ADDRESS 0x04
int number = 5;
int state = 0;
const int zInput = A0;
int zRawMin = 493;
int zRawMax = 530;
float acceleration;
int accel;
void setup() {
analogReference(EXTERNAL);
pinMode(13,OUTPUT);
Serial.begin(9600); // start serial for output
Wire.begin(SLAVE_ADDRESS); // join i2c bus with address #8
Wire.onReceive(receiveData); // register event
Wire.onRequest(sendData);
Serial.println ("Ready");
}
void loop() {
int zRaw = ReadAxis (zInput);
acceleration = map (float(zRaw), float (zRawMin), float(zRawMax), -9.81, 9.81);
accel = int(acceleration);
//delay(100);
}
void receiveData(int byteCount)
{
while (0 < Wire.available())
{ // loop through all but the last
number = Wire.read(); // receive byte as a character
//Serial.print("data received");
Serial.println(number); // print the character
if (number==1)
{
if (state == 0)
{
digitalWrite(13,HIGH);
state = 1;
}
else
{
digitalWrite(13,LOW);
state = 0;
}
}
}
}
void sendData()
{
Wire.write(accel);
}
int ReadAxis(int axisPin)
{
long reading = 0;
int raw = analogRead(axisPin);
return raw;
}
Looks like a solution might be to use a try/catch block courtesy of #Kevin Workman. It works well for what I need it to do thx.
here is the updated Processing code.
import processing.io.*;
I2C i2c;
int val = 0;
void setup()
{
i2c = new I2C(I2C.list()[0]);
}
void draw ()
{
if (I2C.list() != null)
{
i2c.beginTransmission(0x04);
i2c.write(8);
try
{
byte[] in = i2c.read(1);
}
catch(Exception e)
{
i2c.endTransmission();
}
int accel = in[0];
println (accel);
}
}

Problems using a class with arduino

I am trying to make a micro-mouse maze solving robot, and I'm running into some issues with my class called Mouse. I get the error: expected ';' before 'right_motor' and 'left_motor'. I have no idea what is wrong with the code. I also am not sure exactly where I should declare my objects left and right motors. Here is all my code, thank you for your help.
Mouse.h:
#ifndef _MOUSE_H_
#define _MOUSE_H_
class Mouse
{
private:
int speed;
int motor_num;
int direction;
public:
Mouse(int motor_number);
~Mouse();
void run(int speed, int direction);
};
#endif
Mouse.cpp:
#include "mouse.h"
Mouse::Mouse(int motor_number)
{
motor_num = motor_number;
speed = 0;
direction = 0;
return;
}
// Digital pin 11: DC Motor #1 / Stepper #1 (activation/speed control)
// Digital pin 3: DC Motor #2 / Stepper #1 (activation/speed control)
// Digital pin 5: DC Motor #3 / Stepper #2 (activation/speed control)
// Digital pin 6: DC Motor #4 / Stepper #2 (activation/speed control)
void Mouse::run(int speed, int direction)
{
int M1 = 11;
int M2 = 3;
int M3 = 5;
int M4 = 6;
if(motor_num == 1)
{
if(direction == 1)
{
analogWrite(M1, speed);
}
if(direction == -1)
{
// FIXME: how do i do backwards?
}
if(direction == 0)
{
digitalWrite(M1, LOW);
}
}
if(motor_num == 2)
{
if(direction == 1)
{
analogWrite(M2, speed);
}
if(direction == -1)
{
// FIXME: how do i do backwards?
}
if(direction == 0)
{
digitalWrite(M2, LOW);
}
}
if(motor_num == 3)
{
if(direction == 1)
{
analogWrite(M3, speed);
}
if(direction == -1)
{
// FIXME: how do i do backwards?
}
if(direction == 0)
{
digitalWrite(M3, LOW);
}
}
if(motor_num == 4)
{
if(direction == 1)
{
analogWrite(M4, speed);
}
if(direction == -1)
{
// FIXME: how do i do backwards?
}
if(direction == 0)
{
digitalWrite(M4, LOW);
}
}
return;
}
Code in the Arduino sketch:
#include "mouse.h"
void setup()
{
//begin communication with serial port:
Serial.begin(9600);
//pinmodes setup:
//declare variables:
Mouse right_motor(1);
Mouse left_motor(2);
}
void loop()
{
//assign values to their respective variables:
//BEGIN PROGRAM
}
Change your class in MyMouse (...and update all reference of it), I think Mouse is an internal Arduino library
then, pay attention on Uppercase chars sometimes Mouse is uppercase and sometimes is lowercase
Edit:
this is Mouse Arduino library
http://www.arduino.cc/en/Reference/MouseKeyboard

Making a Game With Arduino and Processing

I am trying to form a two player game which requires an audio reflex to a visual. by using littebits sound trigger for sound input and littbits arduino to connect it to the computer. But I am new to this and don't know how to connect arduino to processing and use the input from sound trigger to effect the score when a black square appears.
here is my code in processing and a sample arduino code I have taken from littlebits website and tried to modify a little.
thanks in advance!
float dice;
int playerOne = 0; //player 1 score (left paddle)
int playerTwo = 0; //player 2 score (right paddle)
boolean oneWins = false;
boolean twoWins = false;
void setup(){
size(500, 500);
smooth();
noStroke();
frameRate(2.5);
}
void draw() {
background(255);
showGUI();
dice = random(0, 3);
if (dice < 1.000001 && dice > 0.1){
fill ((0), (255), (0));
ellipse (250,250,100,100);
} else if (dice < 2.000001 && dice > 1.000001){
rectMode(RADIUS);
fill ((255), (0), (0));
rect (250,250,50,50);
} else if (dice < 3.000000 && dice > 1.000000){
rectMode(RADIUS);
fill ((0), (0), (255));
rect (250,250,50,50);
} else if (dice < 0.1){
rectMode(RADIUS);
fill(0);
rect(250,250,50,50);
}
}
----------arduino------
void setup() {
Serial.begin(9600); //Establish rate of Serial communication
establishContact(); //See function below
}
void loop() {
if (Serial.available() > 0) {
int inByte = Serial.read();
int leftTrigger = analogRead(A0);
Serial.print(leftTrigger, DEC);
Serial.print(",");
int rightTrigger = analogRead(A1);
Serial.println(rightTrigger, DEC);
}
}
void establishContact() {
while (Serial.available() <= 0) {
Serial.println("hello");
delay(300);
}
}
You need two pieces of code for this to work: one on the Arduino that sends commands, and one for Processing to receive and parse those commands.
I haven't used the littlebits modules, but here's a button example from this very detailed tutorial.
Arduino code:
int switchPin = 4; // switch connected to pin 4
void setup() {
pinMode(switchPin, INPUT); // set pin 0 as an input
Serial.begin(9600); // start serial communication at 9600bps
}
void loop() {
if (digitalRead(switchPin) == HIGH) { // if switch is ON,
Serial.print(1, BYTE); // send 1 to Processing
} else { // if the switch is not ON,
Serial.print(0, BYTE); // send 0 to Processing
}
delay(100); // wait 100 milliseconds
}
And the matching Processing code:
import processing.serial.*;
Serial port; // create object from Serial class
int val; // data received from the serial port
void setup() {
size(200, 200);
frameRate(10);
// open the port that the board is connected to
// and use the same speed (9600bps)
port = new Serial(this, 9600);
}
void draw() {
if (0 < port.available()) { // if data is available,
val = port.read(); // read it and store it in val
}
background(255); // set background to white
if (val == 0) { // if the serial value is 0,
fill(0); // set fill to black
} else { // if the serial value is not 0,
fill(204); // set fill to light gray
}
rect(50, 50, 100, 100);
}
Notice that the Arduino sends a value that Processing looks for and interprets. You can also look at the PhysicalPixel example from the Arduino IDE for an example on sending data from Processing to Arduino.

Resources