ve2hkw

Tractor unit CAN code

Apr 5th, 2024
817
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Arduino 4.40 KB | Source Code | 0 0
  1. #include "AA_MCP2515.h"
  2. #include "PGN.h"
  3. #include <LCD-I2C.h>
  4.  
  5. #define UP_BUTTON_PIN 5
  6. #define DOWN_BUTTON_PIN 4
  7. #define MASTER_SWITCH_PIN A0
  8.  
  9. // TODO: modify CAN_BITRATE, CAN_PIN_CS(Chip Select) pin, and CAN_PIN_INT(Interrupt) pin as required.
  10. const CANBitrate::Config CAN_BITRATE = CANBitrate::Config_8MHz_500kbps;
  11. const uint8_t CAN_PIN_CS = 10;
  12. const int8_t CAN_PIN_INT = 2;
  13.  
  14. uint8_t valvePins[4] = {9, 8, 7, 6};
  15. uint8_t pinMask = B11111110;
  16.  
  17. volatile uint32_t previousMillis = 0;
  18. const uint16_t interval = 150;
  19.  
  20. uint8_t bitShiftMask[] = {56, 48, 40, 32, 24, 16, 8, 0};
  21.  
  22. CANConfig config(CAN_BITRATE, CAN_PIN_CS, CAN_PIN_INT);
  23. CANController CAN1(config);
  24.  
  25. LCD_I2C lcd(0x27, 20, 4);
  26.  
  27. void setup() {
  28.   lcd.begin();
  29.   lcd.display();
  30.   lcd.backlight();
  31.  
  32.   Serial.begin(115200);
  33.  
  34.   while(CAN1.begin(CANController::Mode::Normal) != CANController::OK) {
  35.     lcd.setCursor(0, 0);
  36.     lcd.print("CAN Controller fault");
  37.     lcd.setCursor(0, 1);
  38.     lcd.print("Retrying in 1 second");
  39.     delay(1000);
  40.     lcd.clear();
  41.   }
  42.   lcd.setCursor(0,0);
  43.   lcd.print("CAN Controller OKAY");
  44.   delay(500);
  45.   lcd.clear();
  46.  
  47.   Serial.println(sizeof(valvePins));
  48.  
  49.   for (int i = 0; i<sizeof(valvePins); i++){
  50.     pinMode(valvePins[i], INPUT_PULLUP);
  51.   }
  52.   pinMode(UP_BUTTON_PIN, INPUT_PULLUP);
  53.   pinMode(DOWN_BUTTON_PIN, INPUT_PULLUP);
  54.   pinMode(MASTER_SWITCH_PIN, INPUT_PULLUP);
  55.  
  56.  
  57. }
  58.  
  59. void loop() {
  60.  
  61.   CANFrame frame;
  62.   if (CAN1.read(frame) == CANController::IOResult::OK) {
  63.     frame.print("RX: ");
  64.     uint32_t id = frame.getId();
  65.     uint8_t dlc = frame.getDlc();
  66.     uint8_t *packet = frame.getData();
  67.     uint8_t dataArray[dlc];
  68.     for (uint8_t i = 0; i<dlc; i++){
  69.       dataArray[i] = *(packet++);
  70.     }
  71.  
  72.     switch(id) {
  73.       case PRESSURE_PGN:
  74.         uint16_t pressure =  
  75.         (dataArray[4] << 24) |
  76.         (dataArray[5] << 16) |
  77.         (dataArray[6] << 8) |
  78.         (dataArray[7]);
  79.         pressureRead(pressure);
  80.         break;
  81.      
  82.       case FLOW_PGN:
  83.        
  84.         break;
  85.      
  86.       case SPEED_PGN:
  87.        
  88.         break;
  89.      
  90.     }
  91.   }
  92.  
  93.   uint32_t currentMillis = millis();
  94.  
  95.   if (currentMillis - previousMillis >= interval) {
  96.     previousMillis = currentMillis;
  97.     uint8_t valveMessage = 0;
  98.     for (int i=0; i<sizeof(valvePins); i++){
  99.       uint8_t var = digitalRead(valvePins[i]);
  100.       uint8_t var2 = var^pinMask; //XOR with B11111110 to produce the inverse, then
  101.       uint8_t var3 = ~var2; // perform a NOT to flip the bits back. This is so we can invert a HIGH input to a 0 in our PGN Byte
  102.       valveMessage |= var3 << i;
  103.     }
  104.    
  105.     uint8_t data2[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, valveMessage};
  106.  
  107.     CANFrame valveFrame(VALVE_PGN, data2, sizeof(data2));
  108.     CAN1.write(valveFrame);
  109.     valveFrame.print("TX: ");
  110.  
  111.    bool upbtn = digitalRead(UP_BUTTON_PIN);
  112.    bool downbtn = digitalRead(DOWN_BUTTON_PIN);
  113.    
  114.  
  115.    if (!upbtn && downbtn) {
  116.     uint8_t UDPacket[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA};
  117.     CANFrame UDFrame(UP_DOWN_PGN, UDPacket, sizeof(UDPacket));
  118.     CAN1.write(UDFrame);
  119.     UDFrame.print("TX: ");
  120.    }
  121.    else if (upbtn && !downbtn) {
  122.     uint8_t UDPacket[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55};
  123.     CANFrame UDFrame(UP_DOWN_PGN, UDPacket, sizeof(UDPacket));
  124.     CAN1.write(UDFrame);
  125.     UDFrame.print("TX: ");
  126.    }
  127.    else {
  128.     uint8_t UDPacket[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  129.     CANFrame UDFrame(UP_DOWN_PGN, UDPacket, sizeof(UDPacket));
  130.     CAN1.write(UDFrame);
  131.     UDFrame.print("TX: ");
  132.    }
  133.  
  134.  
  135.   bool masterSwitch = digitalRead(MASTER_SWITCH_PIN);
  136.     /*The switch is connected to ground and pulls the pin low when set to on.
  137.      Because of this, we want to invert the bool to make it make more sense in our heads here*/
  138.     if (!masterSwitch == true){
  139.       uint8_t MPacket[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA};
  140.       CANFrame MFrame(MASTER_SWITCH_PGN, MPacket, sizeof(MPacket));
  141.       CAN1.write(MFrame);
  142.       MFrame.print("TX: ");
  143.     }
  144.     else if (!masterSwitch == false){
  145.       uint8_t MPacket[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55};
  146.       CANFrame MFrame(MASTER_SWITCH_PGN, MPacket, sizeof(MPacket));
  147.       CAN1.write(MFrame);
  148.       MFrame.print("TX: ");
  149.     }
  150.  
  151.   }
  152. }
  153.  
  154.  
  155. void pressureRead(uint16_t pressure) {
  156.   lcd.clear();
  157.  
  158.   double bar = pressure/1000.0;
  159.  
  160.   lcd.print(bar);
  161. }
  162.  
Advertisement
Add Comment
Please, Sign In to add comment