Hi,
I am trying to use the MKR MEM Shield with Arduino Nano Every. This is the code that I am trying to run
#include <SPI.h>
#include <string.h>
#include <CSV_Parser.h>
#include <SD.h>
#define CAN_2515
#if defined(SEEED_WIO_TERMINAL) && defined(CAN_2518FD)
const int SPI_CS_PIN = BCM8;
const int CAN_INT_PIN = BCM25;
#else
const int SPI_CS_PIN = 10; //Arduino MKR Shield = 3, Arduino Nano Every = 10
const int CAN_INT_PIN = 2; //Arduino MKR Shield = 7, Arduino Nano Every = 2
#endif
#ifdef CAN_2518FD
#include "mcp2518fd_can.h"
mcp2518fd CAN(SPI_CS_PIN);
#endif
#ifdef CAN_2515
#include "mcp2515_can.h"
mcp2515_can CAN(SPI_CS_PIN);
#endif
char *to_find_list[] = {"BMS_HvBus1_Tract_OnFb_bool", "BMS_HvBus2_Chrg_OnFb_bool", "BMS_HvBus3_Anc_OnFb_bool", "BMS_HvBus4_Null_OnFb_bool", "BMS_HvBus5_Null_OnFb_bool", "BMS_Status_enum", "BMS_IsolVal_kohm"};
int x[sizeof(to_find_list) / sizeof(to_find_list[0])];
int ignitionPin = A0;
int physVals[sizeof(to_find_list) / sizeof(to_find_list[0])];
int led_red = 3; //define red pin
int led_green = 5; //define green pin
int led_blue = 6; //define blue pin
int condition;
const int chipSelect = 8;
File myFile;
int rows_count;
char **names;
uint16_t *startbits;
uint16_t *lengths;
int16_t *initial_values;
float *factors;
int16_t *offsets;
char **units;
int32_t *message_ids;
void setup() {
pinMode(chipSelect, OUTPUT);
pinMode(led_red, OUTPUT);
pinMode(led_green, OUTPUT);
pinMode(led_blue, OUTPUT);
Serial.begin(115200);
delay(5000);
int voltageValue = analogRead(ignitionPin);
Serial.print("Initializing SD card...");
if (!SD.begin(chipSelect)) {
Serial.println("Card failed, or not present");
while (1);
}
Serial.print("card initialized...");
CSV_Parser cp("s--udud--dfd--s--ux---", true, ';');
if (cp.readSDfile("/DBC_3.csv")) {
Serial.print(F("Reading file..."));
names = (char**)cp["Name"];
startbits = (uint16_t*)cp["Startbit"];
lengths = (uint16_t*)cp["Length [Bit]"];
initial_values = (int16_t*)cp["Initial Value"];
factors = (float*)cp["Factor"];
offsets = (int16_t*)cp["Offset"];
units = (char**)cp["Unit"];
message_ids = (int32_t*)cp["Message ID"];
rows_count = cp.getRowsCount();
}
else {
Serial.println("ERROR: File called '/DBC_3.csv' does not exist...");
}
while (CAN_OK != CAN.begin(CAN_500KBPS)) { // init can bus : baudrate = 500k
Serial.println("CAN init fail, retry...");
delay(100);
}
Serial.println("CAN init ok!");
for (int i = 0; i < sizeof(x) / sizeof(x[0]); i++) {
Serial.println();
Serial.print(to_find_list[i]);
Serial.println();
x[i] = searcher(to_find_list[i]);
}
}
void loop() {
unsigned char dlc = 0; unsigned char canData[8]; unsigned char data[8][8]; unsigned int byteData[64] = {0}; int voltageVal = analogRead(ignitionPin);
voltageVal = 1;
if (voltageVal > 0) {
condition = 1;
if (CAN_MSGAVAIL == CAN.checkReceive()) { // Check if data coming
CAN.readMsgBuf(&dlc, canData); // Read data, dlc: DLC, data: CAN data
unsigned long canId = CAN.getCanId();
Serial.println("-----------------------------");
Serial.print("Get data from ID: 0x");
Serial.println(canId, HEX);
for(int i = 0; i < sizeof(x) / sizeof(x[0]); i++) {
unsigned int index = x[i];
if (message_ids[index] == canId) { //If canIds are equal to canIds of stored signal names in to_find_list[]
unsigned int sb = startbits[index]; unsigned int len = lengths[index]; int initVal = initial_values[index]; int factor = factors[index]; int offset = offsets[index];
for (int i = 0; i < dlc; i++) { //This for loop converts the whole data into binary format
int* binNum = decToBin(canData[i]); //Each byte of canData is converted to binary number and stored
for (int j = 0; j < 8; j++) {
data[i][j] = binNum[j]; //Binary number is stored in a multidimensional array
}
Serial.print(canData[i], HEX);
Serial.print("\t");
}
if ((sb + len) % 8 != 0) { //If startbits + length > the byte size, we will have to take the next byte into consideration
int index_byte = 0;
for (int j = (sb + len) / 8; j >= (int)(sb / 8); j--) { //Extract the necessary bytes
for (int k = 0; k < 8; k++) {
byteData[index_byte++] = data[j][k];
}
}
}
else { //If startbits + length is divisible by 8
int index_byte = 0;
for (int j = ((sb + len) / 8) - 1; j >= (int)(sb / 8); j--) { //Extract the necessary bytes
for (int k = 0; k < 8; k++) {
byteData[index_byte++] = data[j][k];
}
}
}
int size = 0;
if ((sb + len) % 8 != 0) {
size = ((len / 8) + 1) * 8;
}
else {
size = len;
}
int to = size - 1 - (sb % 8) - len; int from = size - 1 - (sb % 8); unsigned int bitData[len] = {0}; int j = 0;
for (int i = from; i > to; i--) { //Extract the data according to the bit length
bitData[j++] = byteData[i];
}
int size2 = sizeof(bitData) / sizeof(bitData[0]); int rawVal = binTodec(bitData, size2); int physVal;
Serial.println();
Serial.print("Decimal value of extracted data: ");
Serial.print(rawVal); //Convert the extracted bits to decimal format and print
Serial.println();
physVal = offset + (factor * rawVal); //Apply offset and scale to the raw value to get the physical value
Serial.print("Name = ");
Serial.print(to_find_list[i]);
Serial.println();
Serial.print("Binary: ");
for (int i = 0; i < (int)(sizeof (bitData) / sizeof (bitData[0])); i ++) {
Serial.print(bitData[i]);
}
Serial.println();
Serial.print("Physical value = ");
physVals[i] = physVal;
Serial.print(physVals[i]); // Print the physical value
Serial.println();
}
}
if (physVals[5] == 5) {
Serial.print("Ignition off! ");
Serial.println();
condition = 0; //Lights off
}
else if (physVals[5] == 50) {
Serial.print("Fault! ");
Serial.println();
condition = 3; //Red
}
else if (physVals[5] == 20) {
Serial.print("HV active!");
Serial.println();
condition = 2; //Orange
}
else {
Serial.print("Ignition on! ");
condition = 1; //Green
if (physVals[0] == 1 || physVals[1] == 1 || physVals[2] == 1) {
Serial.print("Contactors closed! ");
Serial.println();
condition = 2; //Orange
}
else {
Serial.print("Contactors open! ");
condition = 1; //Green
if (physVals[6] < 48) {
Serial.print(physVals[6]);
Serial.print("Isolation value < 48 kohm! System not isolated! Fault detected!");
Serial.println();
condition = 3; //Red
}
else {
Serial.print("System isolated!");
Serial.println();
condition = 1; //Green
}
}
}
}
else {
Serial.print("CAN Messages Unavailable!");
Serial.println();
condition = 3;
}
}
else {
Serial.print("Ignition off! ");
Serial.println();
condition = 0; //No colour
}
updateLEDs(condition);
}
int searcher(char *to_find) {
for(int i = 0; i < rows_count; i++) {
if (strcmp(names[i], to_find) == 0) {
return i;
}
}
}
int* decToBin (int decimalNumber) {
static int binaryNumber[8];
for (int i = 7; i >= 0; i--) {
binaryNumber[i] = decimalNumber % 2;
decimalNumber = decimalNumber / 2;
}
return binaryNumber;
}
int binTodec (unsigned int binaryNumber[], int size) {
unsigned int decimalNumber = 0;
for (int i = size - 1; i >= 0 ; i--) {
decimalNumber += binaryNumber[i] * (int)(pow(2, i));
}
return decimalNumber;
}
void showColor(byte r, byte g, byte b) {
//Byte values for range 0-255
analogWrite(led_red, r);
analogWrite(led_green, g);
analogWrite(led_blue, b);
}
void updateLEDs(int condition) {
if (condition == 0) {
//Always delay 5 minutes before switching off
showColor(0, 0, 0); // No colour
}
else if (condition == 1) {
showColor(0, 255, 0); // Green
}
else if (condition == 2) {
showColor(255, 127, 0); // Orange
}
else {
showColor(255, 0, 0); // Red
}
}
The output for above code
Initializing SD card...card initialized...R�
The code runs perfectly with some modication on MKR Wifi 1010. But not on Nano Every. I have checked the wiring and it is fine. The CardInfo.ino example from the SD library works perfectly with MKR Mem shield and Nano Every.
/*
SD card test
This example shows how use the utility libraries on which the'
SD library is based in order to get info about your SD card.
Very useful for testing a card when you're not sure whether its working or not.
The circuit:
SD card attached to SPI bus as follows:
** MOSI - pin 11 on Arduino Uno/Duemilanove/Diecimila
** MISO - pin 12 on Arduino Uno/Duemilanove/Diecimila
** CLK - pin 13 on Arduino Uno/Duemilanove/Diecimila
** CS - depends on your SD card shield or module.
Pin 4 used here for consistency with other Arduino examples
created 28 Mar 2011
by Limor Fried
modified 9 Apr 2012
by Tom Igoe
*/
// include the SD library:
#include <SPI.h>
#include <SD.h>
// set up variables using the SD utility library functions:
Sd2Card card;
SdVolume volume;
SdFile root;
// change this to match your SD shield or module;
// Arduino Ethernet shield: pin 4
// Adafruit SD shields and modules: pin 10
// Sparkfun SD shield: pin 8
// MKRZero SD: SDCARD_SS_PIN
const int chipSelect = 8;
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
Serial.print("\nInitializing SD card...");
// we'll use the initialization code from the utility libraries
// since we're just testing if the card is working!
if (!card.init(SPI_HALF_SPEED, chipSelect)) {
Serial.println("initialization failed. Things to check:");
Serial.println("* is a card inserted?");
Serial.println("* is your wiring correct?");
Serial.println("* did you change the chipSelect pin to match your shield or module?");
while (1);
} else {
Serial.println("Wiring is correct and a card is present.");
}
// print the type of card
Serial.println();
Serial.print("Card type: ");
switch (card.type()) {
case SD_CARD_TYPE_SD1:
Serial.println("SD1");
break;
case SD_CARD_TYPE_SD2:
Serial.println("SD2");
break;
case SD_CARD_TYPE_SDHC:
Serial.println("SDHC");
break;
default:
Serial.println("Unknown");
}
// Now we will try to open the 'volume'/'partition' - it should be FAT16 or FAT32
if (!volume.init(card)) {
Serial.println("Could not find FAT16/FAT32 partition.\nMake sure you've formatted the card");
while (1);
}
Serial.print("Clusters: ");
Serial.println(volume.clusterCount());
Serial.print("Blocks x Cluster: ");
Serial.println(volume.blocksPerCluster());
Serial.print("Total Blocks: ");
Serial.println(volume.blocksPerCluster() * volume.clusterCount());
Serial.println();
// print the type and size of the first FAT-type volume
uint32_t volumesize;
Serial.print("Volume type is: FAT");
Serial.println(volume.fatType(), DEC);
volumesize = volume.blocksPerCluster(); // clusters are collections of blocks
volumesize *= volume.clusterCount(); // we'll have a lot of clusters
volumesize /= 2; // SD card blocks are always 512 bytes (2 blocks are 1KB)
Serial.print("Volume size (Kb): ");
Serial.println(volumesize);
Serial.print("Volume size (Mb): ");
volumesize /= 1024;
Serial.println(volumesize);
Serial.print("Volume size (Gb): ");
Serial.println((float)volumesize / 1024.0);
Serial.println("\nFiles found on the card (name, date and size in bytes): ");
root.openRoot(volume);
// list all files in the card with date and size
root.ls(LS_R | LS_DATE | LS_SIZE);
}
void loop(void) {
}
The output for CardInfo.ino
Initializing SD card...Wiring is correct and a card is present.
Card type: SDHC
Clusters: 485936
Blocks x Cluster: 64
Total Blocks: 31099904
Volume type is: FAT32
Volume size (Kb): 15549952
Volume size (Mb): 15185
Volume size (Gb): 14.83
Files found on the card (name, date and size in bytes):
SYSTEM~1/ 2024-07-16 09:40:40
WPSETT~1.DAT 2024-07-16 09:40:40 12
INDEXE~1 2024-07-16 09:40:40 76
DBC_2.TXT 2024-07-16 10:33:08 35631
DBC_1.TXT 2024-07-16 10:33:08 35819
DBC.TXT 2024-07-16 11:34:28 39302
DBC_AQ~1.CSV 2024-07-16 10:33:08 5411
DBC_BM~1.CSV 2024-07-16 11:34:26 42983
DBC_BM~2.CSV 2024-07-16 11:34:34 38013
DBC_VS~1.CSV 2024-07-16 10:33:08 39309
DBC_VS~2.CSV 2024-07-16 10:33:08 39309
NAMES.TXT 2000-01-01 01:00:00 5361
TEST.TXT 2000-01-01 01:00:00 260
DBC_3.CSV 2024-07-16 14:47:08 38242
I think the problem lies with Serial port or program memory. How do I make this code work?