finished code to process apps and update erpm
This commit is contained in:
		
							parent
							
								
									b4eebea7de
								
							
						
					
					
						commit
						7c6b8c6404
					
				
							
								
								
									
										164
									
								
								src/main.cpp
									
									
									
									
									
								
							
							
						
						
									
										164
									
								
								src/main.cpp
									
									
									
									
									
								
							@ -5,42 +5,69 @@
 | 
			
		||||
void sendEnable(); // function to turn the inverter on DON'T FORGET TO EDIT THE ID OF THE DRIVE
 | 
			
		||||
void sendERPM(); // function to change the speed DON'T FORGET TO EDIT THE ID OF THE DRIVE
 | 
			
		||||
 | 
			
		||||
/* Invertor config */
 | 
			
		||||
#define MC_L_ID 0x4F        /* ID of the left invertor, to be used in CAN communication */
 | 
			
		||||
#define MC_R_ID 0x4F        /* ID of the right invertor, to be used in CAN communication */
 | 
			
		||||
#define CAN_MC_TIMEOUT 100  /* Timeout of the invertors */
 | 
			
		||||
 | 
			
		||||
/* Invertor CAN packet IDs */
 | 
			
		||||
#define CAN_MC_ID_ERPM   0x03  /* Message to set ERPM */
 | 
			
		||||
#define CAN_MC_ID_ENABLE 0x0C  /* Message to enable/disable drive */
 | 
			
		||||
 | 
			
		||||
/* CAN variables */
 | 
			
		||||
FlexCAN_T4<CAN1, RX_SIZE_256, TX_SIZE_16> can_lv;  /* LV CAN bus is connected to controller 1 */
 | 
			
		||||
FlexCAN_T4<CAN2, RX_SIZE_256, TX_SIZE_16> can_mc;  /* Motorcontroller/Invertor CAN bus is connected to controller 2 */
 | 
			
		||||
#define CAN_LV_BAUD 1000000                        /* Data rate of the LV CAN = 1Mbps */
 | 
			
		||||
#define CAN_MC_BAUD 500000                         /* Data rate of the MC CAN = 500kbps */
 | 
			
		||||
uint64_t time_last_can_mc_send = 0;                /* Timestamp of last message that was sent to motorcontrollers (because they have timeout safety shit) */
 | 
			
		||||
uint64_t time_last_apps = 0;                       /* Timestamp of last message for APPS values */
 | 
			
		||||
uint64_t time_last_rtd_state = 0;                  /* Timestamp of last message for Boot Sequence State stuff */
 | 
			
		||||
 | 
			
		||||
/* CAN heartbeat stuff */
 | 
			
		||||
uint64_t time_last_heartbeat = 0;  /* Timestamp of last heartbeat message that was sent */
 | 
			
		||||
#define HEARTBEAT_PERIOD 100       /* Send heartbeat message every 100ms */
 | 
			
		||||
#define CAN_ID_HEARTBEAT 0x080     /* CAN ID of heartbeat messages (see spreadsheet) */
 | 
			
		||||
#define CAN_MODULE_ID 0x05         /* Module ID of this system (see spreadsheet) */
 | 
			
		||||
uint64_t time_last_heartbeat = 0;       /* Timestamp of last heartbeat message that was sent */
 | 
			
		||||
#define HEARTBEAT_PERIOD 100            /* Send heartbeat message every 100ms */
 | 
			
		||||
#define HEARTBEAT_STATUS_OK 0x0         /* Everything is allright */
 | 
			
		||||
#define HEARTBEAT_STATUS_SAFESTATE 0x1  /* I'm in a safe state */
 | 
			
		||||
#define CAN_ID_HEARTBEAT 0x080          /* CAN ID of heartbeat messages (see spreadsheet) */
 | 
			
		||||
#define CAN_MODULE_ID 0x05              /* Module ID of this system (see spreadsheet) */
 | 
			
		||||
 | 
			
		||||
/* CAN config continued */
 | 
			
		||||
#define CAN_ID_APPS      0x110  /* CAN ID of APPS values (not using Module ID of APPS) */
 | 
			
		||||
#define CAN_ID_BOOT_SEQ  0x090  /* CAN ID of Boot Sequence Status (for RTD) values (using Module ID of ECU for safety) */
 | 
			
		||||
#define CAN_ID_CRITICAL_FAULT 0x000  /* CAN ID of critical fault message (not using any Module ID) */
 | 
			
		||||
#define CAN_ID_APPS_BPPS      0x110  /* CAN ID of APPS and BPPS values (not using Module ID of APPS/BPPS) */
 | 
			
		||||
#define CAN_ID_BOOT_SEQ       0x090  /* CAN ID of Boot Sequence Status (for RTD) values (using Module ID of ECU for safety) */
 | 
			
		||||
 | 
			
		||||
/* Torque Controller variables */
 | 
			
		||||
uint8_t apps_value = 0;  /* Value of the APPS sensor (0-255) */
 | 
			
		||||
char rtd_state = 0;      /* Whether or not RTD is actived */
 | 
			
		||||
#define TC_OK         0b0
 | 
			
		||||
#define TC_SAFE_STATE 0b1
 | 
			
		||||
char tc_state = TC_OK;                      /* Status of the Torque Controller */
 | 
			
		||||
 | 
			
		||||
uint8_t apps_value = 0;                     /* Value of the APPS sensor (0-255) */
 | 
			
		||||
uint8_t bpps_value = 0;                     /* Value of the BPPS sensor (0-255) */
 | 
			
		||||
uint64_t time_last_apps_bpps = 0;           /* Timestamp of last message for APPS and BPPS values */
 | 
			
		||||
 | 
			
		||||
#define RTD_INACTIVE 0b0
 | 
			
		||||
#define RTD_ACTIVE   0b1
 | 
			
		||||
char rtd_state = RTD_INACTIVE;              /* Whether or not RTD is actived */
 | 
			
		||||
uint64_t time_last_rtd_state = 0;           /* Timestamp of last message for Boot Sequence State stuff */
 | 
			
		||||
 | 
			
		||||
uint64_t time_last_can_mc_send_enable = 0;  /* Timestamp of last enable/disable message that was sent to motorcontrollers (because they have timeout safety shit) */
 | 
			
		||||
uint64_t time_last_can_mc_send_erpm = 0;    /* Timestamp of last erpm message that was sent to motorcontrollers (to limit amount of messages) */
 | 
			
		||||
#define CAN_MC_ERPM_PERIOD 25               /* Time between ERPM messages */
 | 
			
		||||
 | 
			
		||||
void handle_can_lv_message(const CAN_message_t &msg) {
 | 
			
		||||
	/* Callback for LV CAN messages */
 | 
			
		||||
 | 
			
		||||
	if ((msg.id & 0xff0) == CAN_ID_APPS) {
 | 
			
		||||
	if ((msg.id & 0xff0) == CAN_ID_CRITICAL_FAULT) {
 | 
			
		||||
		/* Enter safe state */
 | 
			
		||||
		enter_safe_state(FAULT_EXTERNAL_CRITICAL);
 | 
			
		||||
	}
 | 
			
		||||
	else if ((msg.id & 0xff0) == CAN_ID_APPS_BPPS) {
 | 
			
		||||
		/* APPS value */
 | 
			
		||||
		apps_value = msg.buf[0];
 | 
			
		||||
		time_last_apps = millis();
 | 
			
		||||
		bpps_value = msg.buf[1];
 | 
			
		||||
		time_last_apps_bpps = millis();
 | 
			
		||||
	}
 | 
			
		||||
	else if ((msg.id & 0xfff) == CAN_ID_BOOT_SEQ) {
 | 
			
		||||
		/* Boot Sequence Status */
 | 
			
		||||
		char bs = msg.buf[0];
 | 
			
		||||
		rtd_state = (bs == 5) ? 0b1 : 0b0;
 | 
			
		||||
		rtd_state = (bs == 5) ? RTD_ACTIVE : RTD_INACTIVE;
 | 
			
		||||
		time_last_rtd_state = millis();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@ -68,44 +95,49 @@ void can_setup() {
 | 
			
		||||
	can_mc.onReceive(handle_can_mc_message);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* CAN MC subroutines */
 | 
			
		||||
void can_mc_send_drive_allowed(char allowed) {
 | 
			
		||||
	/* Enable or disable left drive */
 | 
			
		||||
    CAN_message_t ml;
 | 
			
		||||
    ml.flags.extended = 1;
 | 
			
		||||
    ml.id = CAN_MC_ID_ENABLE << 8 | MC_L_ID;
 | 
			
		||||
    ml.buf[0] = allowed;
 | 
			
		||||
    can_mc.write(ml);
 | 
			
		||||
 | 
			
		||||
// ID bij ons was 79 = 0x4F
 | 
			
		||||
	/* Enable or disable right drive */
 | 
			
		||||
    CAN_message_t mr;
 | 
			
		||||
    mr.flags.extended = 1;
 | 
			
		||||
    mr.id = CAN_MC_ID_ENABLE << 8 | MC_R_ID;
 | 
			
		||||
    mr.buf[0] = allowed;
 | 
			
		||||
    can_mc.write(mr);
 | 
			
		||||
 | 
			
		||||
void sendEnable() {
 | 
			
		||||
    CAN_message_t msg_DriveEnable;
 | 
			
		||||
    msg_DriveEnable.flags.extended = 1;
 | 
			
		||||
    msg_DriveEnable.id = 0x24 << 8 | 0x4F; // INVERTER ID INSTELLEN VOLGENS VOLGEND FORMAT: 0x24 << 8 | 0x"ID"
 | 
			
		||||
    msg_DriveEnable.buf[0] = 1;
 | 
			
		||||
    msg_DriveEnable.buf[1] = 255;
 | 
			
		||||
    msg_DriveEnable.buf[2] = 0xFF;
 | 
			
		||||
    msg_DriveEnable.buf[3] = 0xFF;
 | 
			
		||||
    msg_DriveEnable.buf[4] = 0xFF;
 | 
			
		||||
    msg_DriveEnable.buf[5] = 0xFF;
 | 
			
		||||
    msg_DriveEnable.buf[6] = 0xFF;
 | 
			
		||||
    msg_DriveEnable.buf[7] = 0xFF;
 | 
			
		||||
    Can0.write(msg_DriveEnable);
 | 
			
		||||
    Serial.println(); 
 | 
			
		||||
	/* Update state */
 | 
			
		||||
    time_last_can_mc_send_enable = millis()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void can_mc_send_erpm(int32_t erpm_l, int32_t erpm_r) {
 | 
			
		||||
	/* Send ERPM to left drive */
 | 
			
		||||
    CAN_message_t ml;
 | 
			
		||||
    ml.flags.extended = 1;
 | 
			
		||||
    ml.id = CAN_MC_ID_ERPM << 8 | MC_L_ID;
 | 
			
		||||
    ml.buf[0] = (erpm_l >> 24) & 0xff;
 | 
			
		||||
    ml.buf[1] = (erpm_l >> 16) & 0xff;
 | 
			
		||||
    ml.buf[2] = (erpm_l >> 8) & 0xff;
 | 
			
		||||
    ml.buf[3] = erpm_l & 0xff;
 | 
			
		||||
    can_mc.write(ml);
 | 
			
		||||
 | 
			
		||||
void sendERPM() {
 | 
			
		||||
  if ( millis() - time_last_update_can > 100 ) {
 | 
			
		||||
    
 | 
			
		||||
    sendEnable();
 | 
			
		||||
    Serial.print("Enable");
 | 
			
		||||
	/* Send ERPM to right drive */
 | 
			
		||||
    CAN_message_t mr;
 | 
			
		||||
    mr.flags.extended = 1;
 | 
			
		||||
    mr.id = CAN_MC_ID_ERPM << 8 | MC_R_ID;
 | 
			
		||||
    ml.buf[0] = (erpm_r >> 24) & 0xff;
 | 
			
		||||
    ml.buf[1] = (erpm_r >> 16) & 0xff;
 | 
			
		||||
    ml.buf[2] = (erpm_r >> 8) & 0xff;
 | 
			
		||||
    ml.buf[3] = erpm_r & 0xff;
 | 
			
		||||
    can_mc.write(mr);
 | 
			
		||||
 | 
			
		||||
    CAN_message_t msg_ERPM;
 | 
			
		||||
    msg_ERPM.flags.extended = 1;
 | 
			
		||||
    msg_ERPM.id = 0x1C << 8 | 0x4F; // INVERTER ID INSTELLEN VOLGENS VOLGEND FORMAT: 0x1C << 8 | 0x"ID"
 | 
			
		||||
    msg_ERPM.buf[0] = (speed >> 24);
 | 
			
		||||
    msg_ERPM.buf[1] = (speed >> 16) & 0xFF;
 | 
			
		||||
    msg_ERPM.buf[2] = (speed >> 8) & 0xFF;
 | 
			
		||||
    msg_ERPM.buf[3] = speed & 0xFF;
 | 
			
		||||
    Can0.write(msg_ERPM);
 | 
			
		||||
    Serial.println("ERPM");
 | 
			
		||||
    printMessage(msg_ERPM);
 | 
			
		||||
    time_last_update_can = millis();
 | 
			
		||||
  }
 | 
			
		||||
	/* Update state */
 | 
			
		||||
    time_last_can_mc_send_erpm = millis()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Subroutine to check if new heartbeat message needs to be sent and transmits it if needed */
 | 
			
		||||
@ -116,7 +148,7 @@ void check_heartbeat() {
 | 
			
		||||
	/* Send heartbeat */
 | 
			
		||||
	CAN_message_t m;
 | 
			
		||||
	m.id = CAN_ID_HEARTBEAT | CAN_MODULE_ID;
 | 
			
		||||
	m.buf[0] = HEARTBEAT_STATUS_OK;
 | 
			
		||||
	m.buf[0] = (tc_state == TC_SAFE_STATE) ? HEARTBEAT_STATUS_SAFESTATE : HEARTBEAT_STATUS_OK;
 | 
			
		||||
	can_lv.write(m);
 | 
			
		||||
 | 
			
		||||
	/* Update stats */
 | 
			
		||||
@ -125,23 +157,33 @@ void check_heartbeat() {
 | 
			
		||||
 | 
			
		||||
/* Subroutine to update invertors */
 | 
			
		||||
void update_drives() {
 | 
			
		||||
	/* TODO: Return if not needed yet */
 | 
			
		||||
	//if (millis() < time_last_heartbeat + HEARTBEAT_PERIOD) return;
 | 
			
		||||
	/* Check timeouts */
 | 
			
		||||
	if (millis() > time_last_rtd + RTD_TIMEOUT) enter_safe_state(FAULT_RTD_TIMEOUT);
 | 
			
		||||
	if (millis() > time_last_apps_bpps + APPS_BPPS_TIMEOUT) enter_safe_state(FAULT_APPS_BPPS_TIMEOUT);
 | 
			
		||||
 | 
			
		||||
	/* Check if needs to send enable message */
 | 
			
		||||
	if (millis() > time_last_can_mc_send_enable + CAN_MC_TIMEOUT-50) {
 | 
			
		||||
		/* Send enable signal to prevent safety timeout */
 | 
			
		||||
		char allowed = (tc_state == TC_OK && rtd_state == RTD_ACTIVE) ? 0b1 : 0b0;
 | 
			
		||||
		can_mc_send_drive_allowed(allowed);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Only continue if not recent enough */
 | 
			
		||||
	if (millis() < time_last_can_mc_send_erpm + CAN_MC_ERPM_PERIOD) return;
 | 
			
		||||
 | 
			
		||||
	/* Update speed */
 | 
			
		||||
	uint8_t speed = apps_value;
 | 
			
		||||
	int32_t rpm;
 | 
			
		||||
	if (rtd_state != RTD_ACTIVE) rpm = 0;
 | 
			
		||||
	else if (tc_state != TC_OK) rpm = 0;
 | 
			
		||||
	else if (apps_value < APPS_THRESHOLD) rpm = 0;
 | 
			
		||||
	else {
 | 
			
		||||
		/* Calculate RPM from APPS value (TODO: optimize this) */
 | 
			
		||||
		rpm = apps_value * 20;
 | 
			
		||||
	}
 | 
			
		||||
	int32_t erpm = rpm * 10; /* ERPM = RPM * Motor Poles, for Emrax this is equal to 10 */
 | 
			
		||||
 | 
			
		||||
	/* Check if data is recent enough */
 | 
			
		||||
	//if (millis() > time_last_apps 
 | 
			
		||||
 | 
			
		||||
	/* Send heartbeat */
 | 
			
		||||
	CAN_message_t m;
 | 
			
		||||
	m.id = CAN_ID_HEARTBEAT | CAN_MODULE_ID;
 | 
			
		||||
	m.buf[0] = HEARTBEAT_STATUS_OK;
 | 
			
		||||
	can_lv.write(m);
 | 
			
		||||
 | 
			
		||||
	/* Update stats */
 | 
			
		||||
	time_last_heartbeat = millis();
 | 
			
		||||
	/* Send message */
 | 
			
		||||
	can_mc_send_erpm(erpm, erpm);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void setup() {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user