hello,
i'm a total beginner when it comes to Code.
can you please help me out? I want to send a CAN Message when i press a physical button.
how do i code this ? i thik it should be something like:
#include <SPI.h>
#include <mcp2515.h>
struct can_frame canMsg1;
struct can_frame canMsg2;
MCP2515 mcp2515(10);
const int buttonPin = 2;
int buttonState = 0;
void setup() {
canMsg1.can_id = 0x111;
canMsg1.can_dlc = 8;
canMsg1.data[0] = 0x8E;
canMsg1.data[1] = 0x87;
canMsg1.data[2] = 0x32;
canMsg1.data[3] = 0xFA;
canMsg1.data[4] = 0x26;
canMsg1.data[5] = 0x8E;
canMsg1.data[6] = 0xBE;
canMsg1.data[7] = 0x86;
canMsg2.can_id = 0x222;
canMsg2.can_dlc = 8;
canMsg2.data[0] = 0x0E;
canMsg2.data[1] = 0x00;
canMsg2.data[2] = 0x00;
canMsg2.data[3] = 0x08;
canMsg2.data[4] = 0x01;
canMsg2.data[5] = 0x00;
canMsg2.data[6] = 0x00;
canMsg2.data[7] = 0xA0;
while (!Serial);
Serial.begin(115200);
SPI.begin();
mcp2515.reset();
mcp2515.setBitrate(CAN_500KBPS,MCP_8MHZ);
mcp2515.setNormalMode();
pinMode(buttonPin, INPUT);
pinMode(ledPin, OUTPUT);
}
void loop() {
buttonState = digitalRead(buttonPin); // read the state of the pushbutton value
Serial.println(buttonState); // Show the state of pushbutton on serial monitor
if (buttonState == HIGH) { // check if the pushbutton is pressed.
// CAN message1 send:
digitalWrite(mcp2515.sendMessage(&canMsg1));
}
Serial.println("Messages (&canMsg1) sent");
delay(100);
}
could please someone correct the code ?
thank you !
How is the input pin wired ?
Does it have a pulldown resistor or is it floating at an unknown voltage ?
Hello UKHeliBob,
the button has a pulldown resistor.
ok , i have conencted the Button now to PIN 3 (Arduino D3)
and i have adjusted the code like this:
#include <SPI.h>
#include <mcp2515.h>
struct can_frame canMsg1;
struct can_frame canMsg2;
MCP2515 mcp2515(10);
const int buttonPin = 3;
int buttonState = 0;
void setup() {
canMsg1.can_id = 0x111;
canMsg1.can_dlc = 8;
canMsg1.data[0] = 0x8E;
canMsg1.data[1] = 0x87;
canMsg1.data[2] = 0x32;
canMsg1.data[3] = 0xFA;
canMsg1.data[4] = 0x26;
canMsg1.data[5] = 0x8E;
canMsg1.data[6] = 0xBE;
canMsg1.data[7] = 0x86;
canMsg2.can_id = 0x222;
canMsg2.can_dlc = 8;
canMsg2.data[0] = 0x0E;
canMsg2.data[1] = 0x00;
canMsg2.data[2] = 0x00;
canMsg2.data[3] = 0x08;
canMsg2.data[4] = 0x01;
canMsg2.data[5] = 0x00;
canMsg2.data[6] = 0x00;
canMsg2.data[7] = 0xA0;
while (!Serial);
Serial.begin(115200);
SPI.begin();
mcp2515.reset();
mcp2515.setBitrate(CAN_500KBPS,MCP_8MHZ);
mcp2515.setNormalMode();
pinMode(buttonPin, INPUT);
}
void loop() {
buttonState = digitalRead(buttonPin); // read the state of the pushbutton value
Serial.println(buttonState); // Show the state of pushbutton on serial monitor
if (buttonState == HIGH)
{ // check if the pushbutton is pressed.
// CAN message1 send:
digitalWrite(mcp2515.sendMessage(&canMsg1), HIGH); }
else {
// CAN message1 not send:
digitalWrite(mcp2515.sendMessage(&canMsg2), LOW);
}
delay(100);
}
But like this the Message 2 gets sent all the time, and only when i push the button the Message 1 gets send.
This is not the behaviour that i wanted.
Attached screenshot with the behaviour
I want to send the Message 1, ONLY when i push the button. not to send the message 2 all the time, and message 1 by pushing the button.
how do i stop it from sending messages ?
digitalWrite(mcp2515.sendMessage(&canMsg1), HIGH);
What does the sendMessage() function return ?
Which pin do you want to go HIGH, bearing in ind that you have no pins defined as outputs ?
UKHeliBob:
digitalWrite(mcp2515.sendMessage(&canMsg1), HIGH);
What does the sendMessage() function return ?
Which pin do you want to go HIGH, bearing in ind that you have no pins defined as outputs ?
digitalWrite() takes 2 parameters. The first is the pin number to write to and the second is the state to set the pin to. So, if you wrote digitalWrite(3, HIGH), for instance, pin 3 would be set HIGH. In your code you have not got an explicit pin number, rather you have the value returned from the call to the mcp2515.sendMessage() function, hence my question
Now, if you don't want a pin to go HIGH why are you using digitalWrite() ?
ok ok, you are right, it worked.
i adjusted the code like you told me:
#include <SPI.h>
#include <mcp2515.h>
struct can_frame canMsg1;
struct can_frame canMsg2;
MCP2515 mcp2515(10);
const int buttonPin = 3;
int buttonState = 0;
void setup() {
canMsg1.can_id = 0x111;
canMsg1.can_dlc = 8;
canMsg1.data[0] = 0x8E;
canMsg1.data[1] = 0x87;
canMsg1.data[2] = 0x32;
canMsg1.data[3] = 0xFA;
canMsg1.data[4] = 0x26;
canMsg1.data[5] = 0x8E;
canMsg1.data[6] = 0xBE;
canMsg1.data[7] = 0x86;
canMsg2.can_id = 0x222;
canMsg2.can_dlc = 8;
canMsg2.data[0] = 0x0E;
canMsg2.data[1] = 0x00;
canMsg2.data[2] = 0x00;
canMsg2.data[3] = 0x08;
canMsg2.data[4] = 0x01;
canMsg2.data[5] = 0x00;
canMsg2.data[6] = 0x00;
canMsg2.data[7] = 0xA0;
while (!Serial);
Serial.begin(115200);
SPI.begin();
mcp2515.reset();
mcp2515.setBitrate(CAN_500KBPS,MCP_8MHZ);
mcp2515.setNormalMode();
pinMode(buttonPin, INPUT);
}
void loop() {
buttonState = digitalRead(buttonPin); // read the state of the pushbutton value
Serial.println(buttonState); // Show the state of pushbutton on serial monitor
if (buttonState == HIGH)
{ // check if the pushbutton is pressed.
// CAN message1 send:
mcp2515.sendMessage(&canMsg1); }
delay(100);
}
and it really sends the can message ONLY when i push the button (screen shot in attachment).
now i have to see how to make it more reliable (the detection of the pushed button more accurate) i saw somwhere that i should put a delay between reading out the button and executing the function or somthing like that and afterwards it should be better ....or ?
If I were you I would consider sending the message when the button becomes pressed rather than when it is pressed. See the StateChangeDetection example in the IDE and research debouncing of inputs