K-CAN Проект
Модератор: bum_bum
40 мнения
• Страница 3 от 3 • 1, 2, 3
- Nickelback
- старши ентусиаст
- Мнения: 1857
- Регистриран на: 20.10.2010
- Местоположение: София
- Пол: Мъж
- Кара: BigBlockV8 и чат-пат SmallBlockV8
- Мечтае да кара: бангия с предно
- Детайли за колата: ;)
Big: Hemi 370 cu. in.
Small: S62B50 с жокери
Re: K-CAN Проект
Супер, има раздвижване Аз пак да пусна една муха Така и така ще ползваш RPi (а може и нещо по-мощно ), защо не закачиш и една камерка за него и не си направиш gesture control с OpenCV (има порт за Python ) поне да си регулираш музиката и да си сменяш песните с ръкомахане. Може и някакъв vehicle customization (автоматично регулиране на седалката, да речем) като ти разпознае лицето. Ще е яко
"За тЕя пари има Е-шеесе" - форумна пословица.
Лето две и седемнаесто.
- shadowx
- Потребител
- Мнения: 31
- Регистриран на: 5.04.2016
- Пол: Мъж
- Кара: BMW 120d e87
- Детайли за колата: BMW 120d e87 163hp
Re: K-CAN Проект
Мислех го, но реално gesture hat има за 30-40лв https://www.adafruit.com/product/2325 не е нужно да се занимаваш с OpenCV даже ... (аз имам малко опит попринцип ... боене на коли... четене на номера )
(Не официално работя и над едно друго проектче, което основно разчита на OpenCV ...но то няма общо с колата... там е социален проект.)
(Не официално работя и над едно друго проектче, което основно разчита на OpenCV ...но то няма общо с колата... там е социален проект.)
- Nickelback
- старши ентусиаст
- Мнения: 1857
- Регистриран на: 20.10.2010
- Местоположение: София
- Пол: Мъж
- Кара: BigBlockV8 и чат-пат SmallBlockV8
- Мечтае да кара: бангия с предно
- Детайли за колата: ;)
Big: Hemi 370 cu. in.
Small: S62B50 с жокери
Re: K-CAN Проект
shadowx написа:Мислех го, но реално gesture hat има за 30-40лв https://www.adafruit.com/product/2325 не е нужно да се занимаваш с OpenCV даже ... (аз имам малко опит попринцип ... боене на коли... четене на номера )
(Не официално работя и над едно друго проектче, което основно разчита на OpenCV ...но то няма общо с колата... там е социален проект.)
"Senses from up to 5cm away"
Не е същото като с камера, сещаш се...
OpenCV-то на PC ли си го пробвал или пак на някакъв борд?
"За тЕя пари има Е-шеесе" - форумна пословица.
Лето две и седемнаесто.
- shadowx
- Потребител
- Мнения: 31
- Регистриран на: 5.04.2016
- Пол: Мъж
- Кара: BMW 120d e87
- Детайли за колата: BMW 120d e87 163hp
Re: K-CAN Проект
Nickelback написа:"Senses from up to 5cm away"
Не е същото като с камера, сещаш се...
Да...и по-ограничено от към жестове... но пък поставено на мястото на зад скорностния лост , 5см биха били достатъчни, защото ще е удобно....
М/у другото за OpenCV-то ...може и face recodnicion за разрешаване на запалването... но трябва да пускаш RPi-то при отключване от дистанционното например за да може да е заредило малко след като си в колата.
Реално с този дизаин arudino + rpi - the sky is the limit
Nickelback написа:OpenCV-то на PC ли си го пробвал или пак на някакъв борд?
На x86/x86_64 и разни ARM-та
- Nickelback
- старши ентусиаст
- Мнения: 1857
- Регистриран на: 20.10.2010
- Местоположение: София
- Пол: Мъж
- Кара: BigBlockV8 и чат-пат SmallBlockV8
- Мечтае да кара: бангия с предно
- Детайли за колата: ;)
Big: Hemi 370 cu. in.
Small: S62B50 с жокери
Re: K-CAN Проект
Щеше да е яко, ако расберито си имаше нормален power management, за да го сложиш в low power mode, а не го чакаш да буутва всеки път. Аз за това не го харесвам за енергоефективни проекти.
Face recognition-а е яко, ама още не съм си играл да видя доколко е надежден и как/колко трябва да се обучава за конкретно лице или набор от лица... Ако си пробвал - сподели
На какви ARM-ове точно си пускал OpenCV, че си е драма на повечето...?
Face recognition-а е яко, ама още не съм си играл да видя доколко е надежден и как/колко трябва да се обучава за конкретно лице или набор от лица... Ако си пробвал - сподели
На какви ARM-ове точно си пускал OpenCV, че си е драма на повечето...?
"За тЕя пари има Е-шеесе" - форумна пословица.
Лето две и седемнаесто.
- shadowx
- Потребител
- Мнения: 31
- Регистриран на: 5.04.2016
- Пол: Мъж
- Кара: BMW 120d e87
- Детайли за колата: BMW 120d e87 163hp
Re: K-CAN Проект
Nickelback написа:Щеше да е яко, ако расберито си имаше нормален power management, за да го сложиш в low power mode, а не го чакаш да буутва всеки път. Аз за това не го харесвам за енергоефективни проекти.
Face recognition-а е яко, ама още не съм си играл да видя доколко е надежден и как/колко трябва да се обучава за конкретно лице или набор от лица... Ако си пробвал - сподели
На какви ARM-ове точно си пускал OpenCV, че си е драма на повечето...?
Мдам ... PM няма на ARMтата ...нищо, само с едно бързо махане на неща от init скриптовете и имам стартирано mpd на 19тата секунда... и като го направя
* keyfob_lock_event -> send shutdown (kill the relay 10-15s later).
* keyfob_unlock_event -> power up RPi
Реално, докато влезна в колата, сложа ключа, въведа "кода", сложа колана и вече ще е активен 1000%.
Та и без PM изглежда напълно изпълнимо в разумни граници.
Относно Face recognition.... ами... като с всичко друго при OpenCV....ако си го "обучил" добре, се справя доста добре....that said, ако се прави с една камера (т.е. нямаш 3д) ... снимки си го бъркат лесно
Но, разбираемо.... Face recognition е реално няколко стъпков процес ...1во търсиш лице в кадъра... така остава по-малък таргет за обработване... после в този "таргет" , търсиш очи, нос, уста... ..пак същия филм...разделяш... на тях пък, почваш да проверяваш пропорции .. (Face recognition си е това)... но като имаш 2д образ (т.е. 1 камера само) ... 2д репрезентация (т.е. снимка) отговаря напълно на исканото ... препдолагам OpenCV предлага решение на този пороблем по алтернативен начин, не съм влизал толкова на дълбоко
RPi1B с лек клок (100-200Mhz) се справаше прилично да обработва номера в реално време ... но беше направено със висока резолюция и нисък фрейм рейт ...(и хубава IP камера да подчертая) ..та финта беше така ...камерата предлагаше паралелно и висока и ниска резолюция ... взимаш един фрейм и от 2те... за да откриеш къде има регистрационнен номер, не ти трябва много голяма рез. ...та търсиш в малката снимка (то пак е двоен процес..1во откриваш кола, после търсиш в нея регистрация) ..та като ги откриеш като кординати , смяташ при голямата къде биха се падали и четеш от нея само парчето със регистрационния номер
brain kung-fu е OpenCV-то.... само въображението ограничава какво може да направи човек с него
- Nickelback
- старши ентусиаст
- Мнения: 1857
- Регистриран на: 20.10.2010
- Местоположение: София
- Пол: Мъж
- Кара: BigBlockV8 и чат-пат SmallBlockV8
- Мечтае да кара: бангия с предно
- Детайли за колата: ;)
Big: Hemi 370 cu. in.
Small: S62B50 с жокери
Re: K-CAN Проект
О напротив, ARM-базираните SoC-ове си имат прекрасни възможности за истински power management
Гейтване на клоци, спиране на захранването на отделни машини, self retention на RAM-a и т.н. както си му е реда.
А аз говоря конкретно за RPi, при което:
1. Няма "истински" PMIC чип на борда
2. Някои от драйверите използвани от RPi нямат пълноценна поддръжка на какъвто и да било power moding - например VC4 драйвера, който основно Broadcom си го бутат там.
Та така... не са "ARM-овете" виновни
За някои фийчъри не е приятно 20 секунди време на реакция на системата - основно remote команди. Ти поне не планираш такива, доколкото разбирам.
Иначе ARM рилийзнаха ARM Compute Library (ползва NEON инструкциите и Mali GPU-то).
Като скорост очаквам да се справя по-добре от OpenCV вървящо върху ARM. Предстои да си играя с това и ще споделя
Гейтване на клоци, спиране на захранването на отделни машини, self retention на RAM-a и т.н. както си му е реда.
А аз говоря конкретно за RPi, при което:
1. Няма "истински" PMIC чип на борда
2. Някои от драйверите използвани от RPi нямат пълноценна поддръжка на какъвто и да било power moding - например VC4 драйвера, който основно Broadcom си го бутат там.
Та така... не са "ARM-овете" виновни
За някои фийчъри не е приятно 20 секунди време на реакция на системата - основно remote команди. Ти поне не планираш такива, доколкото разбирам.
Иначе ARM рилийзнаха ARM Compute Library (ползва NEON инструкциите и Mali GPU-то).
Като скорост очаквам да се справя по-добре от OpenCV вървящо върху ARM. Предстои да си играя с това и ще споделя
"За тЕя пари има Е-шеесе" - форумна пословица.
Лето две и седемнаесто.
- shadowx
- Потребител
- Мнения: 31
- Регистриран на: 5.04.2016
- Пол: Мъж
- Кара: BMW 120d e87
- Детайли за колата: BMW 120d e87 163hp
Re: K-CAN Проект
Nickelback написа:О напротив, ARM-базираните SoC-ове си имат прекрасни възможности за истински power management
Гейтване на клоци, спиране на захранването на отделни машини, self retention на RAM-a и т.н. както си му е реда.
А аз говоря конкретно за RPi, при което:
1. Няма "истински" PMIC чип на борда
2. Някои от драйверите използвани от RPi нямат пълноценна поддръжка на какъвто и да било power moding - например VC4 драйвера, който основно Broadcom си го бутат там.
Та така... не са "ARM-овете" виновни
За някои фийчъри не е приятно 20 секунди време на реакция на системата - основно remote команди. Ти поне не планираш такива, доколкото разбирам.
Иначе ARM рилийзнаха ARM Compute Library (ползва NEON инструкциите и Mali GPU-то).
Като скорост очаквам да се справя по-добре от OpenCV вървящо върху ARM. Предстои да си играя с това и ще споделя
GPU ако смята за OpenCV нещата, ще е адски бързо..то си е баш за такъв тип процесори работа Очаквам да споделиш като имаш нещо по въпроса, ще ми е интересно да разгледам
Относно PM ...и да и не..първо да кажа,че най-вече говоря за процесорите които се използват в OPi,RPi,BPi и подобните.... определено, самия хардуер има доста по приличен PM от това което е "достъпно" заради недописани driver-и.... that said ...ARM си е дървено (аз гледам от гледната точка на човек който е израснал с x86 малко или много) ...та очаквам от хардуера в днешно време да мога да изполвам ядрата с динамични честоти , необвързани едно с друго (т.е. да мога да си set-на cpu0 на една честота , cpu1 на друга , cpu2 на 3та)
Също така, мисля,че е донякъде нормално за подобен тип устройство да подръжа suspend to memory и да преминава в low power state ... поправи ме ако греша , но това по дизайн е невъззможно на RPi 1,2,3 ....
За RPi1 е обяснимо...там процесора беше правен за друго ....излезна ,че е дефектен и просто се чудеха кво да го правят и се роди RPi1 ...но за другите....
Иначе има и такива с доста приличен PM... TI имаха cortex-a8 много добри ... от друга страна и пазара малко е виновен ...защото смешния android с неговия малумен PM (имам огромен проблем с PM концепцията им на тези хора) не ги ...нека го наерчем "води" в правилната посока.
p.s. ето нещо да се посмееш малко https://vuldb.com/?id.101724
- shadowx
- Потребител
- Мнения: 31
- Регистриран на: 5.04.2016
- Пол: Мъж
- Кара: BMW 120d e87
- Детайли за колата: BMW 120d e87 163hp
Re: K-CAN Проект
Това даже не е alfa .... все още е само POC, но field tested и изглежда добре.
Някой от нещата връщат грешни данни (среден разход на л/100км например... ), други има частични (волана... отчита градусите само при въртене наляво) и още няколко такива...
Но ...в тази жега, не ми се седи дълго в колата да дебъгвам...а ако ида в подземен гараж на мол с лаптоп и кабели излизащи от таблото .... мдам...
Та... аз на C не мога да пиша ... та, кода е грозен и гаден, но що-годе работещ...та се извинявам предварително , ако някой го заболят очите докато го чете
Иначе освен очеизвадното изписване на статуси през serial port-а, има и това за което говорих с контрола на релето на горивната помпа и кода за "отключване/активация" посредством код /комбинация от копчета/ на волана.
unlock_code[] е array с "паролата"
Ако променяте дължината , променете и PASS_LEN (иначе ще стане една боза с паметта... щото аз малко memcpy-вам тук-там )
Има описана "защита" от рестарт по-време на работа..т.е. няма да ви изключи горивната помпа ако се рестартира по време на работа на двигателя.
Ако обаче настъпи рестарт когато колата е загасена, ще приеме,че е в lockdown режим и при наличие на ключ , ще започне да активира релето до въвеждане на код.
Иначе , ако няма рестарт, lockdown се активира само след заключване от дистанционното.
Като цяло "lockdown" статуса не е лоша идея да се прехвърли във EEPROM-а на Arduino-то ..също така може и "кода" да се запише там...
anyway , всякакъв feedback е полезен.
п.с.: Аз наистина не мога да пиша C (като цяло не мога да програмирам...но и не ми е работа) ..обаче Arudino IDE девелопърите къртят мивки...
#define boolean uint8_t
У-во с 2kb памет и да пляскаш по 8бита за нещо което е 1 бит....
Но за сега кода използва разумно количество памет.
Някой от нещата връщат грешни данни (среден разход на л/100км например... ), други има частични (волана... отчита градусите само при въртене наляво) и още няколко такива...
Но ...в тази жега, не ми се седи дълго в колата да дебъгвам...а ако ида в подземен гараж на мол с лаптоп и кабели излизащи от таблото .... мдам...
Та... аз на C не мога да пиша ... та, кода е грозен и гаден, но що-годе работещ...та се извинявам предварително , ако някой го заболят очите докато го чете
Иначе освен очеизвадното изписване на статуси през serial port-а, има и това за което говорих с контрола на релето на горивната помпа и кода за "отключване/активация" посредством код /комбинация от копчета/ на волана.
unlock_code[] е array с "паролата"
Ако променяте дължината , променете и PASS_LEN (иначе ще стане една боза с паметта... щото аз малко memcpy-вам тук-там )
Има описана "защита" от рестарт по-време на работа..т.е. няма да ви изключи горивната помпа ако се рестартира по време на работа на двигателя.
Ако обаче настъпи рестарт когато колата е загасена, ще приеме,че е в lockdown режим и при наличие на ключ , ще започне да активира релето до въвеждане на код.
Иначе , ако няма рестарт, lockdown се активира само след заключване от дистанционното.
Като цяло "lockdown" статуса не е лоша идея да се прехвърли във EEPROM-а на Arduino-то ..също така може и "кода" да се запише там...
anyway , всякакъв feedback е полезен.
- Код: Избери целия код
/*
carpino.ino - BMW K-CAN Traffic Parsing
Copyright (C) 2017 Georgi Kolev <georgi.kolev gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Credits should mostly go to Trevor Cook <http://loopybunny.co.uk/>
For decoding the K-CAN traffic.
*/
#include "Canbus.h"
#include "defaults.h"
#include "global.h"
#include "mcp2515.h"
#include "mcp2515_defs.h"
#include <PrintEx.h>
#define SERIAL_SPEED 250000
#define RPI_OFFTIME 90000
#define CANSPEED_100 9
#define PASS_LEN 6
#define BUZZER_PIN 8
#define OPI_PIN 7
#define FPR_PIN 6
#define B_VOICE 0
#define B_PHONE 1
#define B_VOLUP 2
#define B_TUNEUP 3
#define B_VOLDOWN 4
#define B_CHANGER 5
#define B_AIRFLOW 6
#define B_TUNEDOWN 7
int tmpint, tmpint2;
int stack_array[PASS_LEN];
unsigned long rpi_deadline;
unsigned long bt_voice, bt_airflow, bt_tuneup, bt_voldown;
unsigned long bt_phone, bt_changer, bt_volup, bt_tunedown;
const int unlock_code[PASS_LEN] = {
B_VOICE, B_CHANGER, B_PHONE, B_VOICE, B_CHANGER, B_PHONE };
const unsigned long btn_threshold = 500; // Threshold long press (ms)
PrintEx serial = Serial;
// This will add the printf() method to "Serial"
//PrintExWrap<typeof(Serial)> &__Serial = PrintEx::wrap(Serial);
//#define Serial __Serial
struct CarValues {
int swheel;
int coolant;
int freemem;
byte fuel;
byte fan_speed;
long odometer;
float speed;
float avr_lkm;
float avr_kmh;
float in_temp;
float ext_temp;
float left_temp;
float right_temp;
char datetime[20];
unsigned int rpm;
unsigned int range;
unsigned char throttle;
unsigned char fl_window;
unsigned char fr_window;
unsigned char rl_window;
unsigned char rr_window;
};
struct CarStatus {
union {
unsigned char value[5];
struct {
unsigned key:1;
unsigned init:1;
unsigned locked:1;
unsigned engine:1;
unsigned reverse:1;
unsigned lockdown:1;
unsigned handbrake:1;
unsigned fuelrelay:1; // 8
// Door status open/lock
unsigned fl_door:1;
unsigned fr_door:1;
unsigned rl_door:1;
unsigned rr_door:1;
unsigned fl_lock:1;
unsigned fr_lock:1;
unsigned rl_lock:1;
unsigned rr_lock:1; // 16
// Hood status open
unsigned hood:1;
// Boot status open/lock
unsigned boot:1;
unsigned boot_lock:1; // TBD
// Low/Main/High Beams
unsigned low_beam:1;
unsigned main_beam:1;
unsigned high_beam:1; // TBD
// Fog lights
unsigned rear_fog:1;
unsigned front_fog:1; // 24
// Others
unsigned term15:1;
unsigned term30:1;
unsigned clutch:1;
unsigned brakes:1;
unsigned demister:1;
unsigned door_alarm:1;
unsigned aircondition:1;
unsigned airconditionmax:1; // 32
unsigned recirculate:1;
unsigned recirculateauto:1;
unsigned rpi;
unsigned hazard_lights;
unsigned left_turnsignal;
unsigned right_turnsignal;
};
};
} __attribute__((packed));
struct CarStatus car;
struct CarValues carv;
// Check free memory
int freeRam() {
int v;
extern int __heap_start, *__brkval;
return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
}
// RPi Power Relay Functions
void rpi_on() { digitalWrite(FPR_PIN, 1); car.rpi = 1; }
void rpi_off() { digitalWrite(FPR_PIN, 0); rpi_deadline = 0; car.rpi = 0; }
void rpi_shutdown() { rpi_deadline = millis() + RPI_OFFTIME; }
// Fuel Relay Control Function
void fpr_control(boolean s) {
car.fuelrelay = scheck("fuel_relay", s, car.fuelrelay);
digitalWrite(FPR_PIN, car.fuelrelay);
memset(stack_array, 0, (sizeof(int) * PASS_LEN));
}
// Add to button stack
void button_stack(int p) {
if (car.init && car.lockdown) {
stack_push(p);
if (arrcmp(unlock_code, stack_array, PASS_LEN)) {
Serial.println("auth=true");
fpr_control(0);
car.lockdown = 0;
tone(BUZZER_PIN, 6000, 100);
} else { // DEBUG ONLY
Serial.print("arrcmp(");
for (int n=0; n<PASS_LEN; n++)
Serial.print(stack_array[n]);
Serial.print(", ");
for (int n=0; n<PASS_LEN; n++)
Serial.print(unlock_code[n]);
Serial.println(")");
}
}
}
// LIFO Stack Push
void stack_push(int p) {
int temp_array[PASS_LEN-1];
memcpy(temp_array, stack_array, (sizeof(int) * (PASS_LEN-1)));
memcpy(&stack_array[1], temp_array, (sizeof(int) * (PASS_LEN-1)));
stack_array[0] = p;
}
// Compare arrays
boolean arrcmp(int a[], int b[], int n) {
int i = 0;
boolean c = true;
while(i < n && c) {
c = a[i] == b[i];
i++;
}
return c;
}
// Short/Long Button Press
int long_press(unsigned long ptime) {
if ((millis() - ptime) > btn_threshold)
return 2;
return 1;
}
// int/status check
int scheck(char pstr[], unsigned nval, unsigned cval) {
if (cval != nval) pprint(pstr, nval, 0);
return nval;
}
// Float value check
int vcheck(char pstr[], float nval, float cval) {
if (cval != nval) pprint(pstr, 0, nval);
return nval;
}
// Custom print function
void pprint(char pstr[], unsigned pint,float pdig) {
if (pdig) serial.printf("%s=%4.2f\n", pstr, pdig);
else serial.printf("%s=%u\n", pstr, pint);
Serial.flush();
}
// Get top/bottom (high/low) 4 bits
int low_bits(int b) { return b & 0xF; }
int high_bits(int b) { return (b>>4) & 0xF; }
// Initial Setup
void setup() {
car.init = 0;
// Setup serial port
Serial.begin(SERIAL_SPEED);
// Initizalize
Serial.print("Init...");
// PINs
pinMode(OPI_PIN, OUTPUT);
pinMode(FPR_PIN, OUTPUT);
pinMode(BUZZER_PIN, OUTPUT);
tone(BUZZER_PIN, 6000, 100);
// Initialize CAN Bus
if(Canbus.init(CANSPEED_100))
Serial.println("OK");
else
Serial.println("FAIL");
carv.freemem = scheck("free_memory", freeRam(), carv.freemem);
}
// Main Loop
void loop(){
tCAN message;
// Fuel relay lock/unlock
if (car.init) {
if ((!car.key) && car.fuelrelay) fpr_control(0);
if (car.key && car.lockdown && (!car.fuelrelay)) fpr_control(1);
}
// RPi on/off relay
if ((!car.rpi) && car.engine) rpi_on();
if (rpi_deadline && car.rpi && (millis() > rpi_deadline)) rpi_off();
// check for message from the can bus
if (mcp2515_check_message()) {
if (mcp2515_get_message(&message)) {
switch (message.id) {
case 0x1D6: // Steering wheel buttons
// Volume UP
if (bitRead(message.data[0], 3) && (!bt_volup)) {
bt_volup = millis();
} else if ((!bitRead(message.data[0], 3)) && bt_volup) {
pprint("bt_volup", long_press(bt_volup), 0);
button_stack(B_VOLUP);
bt_volup = 0;
}
if (bitRead(message.data[0], 2) && (!bt_voldown)) {
bt_voldown = millis();
} else if ((!bitRead(message.data[0], 2)) && bt_voldown) {
pprint("bt_voldown", long_press(bt_voldown), 0);
button_stack(B_VOLDOWN);
bt_voldown = 0;
}
if (bitRead(message.data[1], 0) && (!bt_voice)) {
bt_voice = millis();
} else if ((!bitRead(message.data[1], 0)) && bt_voice) {
pprint("bt_voice", long_press(bt_voice), 0);
button_stack(B_VOICE);
bt_voice = 0;
}
if (bitRead(message.data[0], 0) && (!bt_phone)) {
bt_phone = millis();
} else if ((!bitRead(message.data[0], 0)) && bt_phone) {
pprint("bt_phone", long_press(bt_phone), 0);
button_stack(B_PHONE);
bt_phone = 0;
}
if (bitRead(message.data[1], 6) && (!bt_changer)) {
bt_changer = millis();
} else if ((!bitRead(message.data[1], 6)) && bt_changer) {
pprint("bt_changer", long_press(bt_changer), 0);
button_stack(B_CHANGER);
bt_changer = 0;
}
if (bitRead(message.data[1], 4) && (!bt_airflow)) {
bt_airflow = millis();
} else if ((!bitRead(message.data[1], 4)) && bt_airflow) {
pprint("bt_airflow", long_press(bt_airflow), 0);
button_stack(B_AIRFLOW);
bt_airflow = 0;
}
if (bitRead(message.data[0], 5) && (!bt_tuneup)) {
bt_airflow = millis();
} else if ((!bitRead(message.data[0], 5)) && bt_tuneup) {
pprint("bt_tuneup", long_press(bt_tuneup), 0);
button_stack(B_TUNEUP);
bt_tuneup = 0;
}
if (bitRead(message.data[0], 4) && (!bt_tunedown)) {
bt_airflow = millis();
} else if ((!bitRead(message.data[0], 4)) && bt_tunedown) {
pprint("bt_tunedown", long_press(bt_tunedown), 0);
button_stack(B_TUNEDOWN);
bt_tunedown = 0;
}
break;
case 0x23A: // Keyfob
if (bitRead(message.data[2], 2) && (!car.locked)) {
rpi_shutdown();
car.locked = 1;
car.lockdown = 1;
Serial.println("keyfob=lock");
}
if (bitRead(message.data[2], 0) && car.locked) {
rpi_on();
car.locked = 0;
Serial.println("keyfob=unlock");
}
if (bitRead(message.data[3], 4) && car.boot_lock) {
car.boot_lock = 0;
Serial.println("keyfob=boot");
}
break;
case 0x3B0: // Rerverse gear
car.reverse = scheck("reverse", bitRead(message.data[0], 7), car.reverse);
break;
case 0x32E: // Internal Temperature
carv.in_temp = vcheck("in_temp", ((message.data[3] / 10) + 6), carv.in_temp);
break;
case 0x1D0: // Coolant
carv.coolant = vcheck("coolant", (message.data[0] - 48), carv.coolant);
break;
case 0xAA: // RPM, Throttle
carv.rpm = scheck("rpm",
(((message.data[5] * 0x100) + message.data[4]) / 4), carv.rpm);
carv.throttle = scheck("throttle",
(((message.data[3] * 0x100) + message.data[2]) / 256), carv.throttle);
if ((carv.rpm > 0) && (!car.engine))
car.engine = scheck("engine", 1, car.engine);
else if ((!carv.rpm) && car.engine)
car.engine = scheck("engine", 0, car.engine);
// We should this case if the board restarts while the car is running
// It will be bad if we shut it down.
if (!car.init) {
car.init = 1;
if (carv.rpm) {
car.lockdown = 0; Serial.println("unlock=forced");
} else {
car.lockdown = 1; Serial.println("lockdown=on");
}
}
break;
case 0x1B4: // Speed, Handbreak
carv.speed = vcheck("speed",
(((((message.data[1] - 0xC0) * 256) + message.data[0]) / 16) * 1.6), carv.speed);
//car.handbrake = scheck("handbrake", bitRead(message.data[5], 1), bitRead(car.handbrake,0));
break;
case 0x330: // Odmeter & Range are also in this ID
//carv.range = ("range", (((message.data[7] * 256) + message.data[6]) / 16), carv.range);
carv.fuel = scheck("fuel", message.data[3], carv.fuel);
carv.odometer = ((message.data[2] * 0x10000) + (message.data[1] * 0x100) + message.data[0]);
Serial.print("odometer=");
Serial.println(carv.odometer);
break;
case 0x34F: // Handbreak
car.handbrake = scheck("handbrake", bitRead(message.data[0], 6), car.handbrake);
break;
//case 0x2CA: // Outside Temperature (Missing on e87. Check for ext_temp.)
//carv.out_temp = vcheck("out_temp", ((message.data[0] - 80) / 2.0), carv.out_temp);
//break;
case 0x130: // Engine & Key Status
car.key = scheck("key", bitRead(message.data[1], 6), car.key);
car.term15 = scheck("term15", bitRead(message.data[0], 2), car.term15);
car.clutch = scheck("clutch", bitRead(message.data[2], 6), car.clutch);
if (!car.init) {
car.init = 1;
if (!car.key) {
car.lockdown = 1;
Serial.println("lockdown=nokey");
}
}
break;
case 0x24B: // Door Alarms
if (message.data[0]) car.door_alarm = scheck("door_alarms", 1, car.door_alarm);
else car.door_alarm = scheck("door_alarms", 0, car.door_alarm);
break;
case 0x21A: // Lights
car.brakes = scheck("brakes", bitRead(message.data[0], 7), car.brakes);
car.rear_fog = scheck("rear_fog", bitRead(message.data[0], 6), car.rear_fog);
car.low_beam = scheck("low_beam", bitRead(message.data[0], 2), car.low_beam);
car.front_fog = scheck("front_fog", bitRead(message.data[0], 5), car.front_fog);
car.main_beam = scheck("main_beam", bitRead(message.data[0], 0), car.main_beam);
//car.interior_light = scheck("interior_light",
// bitRead(message.data[0], 6), car.interior_light);
break;
case 0x246: // Rear demister
car.demister = scheck("demister", bitRead(message.data[0], 1), car.demister);
break;
case 0x2E6: // Left clima temp & Fan speed
carv.left_temp = vcheck("left_temp", (message.data[7] / 2.0), carv.left_temp);
carv.fan_speed = scheck("fan_speed", message.data[5], carv.fan_speed);
break;
case 0x2EA: // Right clima temp
carv.right_temp = vcheck("right_temp", (message.data[7] / 2.0), carv.right_temp);
break;
case 0x366: // External Temp, Range
carv.freemem = scheck("free_memory", freeRam(), carv.freemem);
carv.range = scheck("range",
((((message.data[2] * 256) + message.data[1]) / 16)), carv.range);
carv.ext_temp = vcheck("ext_temp", ((message.data[0] - 80) / 2.0), carv.ext_temp);
break;
case 0x2FC: // Door & Boot Status
car.fl_door = scheck("fl_door", bitRead(message.data[1], 0), car.fl_door);
car.fr_door = scheck("fr_door", bitRead(message.data[1], 3), car.fr_door);
car.rl_door = scheck("rl_door", bitRead(message.data[1], 5), car.rl_door);
car.rr_door = scheck("rr_door", bitRead(message.data[1], 7), car.rr_door);
car.boot = scheck("boot", bitRead(message.data[2], 0), car.boot);
break;
case 0x3B6: // Front left window
carv.fl_window = scheck("fl_window", message.data[0], carv.fl_window);
break;
case 0x3B7: // Rear left window
carv.rl_window = scheck("rl_window", message.data[0], carv.rl_window);
break;
case 0xC8: // Steering wheel angle (FIX THIS!)
tmpint = (((message.data[1] * 0xFF) + message.data[0]) / 23);
tmpint2 = ((((message.data[1] * 0xFF) + message.data[0]) - 0xFFFF) / 23);
if (tmpint < 360 && tmpint > -1)
carv.swheel = scheck("steering_wheel", tmpint, carv.swheel);
if (tmpint2 < -360 && 1 > tmpint2)
carv.swheel = scheck("steering_wheel", tmpint2, carv.swheel);
break;
case 0x3B8: // Front reft window
carv.fr_window = scheck("fr_window", message.data[0], carv.fr_window);
break;
case 0x3B9: // Rear right window
carv.rr_window = scheck("rr_window", message.data[0], carv.rr_window);
break;
case 0x1F6: // turn signal/Hazzard Lights (testing)
if (message.data[0] == 0x91) {
car.left_turnsignal = scheck("left_turnsignal", 1, car.left_turnsignal);
} else if (message.data[0] == 0xA1) {
car.right_turnsignal = scheck("right_turnsignal", 1, car.right_turnsignal);
} else if (message.data[0] == 0xB1) {
car.hazard_lights = scheck("hazard_lights", 1, car.hazard_lights);
} else {
car.left_turnsignal = scheck("left_turnsignal", 0, car.left_turnsignal);
car.right_turnsignal = scheck("right_turnsignal", 0, car.right_turnsignal);
car.hazard_lights = scheck("hazard_lights", 0, car.hazard_lights);
}
break;
//case 0xF2: // Boot Lock (Missing in e87?)
case 0x1EE: // Indicator Stalk position (testing)
car.high_beam = scheck("high_beam", bitRead(message.data[0], 4), car.high_beam);
car.left_turnsignal = scheck("left_turnsignal", bitRead(message.data[0], 3), car.left_turnsignal);
car.right_turnsignal = scheck("right_turnsignal", bitRead(message.data[0], 1), car.right_turnsignal);
if (message.data[0] == 0x01) Serial.println("right_blink=1");
else if (message.data[0] == 0x04) Serial.println("left_blink=1");
else if (message.data[0] == 0x20) Serial.println("highbeam_flash=1");
break;
//case 0x252: // Windscreen Wiper Status (TBD)
//case 0x2A6: // Windscreen Wiper Controls (TBD)
//case 0x349: // Left/Right Fuel Sensor (TBD)
//case 0x328: // Battery Reset, Production date (TBD)
case 0x362: // Average KM/h & l/100km (l/km wrong?)
Serial.print(" 0x362 ");
Serial.print(message.data[0], HEX); Serial.print(" ");
Serial.print(message.data[1], HEX); Serial.print(" ");
Serial.println(message.data[2], HEX);
carv.avr_lkm = vcheck("avr_lkm", (235.214 *
((message.data[2] + (high_bits(message.data[1]) * 0x100)) / 10)), carv.avr_lkm);
// ((message.data[2] * 0x10) + high_bits(message.data[1])) / 10), carv.avr_lkm);
carv.avr_kmh = vcheck("avr_kmh",
((message.data[0] + (low_bits(message.data[1]) * 0x100)) / 10), carv.avr_kmh);
break;
case 0x380: // VIN
Serial.print("vin=");
for (int u=0; u < message.header.length; u++) {
char c = (char) message.data[u];
Serial.print(c);
}
Serial.println();
break;
case 0x2F8: // Time & Date
Serial.print("datetime=");
sprintf(carv.datetime, "%02d:%02d:%02d %02d/%02d/%d",
message.data[0], message.data[1], message.data[2],
message.data[3], high_bits(message.data[4]),
((message.data[6] * 0x100) + message.data[5]));
carv.datetime[20] = '\0';
Serial.println(carv.datetime);
break;
case 0x242: // AC Status, Air Recirculation
car.recirculate = scheck("recirculate",
bitRead(message.data[0], 5), car.recirculate);
car.aircondition = scheck("aircondition",
bitRead(message.data[0], 0), car.aircondition);
car.airconditionmax = scheck("ac_max",
bitRead(message.data[0], 2), car.airconditionmax);
car.recirculateauto = scheck("recirculate_auto",
bitRead(message.data[0], 4), car.recirculateauto);
break;
case 0x26E: // Testing
if (message.data[1])
car.term30 = scheck("term30", 1, car.term30);
else
car.term30 = scheck("term30", 0, car.term30);
break;
default: // When done with the known traffic we should start printing what is left
break;
}
}
}
}
п.с.: Аз наистина не мога да пиша C (като цяло не мога да програмирам...но и не ми е работа) ..обаче Arudino IDE девелопърите къртят мивки...
#define boolean uint8_t
У-во с 2kb памет и да пляскаш по 8бита за нещо което е 1 бит....
Но за сега кода използва разумно количество памет.
Sketch uses 12,574 bytes (38%) of program storage space. Maximum is 32,256 bytes.
Global variables use 1,197 bytes (58%) of dynamic memory, leaving 851 bytes for local variables. Maximum is 2,048 bytes.
- mrwrong
- кандидат ентусиаст
- Мнения: 77
- Регистриран на: 17.01.2020
- Местоположение: Пловдив
- Пол: Мъж
- Кара: F10 LCI 530xD
- Мечтае да кара: Самолет
- Детайли за колата: Убава йе. Има 4 колелета.
Re: K-CAN Проект
Малко да посъживя темата. Някой успял ли е да изправи по K-can шината някой код който да бъде изпълнен от колата. Имам предвид примерно да накара да мигат мигачите. За сега успявам само да слушам командите по шината , но не успявам да изпълня команда. Ще се радвам ако някой сподели опит.
40 мнения
• Страница 3 от 3 • 1, 2, 3
Кой е на линия
Потребители разглеждащи този форум: 0 регистрирани