Go Down

Topic: CAN Bus on Arduino M0 pro (Read 281 times) previous topic - next topic

arduino_solrac

Sep 17, 2019, 01:20 am Last Edit: Sep 29, 2019, 04:17 pm by arduino_solrac
I am working on add CAN-Bus to my Arduino M0, but the pins D11, D12 does not work

https://store.arduino.cc/usa/arduino-m0



Arduino need the following pins to start CAN BUs with the MCP2515 chip:

Pin  Arduino 'Pin' SERCOM
-----------------------------------------
PA18  D10 SERCOM1.2   CS
PA16  D11 SERCOM1.0   MISO
PA19  D12 SERCOM1.3   MOSI
PA17  D13 SERCOM1.1   SCK
 

Following is the sketch:


#include <SPI.h>
#include <wiring_private.h> // pinPeripheral() function
#define CSPIN 10
#define Time 25

//D12-MISO, D11-MOSI, D13-SCK
SPIClass SPI2 (&sercom1, 12, 13, 11, SPI_PAD_0_SCK_1, SERCOM_RX_PAD_3);
             

int i = 0;
void setup() {
  // put your setup code here, to run once:

  //Get all pins and SPI ports setup
  SPI2.begin();
  pinPeripheral(12, PIO_SERCOM_ALT);
  pinPeripheral(11, PIO_SERCOM_ALT);
  pinPeripheral(13, PIO_SERCOM);
  pinMode(CSPIN, OUTPUT);
  digitalWrite(CSPIN, HIGH); //make sure it is high to start
  SPI2.setClockDivider(SPI_CLOCK_DIV128); //Slow down the master a bit

  //Reset the screen, set backlight, etc.
  digitalWrite(CSPIN, LOW);// Select the screen before sending
  SPI2.transfer('|');//Setting character
  SPI2.transfer('-');//Clear display
  SPI2.transfer('|');//Put LCD into setting mode
  SPI2.transfer(158 + 0); //Set green backlight amount to 0%
  SPI2.transfer('|');//Put LCD into setting mode
  SPI2.transfer(188 + 10); //Set blue backlight amount to 0%
  SPI2.transfer('|');//Put LCD into setting mode
  SPI2.transfer(128 + 5); //Set white/red backlight amount to (15=51% 100%=+29)
  delay(Time);
  digitalWrite(CSPIN, HIGH);// Deselect the screen after sending
  delay(1000);//Each setting change prints an output, this delay allows them to be printed before trying to keep going

  //Send Welcome Text
  char tempString[50]; //Needs to be large enough to hold the entire string with up to 5 digits
  sprintf(tempString, "Welcome ");
  spiSendString(tempString);
  delay(1500);
}

void loop() {   
  // put your main code here, to run repeatedly:

  //Clear the screen, then send the Counting string
  digitalWrite(CSPIN, LOW);// Select the screen before sending
  SPI2.transfer('|');//Setting character
  SPI2.transfer('-');//Clear display
  delay(Time);
  digitalWrite(CSPIN, HIGH);// Deselect the screen after sending
  char tempString[50]; //Needs to be large enough to hold the entire string with up to 5 digits
  sprintf(tempString,"Counting: %d ", i);
  spiSendString(tempString);
  i++;
  delay(1000-Time);

}

//Sends a string over SPI
void spiSendString(char* data)
{
  digitalWrite(CSPIN, LOW); //Drive the CS pin low to select OpenLCD
  for(byte x = 0 ; data
!= '\0' ; x++) //Send chars until we hit the end of the string

    SPI2.transfer(data
);

  digitalWrite(CSPIN, HIGH); //Release the CS pin to de-select OpenLCD
}

Nothing happens on pins D11 and D12, any idea to help ?

Juraj

https://forum.arduino.cc/index.php?topic=630415.0

arduino_solrac

 As I said on my post, this step did not work with the Arduino M0 pro.

That is why, I am asking help for a procedure that could work on an Arduino M0 pro board.

Juraj

As I said on my post, this step did not work with the Arduino M0 pro.

That is why, I am asking help for a procedure that could work on an Arduino M0 pro board.
I write about errors in the tutorial in that comment. did you  read it?

pert

I've deleted your other cross post arduino_solrac.

Cross posting is against the rules of the forum. The reason is that duplicate posts can waste the time of the people trying to help. Someone might spend 15 minutes writing a detailed answer on this thread, without knowing that someone else already did the same in the other thread.

Repeated cross posting will result in a suspension from the forum.

In the future, please take some time to pick the forum section that best suits the topic of your question and then only post once to that forum section. This is basic forum etiquette, as explained in the sticky "How to use this forum - please read." post you will find at the top of every forum section. It contains a lot of other useful information. Please read it.

Thanks in advance for your cooperation.

arduino_solrac

Thanks for the attention !!!

arduino_solrac


Following is the scketch on the send board and also for the receive board.

Hardware:

Arduino M0 pro and a MCP2515 module



receive board
// demo: CAN-BUS Shield, receive data with interrupt mode, and set mask and filter
//
// when in interrupt mode, the data coming can't be too fast, must >20ms, or else you can use check mode
// loovee, 2014-7-8

#include <SPI.h>
#include "mcp_can.h"
#include "wiring_private.h" // pinPeripheral() function
#define chipSelectPin 10
//D12-MISO, D11-MOSI, D13-SCK
SPIClass mySPI (&sercom1, 12, 13, 11, SPI_PAD_0_SCK_1, SERCOM_RX_PAD_3);


MCP_CAN CAN(chipSelectPin);                                    // Set CS pin


unsigned char flagRecv = 0;
unsigned char len = 0;
unsigned char buf[8];
char str[20];

void setup()
{
   
    SerialUSB.begin(115200);
    delay(1000);
   
     mySPI.begin();
  pinPeripheral(12, PIO_SERCOM_ALT);
  pinPeripheral(11, PIO_SERCOM_ALT);
  pinPeripheral(13, PIO_SERCOM);
  pinMode(chipSelectPin, OUTPUT);
  digitalWrite(chipSelectPin, HIGH); //make sure it is high to start
  mySPI.setClockDivider(SPI_CLOCK_DIV128); //Slow down the master a bit

    Repet:
   
    while (CAN_OK == CAN.begin(MCP_STDEXT, CAN_1000KBPS, MCP_8MHZ))             // init can bus : baudrate = 500k
    {
        SerialUSB.println("CAN BUS Shield init fail");
        SerialUSB.println(" Init CAN BUS Shield again");
         delay(2000);
         goto Repet;
    }
    SerialUSB.println("CAN BUS Shield init ok!");
    delay(2000);

    attachInterrupt(0, MCP2515_ISR, FALLING); // start interrupt


    /*
     * set mask, set both the mask to 0x3ff
     */
    CAN.init_Mask(0, 0, 0x3ff);                         // there are 2 mask in mcp2515, you need to set both of them
    CAN.init_Mask(1, 0, 0x3ff);


    /*
     * set filter, we can receive id from 0x04 ~ 0x09
     */
    CAN.init_Filt(0, 0, 0x04);                          // there are 6 filter in mcp2515
    CAN.init_Filt(1, 0, 0x05);                          // there are 6 filter in mcp2515

    CAN.init_Filt(2, 0, 0x06);                          // there are 6 filter in mcp2515
    CAN.init_Filt(3, 0, 0x07);                          // there are 6 filter in mcp2515
    CAN.init_Filt(4, 0, 0x08);                          // there are 6 filter in mcp2515
    CAN.init_Filt(5, 0, 0x09);                          // there are 6 filter in mcp2515

SerialUSB.println("Set Filter ok!!!");
    delay(2000);

}


void MCP2515_ISR()
{
    flagRecv = 1;
}

void loop()
{
   
     if(flagRecv)                   // check if get data
    {

       flagRecv = 1;                // clear flag
             
       
        CAN.readMsgBuf(&len, buf);    // read data,  len: data length, buf: data buf

        SerialUSB.println("\r\n------------------------------------------------------------------");
        SerialUSB.print("Get Data From id: ");
        SerialUSB.println(CAN.getCanId());
        for(int i = 0; i<len; i++)    // print the data
        {
            SerialUSB.print("0x");
            SerialUSB.print(buf, HEX);
            SerialUSB.print("\t");
        }
        SerialUSB.println("Msg ok");
        delay(2000);

    }
}

/*********************************************************************************************************
  END FILE
*********************************************************************************************************/



send board
// demo: set_mask_filter_send
// this demo will show you how to use mask and filter
#include <SPI.h>
#include "mcp_can.h"
#include "wiring_private.h" // pinPeripheral() function
#define chipSelectPin 10

//D12-MISO, D11-MOSI, D13-SCK
SPIClass mySPI (&sercom1, 12, 13, 11, SPI_PAD_0_SCK_1, SERCOM_RX_PAD_3);



MCP_CAN CAN(chipSelectPin);                                    // Set CS pin

void setup()
{
    SerialUSB.begin(115200);
    delay(1000);
   
     mySPI.begin();
  pinPeripheral(12, PIO_SERCOM_ALT);
  pinPeripheral(11, PIO_SERCOM_ALT);
  pinPeripheral(13, PIO_SERCOM);
  pinMode(chipSelectPin, OUTPUT);
  digitalWrite(chipSelectPin, HIGH); //make sure it is high to start
  mySPI.setClockDivider(SPI_CLOCK_DIV128); //Slow down the master a bit
 
    Repet:

    while (CAN_OK == CAN.begin(MCP_STDEXT, CAN_125KBPS, MCP_8MHZ))              // init can bus : baudrate = 500k
    {
        SerialUSB.println("CAN BUS Shield init fail");
        SerialUSB.println(" Init CAN BUS Shield again");
        delay(2000);
        goto Repet;
    }
    SerialUSB.println("CAN BUS Shield init ok!");
    delay(2000);
}

unsigned char stmp[8] = {0, 1, 2, 3, 4, 5, 6, 7};

void loop()
{
    for(int id=0; id<10; id++)
    {
        memset(stmp, id, sizeof(stmp));                 // set id to send data buff
        CAN.sendMsgBuf(id, 0, sizeof(stmp), stmp);
        SerialUSB.println(id, HEX);
        delay(2000);
    }
}

/*********************************************************************************************************
  END FILE
*********************************************************************************************************/

arduino_solrac


I am working on add CAN-Bus to my Arduino M0, but the pins D11, D12 does not work

https://store.arduino.cc/usa/arduino-m0

Arduino need the following pins to start CAN BUs with the MCP2515 chip
Pin  Arduino 'Pin' SERCOM
-----------------------------------------
PA18  D10 SERCOM1.2   CS
PA16  D11 SERCOM1.0   MISO
PA19  D12 SERCOM1.3   MOSI
PA17  D13 SERCOM1.1   SCK
 

Following is the sketch:


#include <SPI.h>
#include <wiring_private.h> // pinPeripheral() function
#define CSPIN 10
#define Time 25

//D12-MISO, D11-MOSI, D13-SCK
SPIClass SPI2 (&sercom1, 12, 13, 11, SPI_PAD_0_SCK_1, SERCOM_RX_PAD_3);
             

int i = 0;
void setup() {
  // put your setup code here, to run once:

  //Get all pins and SPI ports setup
  SPI2.begin();
  pinPeripheral(12, PIO_SERCOM_ALT);
  pinPeripheral(11, PIO_SERCOM_ALT);
  pinPeripheral(13, PIO_SERCOM);
  pinMode(CSPIN, OUTPUT);
  digitalWrite(CSPIN, HIGH); //make sure it is high to start
  SPI2.setClockDivider(SPI_CLOCK_DIV128); //Slow down the master a bit

  //Reset the screen, set backlight, etc.
  digitalWrite(CSPIN, LOW);// Select the screen before sending
  SPI2.transfer('|');//Setting character
  SPI2.transfer('-');//Clear display
  SPI2.transfer('|');//Put LCD into setting mode
  SPI2.transfer(158 + 0); //Set green backlight amount to 0%
  SPI2.transfer('|');//Put LCD into setting mode
  SPI2.transfer(188 + 10); //Set blue backlight amount to 0%
  SPI2.transfer('|');//Put LCD into setting mode
  SPI2.transfer(128 + 5); //Set white/red backlight amount to (15=51% 100%=+29)
  delay(Time);
  digitalWrite(CSPIN, HIGH);// Deselect the screen after sending
  delay(1000);//Each setting change prints an output, this delay allows them to be printed before trying to keep going

  //Send Welcome Text
  char tempString[50]; //Needs to be large enough to hold the entire string with up to 5 digits
  sprintf(tempString, "Welcome ");
  spiSendString(tempString);
  delay(1500);
}

void loop() {   
  // put your main code here, to run repeatedly:

  //Clear the screen, then send the Counting string
  digitalWrite(CSPIN, LOW);// Select the screen before sending
  SPI2.transfer('|');//Setting character
  SPI2.transfer('-');//Clear display
  delay(Time);
  digitalWrite(CSPIN, HIGH);// Deselect the screen after sending
  char tempString[50]; //Needs to be large enough to hold the entire string with up to 5 digits
  sprintf(tempString,"Counting: %d ", i);
  spiSendString(tempString);
  i++;
  delay(1000-Time);

}

//Sends a string over SPI
void spiSendString(char* data)
{
  digitalWrite(CSPIN, LOW); //Drive the CS pin low to select OpenLCD
  for(byte x = 0 ; data
  • != '\0' ; x++) //Send chars until we hit the end of the string

    SPI2.transfer(data
  • );

  digitalWrite(CSPIN, HIGH); //Release the CS pin to de-select OpenLCD
}

Nothing happens on pins D11 and D12, any idea to help ?

Juraj

I am working on add CAN-Bus to my Arduino M0, but the pins D11, D12 does not work

https://store.arduino.cc/usa/arduino-m0

Arduino need the following pins to start CAN BUs with the MCP2515 chip
Pin  Arduino 'Pin' SERCOM
-----------------------------------------
PA18  D10 SERCOM1.2   CS
PA16  D11 SERCOM1.0   MISO
PA19  D12 SERCOM1.3   MOSI
PA17  D13 SERCOM1.1   SCK
why you don't use the SPI available on 2x3 SPI header?

arduino_solrac



Posted by Juraj : why you don't use the SPI available on 2x3 SPI header?


First - Thanks for your replay Juraj.

My point:

Arduino M0 says on the  web page that SERCOM 1  is available and the sketch also inform that it could work .

Pin  Arduino 'Pin' SERCOM1
-----------------------------------------
PA18  D10 SERCOM1.2   CS
PA16  D11 SERCOM1.0   MISO
PA19  D12 SERCOM1.3   MOSI
PA17  D13 SERCOM1.1   SCK
 
It has to work !!! or Arduino or Arduino need to report us that dont.


Juraj

according to variants.cpp and schematics the SERCOM1 is SPI to EDBG chip on Pro. I don't know what for or if it disturbs normal use of this SPI.
there is no mention about SERCOM on the international shop page for M0 or M0 Pro. I can't see the USA version.

arduino_solrac


Take a look on this Arduino M0 Pro schematic.

https://www.arduino.cc/en/uploads/Main/arduino-M0-schematic.pdf


I have this board, that is why I am working with the reported sketch

arduino_solrac

#12
Sep 29, 2019, 09:45 pm Last Edit: Oct 01, 2019, 09:59 pm by arduino_solrac
Ardunino M0 schematics says:

SERCOM 1 PA30 and PA31 for SWD .

https://www.arduino.cc/en/uploads/Main/arduino-M0-schematic.pdf


I need to use the following SERCOM1 pins to have MCP2515 working. ( any idea? )

Pin     Arduino    'Pin' SERCOM1
-----------------------------------------
PA18  D10         SERCOM1.2   CS
PA16  D11         SERCOM1.0   MISO
PA19  D12         SERCOM1.3   MOSI
PA17  D13         SERCOM1.1   SCK
 

Go Up