UNS8 __stdcall canSend_driver(CAN_HANDLE fd0, Message const *m) { SAnaGatePort* pAnaCanPort = (SAnaGatePort*)fd0; char cErrorMsg[100]; int nRetCode; int nMsgTyp; if (m->rtr == 0) { nMsgTyp = 0; //Normal; } else { nMsgTyp = 2; //Remote frame; } if ( (nRetCode = CANWrite(pAnaCanPort->hHandle , m->cob_id,(const char*) m->data, m->len, nMsgTyp) ) ) { CANErrorMessage( nRetCode, cErrorMsg ,100 ); // Convert returncode to error messge fprintf(stderr,"canSend_driver (AnaGate_Win32) %s \n",nRetCode); //printf("canSend_driver (AnaGate_Win32) %s \n",nRetCode); return 1; } return 0; }
void main() { unsigned char value, lastValue, CANdata[8]; /* These variables are used to check that the rear node and the temperature sensing node are active. */ signed char WaitingPeriods, state202, state50, stateLight; unsigned char c; /* A counter for doing things several times */ unsigned long Brake_light; /* 1 if brake light should be on, off=0 */ unsigned char error_flag=0; long id; unsigned short send_flag, dt, len, read_flag; unsigned int total, V0,V1,V2,V3,tempX10; send_flag = _CAN_TX_PRIORITY_0 & _CAN_TX_NO_RTR_FRAME; /* The state of the CANbus Messages can be: 0 or less : Message not received in the last WaitingPeriods periods x [x from 520 to 1] : Message received (WaitingPeriods-x) periods ago The states begin at 20: */ WaitingPeriods = 5; state202 = 0; state50 = 0; stateLight = 0; /* Get the CANbus ready */ CANbus_setup(); /* Set up and start the timing interrupts */ setup_interrupts(); TRISA =0xFF; /* PORTA is input */ ADCON1=0x80; /* Use supply as Vref. */ TRISC = 0; /* PORT C is for output */ PORTC= 0x10; /* Turn on a LED to show life */ /* Program loop. */ Brake_light=0; for(;;) /* Endless loop */ { if (Tcount20Hz>50){ /* Do this at 20 Hz, roughly */ /* Read the ADC channels Channels 0 and 1 first */ V0=Adc_Read(0); V1=Adc_Read(1); total=V0+V1; /* Now Channel 2, brake pedal */ V2=Adc_Read(2); /* Repeat for Channel 3, brake light level setting pot. */ V3=Adc_Read(3); /* Now decide if Brake light should be on. */ if (V2>V3) Brake_light=1; else Brake_light=0; /* Switch on-board LED for diagnostics */ PORTC.F5=Brake_light; /* Transmit the accelerator and brake pedal settings */ value=V0/5; /* Scale to 0 to 200 from 0 to 1023 */ if (value>200) value=200; if ((value==lastValue)&&(value>60)) c++; else c=0; /* If the throttle pos is stuck, and over 30% for more than 5*20= 120 loops, i.e. 5 seconds, then assume stuck. */ if (c>120) error_flag.F1=1; else error_flag.F1=0; if (c>130) c=130; /* Stop c reseting to 0 by going over 255 */ lastValue=value; /* Now check pedals are not stuck. The total reading from both pots should be 1023, as one falls as the other rises. Initially allow 300 either side of this. */ if ((total<723)||(total>1323)) error_flag.F0=1; else error_flag.F0=0; /* Now set up the data for message 0x80 */ CANdata[0]=value; /* Scale the brake pedal setting to 0-200 */ value=V2/5; CANdata[1]=value; CANdata[2]=error_flag; id=0x80; CANWrite(id, CANdata, 3, send_flag); /* Transmit brake light message, which has id 0x200 */ CANdata[0]=Brake_light; id=0x200; CANWrite(id, CANdata, 1, send_flag); Tcount20Hz=0; } /* End of things done at 20Hz */ if (Tcount1Hz>1000){ /* Do this at 1 Hz, roughly */ if (state202==0){ error_flag.F6=1; } else{ state202--; error_flag.F6=0; } if (state50==0){ error_flag.F7=1; } else{ state50--; error_flag.F7=0; } if (stateLight==0) error_flag.F3=1; else{ stateLight--; error_flag.F3=0; } Tcount1Hz=0; } dt = CANRead(&id, CANdata, &len, &read_flag); if (dt>0){ /*Message received */ if (id==0x202){ state202=WaitingPeriods; error_flag.F4=CANdata[0].F1; error_flag.F5=CANdata[0].F2; if (Brake_light == CANdata[0].F0) stateLight=WaitingPeriods; } if (id==0x50){ state50=WaitingPeriods; tempX10= (CANdata[0]<<8) + CANdata[1]; if (tempX10>600) error_flag.F2=1; else error_flag.F2=0; } } } /* End of endless loop */ } /* End of void main() */
// Now we have the main procedure. void main() { unsigned char CANdata[8]; unsigned char A, B; // scratch-pad variables long id; unsigned short send_flag, dt, len, read_flag; float chargeInc=0; float energyInc=0; float x,y,E,Q; // floats used for energy and charge calcs. // Set up the structures for the CANbus messages that are transmitted // by this node. See manual. These relate to its the system status, and // the total charge and energy used. struct CAN { long id; short len; unsigned char mdata[8]; }errors, totals; errors.id=1024; errors.len=2; totals.id=1025; totals.len=3; // Get the CANbus ready send_flag = _CAN_TX_PRIORITY_0 & _CAN_TX_NO_RTR_FRAME; CANbus_setup(); // Set up and start the timing interrupts setup_interrupts(); // setup the ports TRISA =0xFF; // PORTA is input ADCON1 =0x07; // Configure AN pins 0-3 as digital I/O, page 242 TRISC = 0; // PORT C is for output // Read the energy and charge values out of EEPROM. charge=EEPROM_Read(1); delay_ms(20); A = EEPROM_Read(2); //LSB of energy value delay_ms(20); B = EEPROM_Read(3); //MSB of energy value energy = (B*256) + A; E=energy; // Convert charge and energy to float Q=charge; for(;;) /* Endless loop */ { WhatState(); IndicateState(); SetErrorFlags(); OperateRL3(); // See if any CAN messages in. dt = CANRead(&id, CANdata, &len, &read_flag); if (dt>0) { /*Message received */ if (id==128){ FN_flags= CANdata[2]; // Map Fn errors Accel = CANdata[0]; // Accel postion, 0-200 } if (id==150){ I=(CANdata[0] + (CANdata[1]<<8)); // NB V and I are x10 V=(CANdata[2] + (CANdata[3]<<8)); } if (id==512) brakelight=CANdata[0]; if (id==1026){ T1=CANdata[0]; T2=CANdata[1]; } if (id==1280){ energy=0, E=0, energyInc=0; charge=0, Q=0, chargeInc=0; } } // end of dealing with messages. if (Tcount1Hz>1000){ // Do this at 1 Hz Tcount1Hz=0; // Update float values of energy and charge totals. // E is in 10th of Watt hours, and Q is in 10th of Ah. E = E + (energyInc/360); energyInc=0; Q = Q + ((chargeInc/100)/360); chargeInc=0; // And udate low res integer values as well energy=E; charge=Q; // Send out the two CAN messages. errors.mdata[1]=state; errors.mdata[0]=ERR_FLAG; CANWrite(errors.id, errors.mdata, errors.len, send_flag); // Now set up the CAN charge and energy message, and write the data // to EEPROM. totals.mdata[0]=charge; EEPROM_write(1,charge); totals.mdata[1]=energy; EEPROM_write(2,totals.mdata[1]); totals.mdata[2]=energy>>8; // MS byte second EEPROM_write(3,totals.mdata[2]); CANWrite(totals.id, totals.mdata, totals.len, send_flag); } // end of 1 Hz actions if (Tcount10Hz>100) { // Do this at 10Hz Tcount10Hz=0; x = I; // Be careful to do anything tricky while float chargeInc = (chargeInc + x); // chargeInc is in coulombs, and x100 // Remember that I and V are both x10 y = V; energyInc = (energyInc + ((x*y/1000))); // energyInc is the energy in Joules } // end of 10Hz energy and charge calculations. } /* End of endless loop */