Ny design Virtuino.

Lagt in lite nya parametrar mest för skoj skull. NightPanel flik som bara visar utetemp och snöflinga.
Länk till dom gamla filerna : GoogleDrive
Bromsljus, dimljus, blinkers, farthållar indikering, recirkulation, dörr-bagage öppna mm. och lite förbrukningsvärden som uppdateras 1/min.
Lagt in en massa appar för att få Virtuino och Waze att starta vid start av surfplattan, laddning mm.
Använt AutoStart, MacroDroid och Trigger.

Arduino-Virtuino code

2019-01-05
// Skickar fråga till SID att skriva på 2 rader. När man trycker på CLR knappen på ratten.
// Hämtar SID tid och datum, kylvatten temp och inne temp. konverterar till HEX och delar upp det per byte.
// Och skickar det till SIDen. 3 ingångar från det andra UNO kortet för att indikera för ändringar
// för AQS, Halvljus och Baksätes värmen. B Visar temp ändring vid Nightpanel. C SPA(backvarn)+ SET inaktiv. CLR funktion.
// C2 : ljussensor värde för att styra halvljuset på det andra Arduinokortet.
// volt spänningsdela 12 volt och presentera batt spänningen 68 kohm/analog ingång/ 33 kohm/ till jord
// Virtuino skickar värden via blåtand till android plattan. 2, nya Canbus värden SPA signaler backväxel.
//Door, kalkylera vilka dörrar är öppna..

#include "VirtuinoBluetooth.h" // Include VirtuinoBluetooth library to your code
// Code to use SoftwareSerial
#include // Disable this line if you want to use hardware serial
SoftwareSerial bluetoothSerial = SoftwareSerial(9,8); // arduino RX pin=2 arduino TX pin=3 connect the arduino RX pin to bluetooth module TX pin - connect the arduino TX pin to bluetooth module RX pin. Disable this line if you want to use hardware serial
VirtuinoBluetooth virtuino(bluetoothSerial); // Set SoftwareSerial baud rate. - Disable this line if you want to use hardware serial

#include
#include
int request = 0 ;
MCP_CAN CAN0(10); // Set CS to pin 10

//-----recive
long unsigned int rxId;
unsigned char len = 0;
unsigned char rxBuf[8];
#define CAN0_INT 2 //tillagt interupt PIN
int value=0 ; int Rx=0; int RxA = 0; int RxB = 0; int RxC = 0; int RxP = 0;

byte Hour = 0; byte HourA = 0; byte HourB = 0; byte MinA = 0; byte MinB = 0;
byte Day = 0; byte Month = 0; byte DayA = 0; byte MonthA = 0; byte DayB = 0; byte MonthB = 0;
int CTemp = 0; byte CTempA = 0; byte CTempB = 0; byte CTempP = 0;
int ITemp = 0; byte ITempA = 0; byte ITempB = 0; byte ITempP = 0;
int OTemp0 = 0;int OTemp1 = 0; int OTempA=0; int OTempB=0; int OTemp = 0;
int NightP=0; int OutTref=0; int OutTime=0;
int LSensor0 = 0;int LSensor1 = 0; // light sensor values
int SPAdist = 0, GearShift = 0, DoorStatus = 0;
unsigned long CLRtime = 0;
//---------------bHeat + Halvljus + AQS-sensorn
int lightOnOUT = 7 ; //ok 6,7,8,9,12 ingång AQS ej 10, 11, 13
int AQSstatus = 0;
int Smell = 0; // 0= low 1 = High 2 = normal ,25, värde för dålig luft normal 15-17
int lightOn = 0; int bHeat = 0; int Cold =0;

int Status = 0; // display status
byte dataA[8] = {0x11, 0x00, 0x03, 0x19, 0x00, 0x00, 0x00, 0x00}; //0x348 SID audio text request from "IHU"
// rad * 19 //*FF=inget meddelande,prio.nivå b3(19=IHU 12=SPA 23=ACC)
//[2]: request type: 1 = Engineering test; 2 = Emergency; 3 = Driver action; 4 = ECU action; 5 = Static text; 0xFF = We don't want to write on SID
byte dataB[8] = {0x80, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; // SID beep vid halkvarning

int battPin = A5;
float battVolt = 0; //float
byte battA =0; byte battB =0; byte battC = 0; // ascII values for batt. voltage

unsigned long VirtuTime = 0; //RXY timer

void setup()
{
Serial.begin(9600);
virtuino.DEBUG=true; // set this value TRUE to enable the serial monitor status
bluetoothSerial.begin(9600); // Enable this line if you want to use software serial (UNO, Nano etc.)
if(CAN0.begin(CAN_47K619BPS,1) == CAN_OK) Serial.println("MCP2515 Initialized Successfully!");
else Serial.println("Error Initializing MCP2515...");
pinMode(2, INPUT); // Setting pin 2 for /INT input
//----Headlamp
pinMode(lightOnOUT,OUTPUT); // ungång INPUT_PULLUP
digitalWrite(lightOnOUT,LOW);
}
void loop()
{ //ordning från rad ascII-----------------------
byte data1[8] = {0x45, 0x96, 0x01, HourB, HourA, 0x3A, MinB, MinA}; // 1 message 1 01 = rad 1 alt. 81= uppdaterad rad 1
byte data2[8] = {0x04, 0x96, 0x01, 0x20, 0x20, DayB, DayA, 0x2F}; // day/ "SAAB" S=53 A=41 B=42 20=_
byte data3[8] = {0x03, 0x96, 0x01, MonthB, MonthA, 0x20, 0x20, 0x20}; //Month "SAAB" S=53 A=41 B=42 3 SISTA BYTE SYNS EJ PÅ sid

byte dataA1[8]= {0x02, 0x96, 0x02, 0x41, 0x51, 0x53, 0x20, 0x52}; // AQS_R
byte dataA2[8]= {0x01, 0x96, 0x02, 0x63, 0x69, 0x72, 0x6B, 0x20}; // cirk_

byte dataB1[8]= {0x02, 0x96, 0x02, 0x48, 0x61, 0x6C, 0x76, 0x6C}; // Halvl
byte dataB2[8]= {0x01, 0x96, 0x02, 0x6A, 0x75, 0x73, 0x20, 0x20}; // jus__

byte dataC1[8]= {0x02, 0x96, 0x02, 0x42, 0x61, 0x6B, 0x73, 0x2E}; // Baks.
byte dataC2[8]= {0x01, 0x96, 0x02, 0x76, 0x61, 0x72, 0x6D, 0x20}; // varm_ D1=å ?

byte dataL[8] = {0x00, 0x96, 0x02, 0x41, 0x56, 0x00, 0x00, 0x00}; //328 Av SID text
byte dataH[8] = {0x00, 0x96, 0x02, 0x50, 0xE1, 0x00, 0x00, 0x00}; //328 På SID text E1=Å D7=Ö (D1=Ä)

byte dataD1[8]= {0x02, 0x96, 0x02, 0x48, 0x61, 0x6C, 0x6B, 0x2E}; // Halk.
byte dataD2[8]= {0x01, 0x96, 0x02, 0x56, 0x61, 0x72, 0x6E, 0x2D}; // Varn-
byte dataD3[8]= {0x00, 0x96, 0x02, OTempB, OTempA,0x20, 0x20, 0x20}; // Outside temp. values

byte data4[8] = {0x02, 0x96, 0x02, 0x49, 0x6E, ITempP, ITempB, ITempA}; // In CTemp+- message 0 "SAAB" S=53 A=41 B=42 20=_
byte data5[8] = {0x01, 0x96, 0x02, 0x20, 0x4B, 0x79, 0x6C, CTempP}; // Kyl 328 SID audio text 0 message 0 "SAAB" S=53 A=41 B=42 3 SISTA BYTE SYNS EJ PÅ sid
byte data6[8] = {0x00, 0x96, 0x02, CTempB, CTempA, 0x20, 0x20}; //328 SID audio text 0 message 0 "SAAB" S=53 A=41 B=42 3 SISTA BYTE SYNS EJ PÅ sid
// test with batt.voltage on SID
//byte data5[8] = {0x01, 0x96, 0x02, 0x20, battC, battB, 0x2C, battA}; // Batteri spänningen 12.5 S=53 A=41 B=42 3 SISTA BYTE SYNS EJ PÅ sid
//byte data6[8] = {0x00, 0x96, 0x02, 0x20, 0x56, 0x20, 0x20, 0x20 }; //328 SID audio text 0 message 0 "SAAB" S=53 A=41 B=42 3 SISTA BYTE SYNS EJ PÅ sid
//order SID row ASCII-------------------
unsigned long currentSek = millis()/1000 ; //unsigned long värde i sekunder
virtuino.run(); // necessary command to communicate with Virtuino android app
//------------------ Sending values to Tablet V10-15
if(currentSek-VirtuTime >= 2) { //uppdaterar värderna vart 4e sek.
virtuino.vMemoryWrite(10,CTemp); //coolanttemp
virtuino.vMemoryWrite(11,ITemp); //kupetemp
virtuino.vMemoryWrite(12,OTemp); //utetemp
virtuino.vMemoryWrite(13,LSensor1); //ljussensorn värdet
virtuino.vMemoryWrite(14,battVolt); //batteri spän.
virtuino.vMemoryWrite(15,DoorStatus); // test value for door status
//------------------------ Checking door status DV10-15
if (DoorStatus-128 >= 0) { virtuino.vDigitalMemoryWrite(10,0); DoorStatus = DoorStatus-128; } // door 128 = unlocked
else { virtuino.vDigitalMemoryWrite(10,1); } // door = locked
if (DoorStatus-64 >= 0) { virtuino.vDigitalMemoryWrite(11,1); DoorStatus = DoorStatus-64; } // Driversdoor 64 = open
else { virtuino.vDigitalMemoryWrite(11,0); }
if (DoorStatus-32 >= 0) { virtuino.vDigitalMemoryWrite(12,1); DoorStatus = DoorStatus-32; } // Passangerdoor 32 = open
else { virtuino.vDigitalMemoryWrite(12,0); }
if (DoorStatus-16 >= 0) { virtuino.vDigitalMemoryWrite(13,1); DoorStatus = DoorStatus-16; } // LeftBacksdoor 16 = open
else { virtuino.vDigitalMemoryWrite(13,0); }
if (DoorStatus-8 >= 0) { virtuino.vDigitalMemoryWrite(14,1); DoorStatus = DoorStatus-8; } // RightBackdoor 8 = open
else { virtuino.vDigitalMemoryWrite(14,0); }
if (DoorStatus-4 >= 0) { virtuino.vDigitalMemoryWrite(15,1); DoorStatus = DoorStatus-4; } // Trunk 4 = open
else { virtuino.vDigitalMemoryWrite(15,0); }
VirtuTime = currentSek; }
//------------------ Sending SPA value and revers status V1, DV 0,1 ,2+3
if (GearShift == 2) { virtuino.vDigitalMemoryWrite(0,1); // 2 = Revers gear DV 0 blir 1 aktierar panel 2 "Park assist"
virtuino.vMemoryWrite(1,SPAdist); // Park assist distance value (190 utan blockering)
if (SPAdist <= 150) { virtuino.vDigitalMemoryWrite(2,1); } // DV2 SPAbild om distan är närmare än 100 cm else { virtuino.vDigitalMemoryWrite(2,0); } if (SPAdist <= 15) { virtuino.vDigitalMemoryWrite(3,1); } // DV3 rödSPAbild om distan är närmare än 15 cm else { virtuino.vDigitalMemoryWrite(3,0); } } else { virtuino.vDigitalMemoryWrite(0,0); } // visar orginal fönster annars //------------------ Night Panel status DV 0,2 //if (NightP==1) { virtuino.vDigitalMemoryWrite(0,2); } // NightPanel active on Tablet. // else { virtuino.vDigitalMemoryWrite(0,0); } //----------Kontrollerar vad digi-ingångarna för AQS,bHeat och Halvljus //AQSstatus = digitalRead(airSensorIN); if (digitalRead(6) == 1 && Smell == 0) {Status = 1; request = 1; Smell = 1; } // AQS hög Status = 1; // byte sndStat = CAN0.sendMsgBuf(0x430, 0, 8, dataB);delay(30);} // send Beep 430 when AQS go High if (digitalRead(6) == 0 && Smell == 1) {Status = 1; request = 1; Smell = 0; } // AQS låg Status = 11; //----------- read lightsensor and activate/inactivate headligths/DRL DV 1 if (LSensor1 <= 5 && lightOn == 0) { lightOn = 1; digitalWrite(lightOnOUT,HIGH); //v-urdino Status = 2; request = 1; virtuino.vDigitalMemoryWrite(1,1); } // Halvljus På 12-14 hystres (20 tunnel) if (LSensor1 >= 15 && lightOn == 1) { lightOn = 0; digitalWrite(lightOnOUT,LOW); //v-urdino Status = 2; request = 1;
virtuino.vDigitalMemoryWrite(1,0); } // Halvljus Av

//v-urdino 8 if (digitalRead(6) == 1 && bHeat == 0) {Status = 3; request = 1; bHeat = 1;} // BaksätesVärme På
//v-urdino 8 if (digitalRead(6) == 0 && bHeat == 1) {Status = 3; request = 1; bHeat = 0;} // BaksätesVärme Av
/// ------------Halkvarning om temp är vid noll och/eller sjunker 2 grader
if (OTemp <= 0 && currentSek >= 60 && Cold == 0) {request = 1; Status=4; Cold=1; OutTref = OTemp; // Outside temp =< 0 byte sndStat = CAN0.sendMsgBuf(0x430, 0, 8, dataB);delay(30);} // send Beep 430 when Outside temp =< 1 if (OTemp > 2) Cold = 0;
if (NightP==1 && OTemp <= 0) { // (med aktiv Night Panel) och minusgrader if (OutTref <= OTemp-2 || OutTref >= OTemp+2) // presenterar temp om den ändras 2 grader
{request = 1; Status=4; OutTref = OTemp; }
}
//----------- batteri voltage analogPIN
battVolt = analogRead(battPin); // 1024 = 5 volt = ca.15 volt
battVolt = (5*battVolt)/1024 ; // konverterar analoga värdet till volt 0-5 volt
battVolt = ((33+68)/33 *battVolt)*10 ; // kontverterar 5 till 12 volt (analog in)
battVolt = battVolt/10 ;
// Rx=battVolt; Convert(); battA=RxA; battB=RxB; if(RxC==0x30)battC=0x20; //battC=RxC; // konv. 12 volts värdet till ascII
// Serial.println(battVolt);
// Serial.println(Rx); Serial.print(RxC);Serial.print(RxB);Serial.println(RxA);

// Serial.print("\t"); // print a tab character

//------ send data: ID = 0x100, Standard CAN Frame, Data length = 8 bytes, 'data' = array of data bytes to send
if (request == 1) { // if request is active och efter 1 min för att cleara Service Meddelandet mm,
byte sndStat = CAN0.sendMsgBuf(0x348, 0, 8, dataA);delay(10); //0x348 SID audio text
// Serial.println("Request Sent Successfully!");
}
// -----receive SID okey
if(digitalRead(CAN0_INT)== LOW && request == 1) { // If pin 2 is low, read receive buffer
CAN0.readMsgBuf(&len, rxBuf); // Read data: len = data length, buf = data byte(s)
rxId = CAN0.getCanId(); // Get message ID
if(rxId == 0x368 ){ // får OK från SID att skicka
for(int i = 0; i898ms)
} } } }

///-----------läser av CANbus
if(digitalRead(CAN0_INT)== LOW && request == 0) { // If pin 2 is low, read receive buffer
CAN0.readMsgBuf(&len, rxBuf); // Read data: len = data length, buf = data byte(s)
rxId = CAN0.getCanId(); // Get message ID

switch (rxId) {
case 0x290: //-------------------set eller clr button pressed
value=3 ; //// 80 = vol- && (rxBuf[5] == 0x80)
CanbusRead();
if (Rx == 0x40) CLRtime = currentSek ; // vid SET nollar CLR timer = inaktiverar CLR request i 10 sek.
if (Rx == 0x80 && currentSek-CLRtime >= 10 && currentSek >= 40) {request = 1; Status=0;} // inakriverar clr funktionen under 30 sek.
break;
case 0x320: //-------------------Door status
value = 1 ; //// 1 = door status
CanbusRead(); DoorStatus = Rx;
Serial.print("Door status ");Serial.println(DoorStatus);
break;
case 0x3E0: //-------------------- Automatic gearbox är aktiv
value = 2 ; CanbusRead(); GearShift = Rx; //Distance
Serial.print("Backväxel aktiv "); Serial.println(GearShift);
break;
case 0x439: //-------------------- SPA är aktiv + distance
CLRtime = currentSek ; // nollar CLR timer = inaktiverar request i 10 sek.
value = 2 ; CanbusRead(); SPAdist = Rx; //Value 01h means Park, 02h Reverse, 03h Neutral, 04h Drive
Serial.println("SPA aktiv ");
break;
case 0x7A0: //-------------------- Outside temp
value=2 ;CanbusRead(); OTemp0 = Rx;
value=1 ;CanbusRead(); OTemp1 = Rx;
OTemp = (OTemp1 * 256)+OTemp0 ;
OTemp=OTemp/10-40; // Serial.print("Outside Temp Recived Successfully! ");Serial.println(OTemp);
Rx=OTemp; Convert(); OTempA=RxA; if(RxB==0x30)RxB=0x20; OTempB=RxB; // om RxB är noll ger mellanslag
break;
case 0x410: // ------ NightPanel active
//------- Light Dimm Sensor values (Integer value is between about 1800h(6144 dec) to 2C00h(11264 dec))
// value=3 ;CanbusRead(); LSensor0 = Rx;
value=4 ;CanbusRead(); LSensor1 = Rx; // använder endast Lsensor1 värdet för styrning av halvljuset.
//LSensor = LSensor1 // * 256) + LSensor0 ;
//Serial.print(LSensor0);Serial.print(" 0Light Sensor value1 ");Serial.println(LSensor1);
//Serial.println(lightOn);
value=5 ; // Night Panel byte som ska läsas av
CanbusRead();
NightP=Rx; //Serial.print("NightPanel ");Serial.println(NightP);
break;
case 0x5C0: // -------------------- ECU coolant Temp 5C0h - COOLANT PRES1 PRES0
value=1 ; // vilken byte som ska läsas av
CanbusRead();
CTemp=Rx-40 ; //0x28=40dec 40 ;
Rx = CTemp ;
// Serial.print("Coolant Temp ");Serial.println(Rx);
Convert();
CTempA=RxA; CTempB=RxB; CTempP=RxP; // Serial.print(RxA);Serial.println(RxB);
Serial.print(RxP);Serial.print(RxB);Serial.println(RxA);
break;
case 0x520 : //----------------------- Reciving ACC Inside Temp 520h - ACC - - - TEMP
value=5 ; // vilken byte som ska läsas av
CanbusRead();// byte 5
ITemp=Rx-40 ; //28=40dec;
Rx = ITemp;
// Serial.print("Inside Temp ");Serial.println(ITemp);
Convert();
ITempA = RxA; ITempB = RxB; ITempP=RxP; // Serial.print(RxA);Serial.println(RxB);
Serial.print(RxP);Serial.print(RxB);Serial.println(RxA);
break;
case 0x730 : // SID Byte 0 Byte 1 Byte 2 Byte 3 Byte 4 Byte 5 Byte 6 Byte 7
// 730h - SEC MIN HOUR DAY MONTH ENGCOLD -
value=3 ; CanbusRead(); // Rx = Rx+1; // byte 3 Hour (Rx = Rx+1;) ger sommartid
Convert(); HourA=RxA;if(RxB==0x30)RxB=0x20; HourB=RxB; // Serial.println("Time Recived! ");
value=2 ; CanbusRead();// byte 2 Min
Convert(); MinA=RxA; MinB=RxB;
value=5 ; CanbusRead();// byte 5 Month
Convert(); MonthA=RxA; MonthB=RxB;
value=4 ; CanbusRead();// byte 4 Day
Convert(); DayA=RxA; if(RxB==0x30)RxB=0x20; DayB=RxB;
// Serial.print(HourA); Serial.print(HourB);Serial.print(" : ");Serial.print(MinA);Serial.println(MinB);
break;
} }
}
void CanbusRead(){
for(int i = 0; i= 0 ){RxP = 0x20;} else {RxP = 0x2D; Rx=-Rx;} // 2D Minus tecken 2B Plus tecken
//--------hundratal
if (Rx<900 && Rx >= 800) {RxC=0x38; Rx=Rx-800;} if (Rx >= 900) {RxC=0x39; Rx=Rx-900;}
if (Rx<700 && Rx >= 600) {RxC=0x36; Rx=Rx-600;} if (Rx<800 && Rx >= 700) {RxC=0x37; Rx=Rx-700;}
if (Rx<500 && Rx >= 400) {RxC=0x34; Rx=Rx-400;} if (Rx<600 && Rx >= 500) {RxC=0x35; Rx=Rx-500;}
if (Rx<300 && Rx >= 200) {RxC=0x32; Rx=Rx-200;} if (Rx<400 && Rx >= 300) {RxC=0x33; Rx=Rx-300;}
if (Rx<100) {RxC=0x30; Rx=Rx;} if (Rx<200 && Rx >= 100) {RxC=0x31; Rx=Rx-100;}
//--------tiotal
if (Rx<90 && Rx >= 80) {RxB=0x38; RxA=Rx-80;} if (Rx >= 90) {RxB=0x39; RxA=Rx-90;}
if (Rx<70 && Rx >= 60) {RxB=0x36; RxA=Rx-60;} if (Rx<80 && Rx >= 70) {RxB=0x37; RxA=Rx-70;}
if (Rx<50 && Rx >= 40) {RxB=0x34; RxA=Rx-40;} if (Rx<60 && Rx >= 50) {RxB=0x35; RxA=Rx-50;}
if (Rx<30 && Rx >= 20) {RxB=0x32; RxA=Rx-20;} if (Rx<40 && Rx >= 30) {RxB=0x33; RxA=Rx-30;}
if (Rx<10) {RxB=0x30; RxA=Rx;} if (Rx<20 && Rx >= 10) {RxB=0x31; RxA=Rx-10;}
//-----ental
if (RxA==0)RxA=0x30;if (RxA==1)RxA=0x31;if (RxA==2)RxA=0x32;if (RxA==3)RxA=0x33;if (RxA==4)RxA=0x34;
if (RxA==5)RxA=0x35;if (RxA==6)RxA=0x36;if (RxA==7)RxA=0x37;if (RxA==8)RxA=0x38;if (RxA==9)RxA=0x39;
}
/*********************************************************************************************************
*********************************************************************************************************/

Virtuino istället för RemoteXY

Hittade detta alternativa program till Surfplattan.
Virtuino den har en liten annan uppbyggnad och med den fördelen att man kan använda bilder.

En första design.
Med och utan halvljuset på.
Dom vanliga tempvärdena och
la in dörrindikerings värden som
jag tänkte använda i version 2.
När man lägger i backen visas denna bild med avstånd och larm bild som ska dyka upp när den larmar.

Sen verkar den fungera bättre ihop med SID kommunikationen också.





Sitter med ett problem hur jag ska tolka dörr värdena, nivåerna är
Bagagelucka 4 ,  Höger bakdörr 8, Vänster bakdörr 16, Höger framdörr 32, Vänster framdörr 64
samt Olåst 128, Det blir en massa kombinationer.
T.ex 192 är olåst och vänster framdörr öppen med bagageluckan öppen blir det 196....osv.
Trir jag fixat det med denna lösning: (ny kod är upplagd)
    //------------------------     Checking door status DV10-15
if (DoorStatus-128 >= 0) { virtuino.vDigitalMemoryWrite(10,0); DoorStatus = DoorStatus-128; }  // door 128 = unlocked
           else { virtuino.vDigitalMemoryWrite(10,1); }          // door  = locked
if (DoorStatus-64 >= 0) { virtuino.vDigitalMemoryWrite(11,1); DoorStatus = DoorStatus-64; }  // Driversdoor 64 = open
           else { virtuino.vDigitalMemoryWrite(11,0); }        
if (DoorStatus-32 >= 0) { virtuino.vDigitalMemoryWrite(12,1); DoorStatus = DoorStatus-32; }  // Passangerdoor 32 = open
           else { virtuino.vDigitalMemoryWrite(12,0); }
if (DoorStatus-16 >= 0) { virtuino.vDigitalMemoryWrite(13,1); DoorStatus = DoorStatus-16; }  // LeftBacksdoor 16 = open
           else { virtuino.vDigitalMemoryWrite(13,0); }
if (DoorStatus-8 >= 0) { virtuino.vDigitalMemoryWrite(14,1); DoorStatus = DoorStatus-8; }  // RightBackdoor 8 = open
           else { virtuino.vDigitalMemoryWrite(14,0); }
if (DoorStatus-4 >= 0) { virtuino.vDigitalMemoryWrite(15,1); DoorStatus = DoorStatus-4; }  // Trunk 4 = open
           else { virtuino.vDigitalMemoryWrite(15,0); }

CanBus parametrar till Surfplattan via Blåtand.

Inspirerade av dessa "byggen": Car Dash Tablet och
Canbus-reverse-engineering-with-arduino-and-ios
Skaffade ett Blåtandskort (HC-06) till Canbus kortet för att kunna skicka parametrar till Surfplattan.
Tyvärr är man ingen Android programmerare så denna app RemoteXY får duga.
5 parametrer i den fria versionen så det blev 3 temp, långtext + batteri spänningen.

Man går in på RemoteXY hemsida och skapar sin design som man sedan kopierar in i Arduino
programmet (med lite modifikationer).
https://saab9000vector.blogspot.com/2018/12/remotexy-kod.html
Batterispänningen spänningsdelar jag ner till en analog ingång. (med 33k och ett 68 k motstånd)
Konverterar värdet i programet så att det stämmer hyfsat.

Det negativa är att SID meddelanderna inte funkar 100% försökt avlasta programet lite och
minus grader visas som 255 och under , får väl modifiera lite på koden...

RemoteXY kod.

// RemoteXY select connection mode and include library
#define REMOTEXY_MODE__SOFTSERIAL
#include <SoftwareSerial.h>
#include <RemoteXY.h>
// RemoteXY connection settings
#define REMOTEXY_SERIAL_RX 2
#define REMOTEXY_SERIAL_TX 3
#define REMOTEXY_SERIAL_SPEED 9600


// RemoteXY configurate 
#pragma pack(push, 1)
uint8_t RemoteXY_CONF[] =
  { 255,0,0,44,0,80,0,8,13,0,
  67,4,9,11,20,5,134,26,11,67,
  4,38,11,20,5,134,26,11,67,4,
  66,11,20,5,134,26,11,67,4,64,
  44,20,5,134,26,11,129,0,10,22,
  18,6,17,73,110,110,101,45,32,32,
  32,32,32,32,32,32,32,75,121,108,
  97,114,45,32,32,32,32,32,32,85,
  116,101,116,101,109,112,0 };
 
// this structure defines all the variables of your control interface
struct {

    // output variable
  char INtemp[11];  // string UTF8 end zero
  char Coolant[11];  // string UTF8 end zero
  char OUTtemp[11];  // string UTF8 end zero
  char Voltage[11];  // string UTF8 end zero
    // other variable
  uint8_t connect_flag;  // =1 if wire connected, else =0

} RemoteXY;
#pragma pack(pop)
//           END RemoteXY include          //
  double temp = 24;

void setup()
{
  RemoteXY_Init (); 
}

void loop()
{
  RemoteXY_Handler ();  
if(currentSek-rXYtime >= 4)   {   //uppdaterar rXY värderna vart 4dje sek.
  //      value, ? , decimals, rXY label   tillagt manuellt
  dtostrf(ITemp, 0, 0, RemoteXY.INtemp);  
  dtostrf(CTemp, 0, 0, RemoteXY.Coolant);
  dtostrf(OTemp, 0, 0, RemoteXY.OUTtemp);
  dtostrf(battVolt, 0, 1, RemoteXY.Voltage);
  rXYtime = currentSek;      }

//----------- batteri voltage
    battVolt = analogRead(battPin);     // 1024 = 5 volt = ca.15 volt
   //battVolt = 967 ;  // test
    battVolt = (5*battVolt)/1024 ;    // konverterar analoga värdet till volt 0-5 volt
    battVolt = ((33+68)/33 *battVolt)*10 ; // kontverterar 5 till 12 volt (analog in)
    battVolt = battVolt/10 ;
}

Styrning av Halvljus automatiken med ljussensorn för inst.panelen.

Tänkte rationalisera bort ljussensorena som styr halvljus automatiken.
Så tar ljussensorvärdet ifrån instrumentpanelen.
Det är 2 8bitars värden men jag använder bara ett,

case 0x410: //-------   Light Dimm Sensor values
                   // (Integer value is between about 1800h(6144 dec) to 2C00h(11264 dec))
value=3 ;CanbusRead(); LSensor0 = Rx;
value=4 ;CanbusRead(); LSensor1 = Rx;  // använder endast Lsensor1 värdet för styrning av halvljuset.

Sedan använder jag ganska grov hystres för att undvika flip-flopande lampor.

  if (LSensor1 <= 5  && lightOn == 0) {Status = 2; request = 1; lightOn = 1; digitalWrite(lightOnOUT,HIGH); }  // Halvljus På 01-05 hystres 
  if (LSensor1 >= 15 && lightOn == 1) {Status = 2; request = 1; lightOn = 0; digitalWrite(lightOnOUT,LOW); }  // Halvljus Av








Testningen går ju lite långsam eftersom det är kolsvart både till och från jobbet.
Och styrningen går via det gamla Arduino kortet tillsvidare. Ändringen i det gamla kortet.

pinMode(headLightPinCan, INPUT);    // halvljus Ingång, från Can-kortet
 //---------------------------- HALVLJUS AUTOMATIK
        headLightCan = digitalRead(headLightPinCan);
       if (headLightCan == 1 && lightOn == 0) {                                                          
                digitalWrite(headlightPin,HIGH);  // tänder halvljuset   
                delay(50); lightOn = 1; 
                headLightTimer = currentSekund ; // Sätter timer tid          
            } //{lightOn = 1;}
       if (headLightCan == 0 && lightOn == 1) {
                digitalWrite(headlightPin,LOW);
                delay(50); lightOn = 0; 
                headLightTimer = currentSekund ; // Sätter timer tid
              }

Grotta ner sig i CANbus med Arduino

Köpt på mig MCP2515 CANbus kort och ett Arduino Pro Micro kort.
Installtion av Arduino kortet hittar man här:
https://learn.sparkfun.com/tutorials/pro-micro--fio-v3-hookup-guide/all
och så här kopplar man inkl. 12 volts reg på RAW och GND.















Sen kan man krympa ner den mer än detta men som vanligt tar vi det senare......

Här är koden och tanken är att man filtrerar bort all information man inte vill ha med.
Det är ju mycket babbel på CANbusen.

// demo: CAN-BUS Shield, receive data
#include <mcp_can.h>
//#include <mcp_can_dfs.h>
#include <SPI.h>

long unsigned int rxId;
unsigned char len = 0;
unsigned char rxBuf[8];
unsigned long OLDmilliSek;
MCP_CAN CAN0(10);                // Set CS to pin 9
#define CAN0_INT 2                  //tillagt

void setup()
{
  Serial.begin(9600);
  //CAN0.begin(MCP_ANY, CAN_33K3BPS, MCP_16MHZ);
  //CAN0.begin(CAN_47K619BPS,2);              // init can bus :CAN_33K3BPS baudrate = 33.3(GMLAN) with 8MHZ change 2 to 1 run with 16mhz oscilator
  //CAN0.begin(CAN_33K3BPS,1);                // CAN0.begin(CAN_47K619BPS,1);   CANbus-I
  CAN0.begin(CAN_500KBPS,1);                // CANBUS-P powertrain
  //pinMode(CAN0_INT, INPUT);                            // Configuring pin for /INT input
  pinMode(2, INPUT);                            // Setting pin 2 for /INT input
  Serial.println("MCP2515 Library Receive CAN BUS Example...");
}

void loop(){
  unsigned long currentmilliSek = millis(); // / 1000 ;  //unsigned long värde i sekunder
    if(digitalRead(CAN0_INT)== LOW)                         // If pin 2 is low, read receive buffer
    {
      CAN0.readMsgBuf(&len, rxBuf);              // Read data: len = data length, buf = data byte(s)
      rxId = CAN0.getCanId();                    // Get message ID
      if(rxId == 0x439 ){ //  290= steeringwheel || rxId == 0x530 om Id = ACC 520 eller 530 0x280 crusies byte 4
        //filtrerar bort 439h - SPA distance
      } else {
      Serial.print("ID: ");
      Serial.print(rxId, HEX);
      Serial.print("  Data: ");
      for(int i = 0; i<len; i++)                // Print each byte of the data
      {
       if(rxBuf[0] < 0x80) {                     // shows changed Status
        if(rxBuf[i] < 0x10)                     // If data byte is less than 0x10, add a leading zero
        {
          Serial.print("0");
        }
        Serial.print(rxBuf[i], HEX);
        Serial.print(" ");
      }                                 // satus change end
      }
      Serial.print("  ");Serial.print(currentmilliSek-OLDmilliSek);Serial.println();
      OLDmilliSek=currentmilliSek;    // tidstämpel
    }                                     // filter end
    }
}