Having problems blinking an LED on Arduino using information sent over CAN-bus - arduino

I've been messing around with CAN-bus to try and learn the basics so I can use it in a future project. I have 2 arduinos with MCP2515 chips connected that I am sending messages between.
I have been able to wire up the chips and send messages between the arduinos just fine, but when I went to modify the code to blink an LED if the first byte is 0x00 or 0x01 it wont blink. I added print statements to check that it is entering the loop, and it is, using the serial monitor I can see it yeet and yote, but digital pin 3 remains at ~0V.
This is probably more an arduino question than a CAN-bus question but could somebody help me understand why my LED wont blink? The code is entering the loop so it should be processing the command, and I initialized the pin to be an output, but i'm still not getting any blinking.
As a note, the transmitting arduino is sending alternating packets of data, first a packet with 0X01 as the first data byte, then with 0x00 as the first data byte. These data packets are separated by 5000 ms.
I am currently using the CAN library available here https://github.com/autowp/arduino-mcp2515
Code for receiving arduino
#include <SPI.h>
#include <mcp2515.h>
struct can_frame canMsg;
MCP2515 mcp2515(10);
int LED_PIN = 3;
void setup() {
Serial.begin(115200);
SPI.begin();
pinMode(LED_PIN, OUTPUT);
mcp2515.reset();
mcp2515.setBitrate(CAN_125KBPS);
mcp2515.setNormalMode();
Serial.println("------- CAN Read ----------");
Serial.println("ID DLC DATA");
}
void loop() {
if (mcp2515.readMessage(&canMsg) == MCP2515::ERROR_OK) {
Serial.print(canMsg.can_id, HEX); // print ID
Serial.print(" ");
Serial.print(canMsg.can_dlc, HEX); // print DLC
Serial.print(" ");
if(canMsg.data[0] == 0x00){
digitalWrite(LED_PIN,HIGH);
Serial.print("YEET");
}
if(canMsg.data[0] == 0x01){
digitalWrite(LED_PIN,LOW);
Serial.print("YOTE");
}
for (int i = 0; i<canMsg.can_dlc; i++) { // print the data
Serial.print(canMsg.data[i],HEX);
Serial.print(" ");
}
Serial.println();
}
}
and the code for transmitting arduino for completeness
#include <SPI.h>
#include <mcp2515.h>
struct can_frame canMsg1;
struct can_frame canMsg2;
MCP2515 mcp2515(10);
void setup() {
canMsg1.can_id = 0x0F6;
canMsg1.can_dlc = 8;
canMsg1.data[0] = 0x01;
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 = 0x036;
canMsg2.can_dlc = 8;
canMsg2.data[0] = 0x00;
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_125KBPS);
mcp2515.setNormalMode();
Serial.println("Example: Write to CAN");
}
void loop() {
mcp2515.sendMessage(&canMsg1);
delay(5000);
mcp2515.sendMessage(&canMsg2);
Serial.println("Messages sent");
delay(5000);
}

Sorry, i'm an idiot. I forgot that breadboard power lines are not connected all the way down the board. I connected the Arduino to the proper section of the breadboard to receive power and ground, but connected the LED to an unconnected ground pin.

Related

Receiving all zeros in payload sent from nodemcu to Arduino UNO over UART using SerialTransfer library

I have a nodemcu master streaming sensor values to Arduino Uno slave over UART using SerialTransfer.h. I have set up an additional serial port on Arduino digital pins 2, 3 for Rx, Tx using SoftwareSerial.h. I have wired the Tx on nodemcu to Rx on Uno and Rx on nodemcu to Tx on the Uno. I have a level-shifter to adjust for 3.3 V nodemcu and 5 V Arduino. I have made sure to provide a common ground.
I transmit a struct from nodemcu with sensor values (bool and int types, hard-coded for demo) but receive only zero values at the Arduino, as seen with Serial monitor. My code is below. I'd appreciate any inputs.
I have tried the following with no difference.
With and without an extra serial port on Uno created using SoftwareSerial.h
Reversing the set up with Arduino Uno master and nodemcu slave
With and without level-shifter on nodemcu Tx and Arduino Uno Rx
Here is the code for nodemcu master.
#include <Wire.h>
#include <SerialTransfer.h>
SerialTransfer masterMCU;
struct PAYMASTER {
/*
water: instruction to switch pump on or off. Note the float sensor in pump's circuit will prevent overflow.
fan: instruction to control fan speed - LO, MED, HIGH. Note PC fan requires an int between 0 and 255.
led: instruction to control LED brightness. Note that the FastLED library requires an int between 0 and 255.
*/
bool water;
int fan;
int led;
} instructions = {
true,
201,
60
};
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
delay(999);
masterMCU.begin(Serial);
delay(999);
}
void debug() {
Serial.print("MASTER: ");
Serial.print(millis());
Serial.print(" Water: ");
Serial.print(instructions.water);
Serial.print(", Fan: ");
Serial.print(instructions.fan);
Serial.print(", LED: ");
Serial.println(instructions.led);
}
void loop() {
// put your main code here, to run repeatedly:
masterMCU.txObj(instructions, sizeof(instructions));
masterMCU.sendData(sizeof(instructions));
debug();
delay(999);
}
Here is the code for Arduino Uno slave.
#include <Wire.h>
#include <SerialTransfer.h>
#include <SoftwareSerial.h>
SerialTransfer slaveMCU;
SoftwareSerial extra(2, 3); // Rx 2, Tx 3
struct PAYMASTER {
/*
water: instruction to switch pump on or off. Note the float sensor in pump's circuit will prevent overflow.
fan: instruction to control fan speed - LO, MED, HIGH. Note PC fan requires an int between 0 and 255.
led: instruction to control LED brightness. Note that the FastLED library requires an int between 0 and 255.
*/
bool water;
int fan;
int led;
} instructions;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
delay(201);
extra.begin(9600);
delay(201);
slaveMCU.begin(extra);
delay(201);
}
void debug() {
Serial.print("SLAVE: ");
Serial.print(millis());
Serial.print(" Water: ");
Serial.print((bool)instructions.water);
Serial.print(", Fan: ");
Serial.print(instructions.fan);
Serial.print(", LED: ");
Serial.println(instructions.led);
}
void loop() {
// put your main code here, to run repeatedly:
if (slaveMCU.available()) {
slaveMCU.rxObj(instructions, sizeof(instructions));
debug();
} else if (slaveMCU.status < 0) {
Serial.print("ERROR: ");
if(slaveMCU.status == -1)
Serial.println(F("CRC_ERROR"));
else if(slaveMCU.status == -2)
Serial.println(F("PAYLOAD_ERROR"));
else if(slaveMCU.status == -3)
Serial.println(F("STOP_BYTE_ERROR"));
}
delay(999);
}
I made a few changes and data are received with correct values now.
I replaced delay() with millis() in master.
I replaced SerialTransfer::sendData() with SerialTransfer::sendDatum() in master. The former is for streaming multiple objects whereas the latter is for streaming a single object.
I replaced int types with uint8_t in the struct that is sent over wires in both master and slave.
The values are received correctly at Arduino Uno now. None of the changes made any difference until 3. above. I have retained the other changes as they also appear important to the result. Here is the final code that works for correct transmission and reception of objects from nodemcu master to Arduino Uno slave.
nodemcu master:
#include <Wire.h>
#include <SerialTransfer.h>
SerialTransfer masterMCU;
unsigned long tic = millis();
unsigned long toc = tic;
#define DELTA 1000
struct PAYMASTER {
/*
water: instruction to switch pump on or off. Note the float sensor in pump's circuit will prevent overflow.
fan: instruction to control fan speed - LO, MED, HIGH. Note PC fan requires an int between 0 and 255.
led: instruction to control LED brightness. Note that the FastLED library requires an int between 0 and 255.
*/
bool water;
uint8_t fan;
uint8_t led;
} instructions = {
true,
201,
60
};
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
delay(999);
masterMCU.begin(Serial);
delay(999);
}
void debug() {
Serial.print("MASTER: ");
Serial.print(millis());
Serial.print(" Water: ");
Serial.print(instructions.water);
Serial.print(", Fan: ");
Serial.print(instructions.fan);
Serial.print(", LED: ");
Serial.println(instructions.led);
}
void loop() {
// put your main code here, to run repeatedly:
toc = millis();
if ((toc - tic) > DELTA) {
masterMCU.txObj(instructions, sizeof(instructions));
masterMCU.sendDatum(instructions), sizeof(instructions);
debug();
tic = toc;
}
}
Arduino Uno slave:
#include <Wire.h>
#include <SerialTransfer.h>
#include <SoftwareSerial.h>
SerialTransfer slaveMCU;
SoftwareSerial Extra(2, 3); // Rx: 2, Tx: 3
unsigned long tic = millis();
unsigned long toc = tic;
struct PAYMASTER {
/*
water: instruction to switch pump on or off. Note the float sensor in pump's circuit will prevent overflow.
fan: instruction to control fan speed - LO, MED, HIGH. Note PC fan requires an int between 0 and 255.
led: instruction to control LED brightness. Note that the FastLED library requires an int between 0 and 255.
*/
bool water;
uint8_t fan;
uint8_t led;
} instructions;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
delay(201);
Extra.begin(9600);
delay(201);
slaveMCU.begin(Extra);
delay(201);
}
void debug() {
Serial.print("SLAVE: ");
Serial.print(millis());
Serial.print(" Water: ");
Serial.print((bool)instructions.water);
Serial.print(", Fan: ");
Serial.print(instructions.fan);
Serial.print(", LED: ");
Serial.println(instructions.led);
}
void loop() {
// put your main code here, to run repeatedly:
if (slaveMCU.available()) {
slaveMCU.rxObj(instructions);
debug();
} else if (slaveMCU.status < 0) {
Serial.print("ERROR: ");
if(slaveMCU.status == -1)
Serial.println(F("CRC_ERROR"));
else if(slaveMCU.status == -2)
Serial.println(F("PAYLOAD_ERROR"));
else if(slaveMCU.status == -3)
Serial.println(F("STOP_BYTE_ERROR"));
}
}

Attiny85 EEPROM erase, after power lost

my Attiny85 losts the whole EEPROM data, if I turn the power of.
I use the Arduino IDE and I'm sure, that The EEPROM was wrote, because I get Serial feedback. Here my code:
#include <EEPROM.h>
#include <SoftwareSerial.h>
SoftwareSerial SSerial(0, 1);
int addr = 0;
uint8_t val = 2;
void setup()
{
SSerial.begin(9600);
}
void loop()
{
EEPROM.write(addr, val);
delay(100);
uint8_t value = EEPROM.read(addr);
SSerial.print(addr);
SSerial.print("\t");
SSerial.print(value, DEC);
SSerial.println();
addr = addr + 1;
if (addr == 512)
while(1);
}
Thank you :)
Programming through ISP SPI erases eeprom (all values become 0xFF) by default but seems this feature can be setup in programmer settings. Programming through bootloader do not erase eeprom.
Thank you #Vladimir Tsykunov

Unable to receive correct data using i2c serial communication between two Arduino

I'm using an i2c serial bus for communication between two Arduino (Uno = Master, Due = Slave) and I'm currently experiencing problems while reading data received by the slave.
The master sends some data using Wire.write(command). The slave receives it and the handler function receiveEvent(int howMany) is called thanks the instruction Wire.onReceive(receiveEvent).
Here is the simplified code for the serial communication:
Master's Sketch
#include <Wire.h>
void setup() {
Wire.begin();
Serial.begin(9600);
}
void loop() {
Wire.beginTransmission(8);
byte command[] = {2, 5, 3};
Wire.write(command, 3);
Wire.endTransmission();
Serial.println("command sent...");
delay(1000);
}
Slave's Sketch
#include <Wire.h>
int c = 0;
void setup() {
Serial.begin(9600);
Wire.begin(8);
Wire.onReceive(receiveEvent);
}
void loop() {
delay(1000);
}
void receiveEvent(int howManyBytes){
for(int iter=0; iter<howMany; iter++){
c = Serial.read();
Serial.print("c : ");
Serial.println(c);
}
}
Slave's Output
c : -1
c : -1
c : -1
It appears that three bytes are received but the data are not transmitted correctly. Any idea were there could be a mistake or a bug? Thanks!
Since you expect the data from the Wire, I think your slave should receive the data via Wire.read() instead of Serial.read().

TWO RFID READERS and ARDUINO MEGA, only one reader will read

I am trying to run 2 rfid readers (RDM 630) in an Arduino Mega 2560. I just can't figure it out why only one reader will read and the other won't. (The readers are both functional).
#include <SoftwareSerial.h>
SoftwareSerial Reader1(50, 51);
SoftwareSerial Reader2(52, 53);// RX and TX
int rfid, i;
char newtag[14];
void setup()
{
Reader1.begin(9600); // start serial to RFID reader
Reader2.begin(9600);
Serial.begin(9600); // start serial to PC
}
void loop()
{
if (Reader1.available() > 0)
{
Serial.println();
Serial.println();
Serial.println("Reading RFID Tag...");
delay(100);
for (i=0; i < 13; i++)
{
rfid = Reader1.read();
newtag[i]=rfid;
}
Reader1.flush();
Serial.print("RFID Tag No:");
Serial.print(newtag);
}
if (Reader2.available() > 0)
{
Serial.println();
Serial.println();
Serial.println("Reading RFID Tag...");
delay(100);
for (i=0; i < 13; i++)
{
rfid = Reader2.read();
newtag[i]=rfid;
}
Reader2.flush();
Serial.print("RFID Tag No:");
Serial.print(newtag);
}
}
SofwareSerial has shared resources so needs a little extra thought on implementation. When you initialise a device it is the listening device. If you initialise another the listening device changes. You need to put:
Reader1.listen();
Before your Reader1 code and switch again for your Reader2 code.
See this for example code: http://arduino.cc/en/Tutorial/TwoPortReceive
However, you say you have a Mega. Why not use the multiple serials you have onboard? Your code base will be smaller and the coding is cleaner. http://arduino.cc/en/Tutorial/MultiSerialMega
After around million of trying and trying I discovered that the correct way to connect 4 RFID RC522 is to put them in the same line on test board except SS pins and the code as usual is ReadUidMultiReader from RFID library like this :

How can I get rid of error: 'SerialUSB' was not declared in this scope in my Arduino Sketch?

The code is below, slightly modified from a tutorial. I am working on a Teensy3.1. I added #include <SoftwareSerial.h> but it did not help. I also tried SerialUSB.begin(9600); instead of WiredSerial.begin(9600); //use native port on Due
#include <SoftwareSerial.h>
//minimal sketch for connection to ADS129n family. Load this script and open Tools/SerialMonitor.
//You should see text like this
// Device Type (ID Control Register): 62 Channels: 8
//If you see "Channels: 0" then check your wiring
#include "ads1298.h"
#include "adsCMD.h"
#include <Arduino.h>
#include <SPI.h> // include the SPI library:
int gMaxChan = 0; //maximum number of channels supported by ads129n = 4,6,8
int gIDval = 0; //Device ID : lower 5 bits of ID Control Register
int activeSerialPort = 0; //data will be sent to serial port that last sent commands. E.G. bluetooth or USB port
const int kPIN_LED = 13;//pin with in-built light - typically 13, 11 for Teensy 2.0.
#if defined(__SAM3X8E__)
#define isDUE //Detect Arduino Due
#define WiredSerial SerialUSB //Use Due's Native port
#else
#define WiredSerial Serial
#endif
void setup(){
using namespace ADS1298;
//prepare pins to be outputs or inputs
//pinMode(PIN_SCLK, OUTPUT); //optional - SPI library will do this for us
//pinMode(PIN_DIN, OUTPUT); //optional - SPI library will do this for us
//pinMode(PIN_DOUT, INPUT); //optional - SPI library will do this for us
pinMode(IPIN_CS, OUTPUT);
pinMode(PIN_START, OUTPUT);
pinMode(IPIN_DRDY, INPUT);
//pinMode(PIN_CLKSEL, OUTPUT);//*optional
//pinMode(IPIN_RESET, OUTPUT);//*optional
//pinMode(IPIN_PWDN, OUTPUT);//*optional
//start small peripheral interface
SPI.begin();
SPI.setBitOrder(MSBFIRST);
#ifndef isDUE
SPI.setClockDivider(SPI_CLOCK_DIV4); //http://forum.pjrc.com/threads/1156-Teensy-3-SPI-Basic-Clock-Questions
#endif
SPI.setDataMode(SPI_MODE1);
//Start ADS1298
delay(500); //wait for the ads129n to be ready - it can take a while to charge caps
adc_send_command(SDATAC); // Send SDATAC Command (Stop Read Data Continuously mode)
delay(10);
// Determine model number and number of channels available
gIDval = adc_rreg(ID); //lower 5 bits of register 0 reveal chip type
switch (gIDval & B00011111 ) { //least significant bits reports channels
case B10000: //16
gMaxChan = 4; //ads1294
break;
case B10001: //17
gMaxChan = 6; //ads1296
break;
case B10010: //18
gMaxChan = 8; //ads1298
break;
case B11110: //30
gMaxChan = 8; //ads1299
break;
default:
gMaxChan = 0;
}
//start serial port
SerialUSB.begin(9600); //use native port on Due
//WiredSerial.begin(9600); //use native port on Due
while (WiredSerial.read() >= 0) {} //http://forum.arduino.cc/index.php?topic=134847.0
//while (!WiredSerial) ; //required by Leonardo http://arduino.cc/en/Serial/IfSerial (ads129n requires 3.3v signals, Leonardo is 5v)
delay(200); // Catch Due reset problem
pinMode(kPIN_LED, OUTPUT);
}
void loop()
{
WiredSerial.print("Device Type (ID Control Register): "); SerialUSB.print(gIDval); SerialUSB.print(" Channels: "); SerialUSB.println(gMaxChan);
digitalWrite(kPIN_LED, HIGH); // turn the LED on (HIGH is the voltage level)
if (gMaxChan > 0)
delay(500); //long pause if OK
else
delay(50); //rapid blink if error
digitalWrite(kPIN_LED, LOW); // turn the LED off by making the voltage LOW
delay(500);
}
Try using Serial instead of SerialUSB, I've tried it while using Arduino UNO.

Resources