

Kiitoksia
Koodi: Valitse kaikki
void FanControl()
{
unsigned long FCcurrentMillis = millis(); // Record current time
if (FCcurrentMillis - FClastExecutedMillis >= FC_EXE_INTERVAL) //If elapsed time from last execution is more than the specified interval
{
FClastExecutedMillis = FCcurrentMillis;
if ((bCastMsg.clt-32)*5/9 >= 90 && FCstatus == 0)
{
digitalWrite(FCpin, HIGH);
Serial.println("Fan ON");
FCstatus = 1;
}
else if((bCastMsg.clt-32)*5/9 <= 87 && FCstatus == 1)
{
digitalWrite(FCpin, LOW);
Serial.println("Fan OFF");
FCstatus = 0;
}
Serial.println((bCastMsg.clt-32)*5/9);
}
}
Näinhän se on tuon lukon kanssa, ei sitä perää jaksa joka viikko pöydälle nostaa. Täytyy tutkailla vaihtoehtoja. Vaikka pakosarjan sopivuus on kiinan sarjan luokkaa, niin tuo on ihan turbobanditin valmistama. Ajattelin ostaa kunnollisen ja kuinka kävikäänMJPfin kirjoitti: ↑Ke 06.12.2023 12:00 Noi pilipala "lukot" kannattaa jättää sinne kauppaan, ei ne kestä edes talven suddailua saati sitten kesällä pitoja.
Kunnon lukko vaan kaupasta, kerran se kirpaisee ja on sitten sellainen että ei tarvitse joka hetki räplätä.
Pakosarja on hyvä pinnoittaa, auttaa lämpöjen kanssa ja ahtimen heräämiseen. Noista kiinan sarjoista sen verran että kannattaa ahdin tukea hyvin moottoriin, muuten pääset parsimaan halkeemia tämän tästä.
Tiedä sitten. Varmaa on se, että toista kertaa en sieltä sarjoja osta.
KiitosMJPfin kirjoitti: ↑To 28.12.2023 21:33 Hyvää settiä taas!
Nokassa vähän "rokkoa", melkein pinnottaisin tuon keraamisella liukupinnoitteella että ei nostaja taas lähde kulumaan.
Saman kaltaista ongelmaa oli klonkswageni riiselissä ja se korjaantui techlinen cermalube pinnoitteella.
Tulee kyllä makea laite tuosta kunhan valmiiksi saat!
Kiitokset
Tarvikemotista katselin jotain vaihtoehtoja, mutta heikosti oli saatavuutta. 16mm banjo ja 12-13mm letkulähtö tarvitsisi olla. Löytyisköhän jostain hydrauliikkaliikkeestä? Mielessä kävi jo, että itse taivuttelisi ja hitsaisi pätkät väliin.MJPfin kirjoitti: ↑La 16.03.2024 12:36 Noot vesilähdöt kannattaa viedä sellaiset 150-200mm putkella pois turbon rungon vierestä ennen kuin vetää letkulla.
Se on aika ikävää kun vesiletku päättää että liian kuuma ja lähtee irti.
Kauheasti savuhöyry juttua pellin alta ja paniikki että nytkö se räjähti. Ja hirveä siivoaminen
Tuo palosuoja kävi mielessä myös, on vaan hintava vaihtoehtoepk kirjoitti: ↑La 16.03.2024 13:09 noihin saa myös palosuojaletkua, ainakin mustaa ja punaista. Laittaa vielä oetiker letkunkiristimen niin mahtuu vetää ns. ylitse asti koko suojaletkun.
esim. : https://www.usparts.fi/performance/letk ... /palosuoja
Täytyy myöntää, että on niitä joskus itsekin tullut tehtyä... 10v omistajuuden aikana on vaan päässyt käymään niin, että itse ne on saanut korjata
Kiitokset. Kieltämättä tuo on käynyt mielessä. Perästä saisi ABS-anturilta tiedon ja tuon jo kiinni olevan Arduinon kanssa saisi tiedon mittarille asti melko pienellä vaivalla. Sattuu olemaan hyllyssä pussillinen toimintasavuttomia MAX9926 muuntimiakin. Lutikoitakin löytyisi niihin.
Koodi: Valitse kaikki
void ICSControl()
{
unsigned long ICSCcurrentMillis = millis(); // Record current time
if (ICSCcurrentMillis - ICSClastExecutedMillis >= ICSC_EXE_INTERVAL) //If elapsed time from last execution is more than the specified interval
{
ICSClastExecutedMillis = ICSCcurrentMillis;
//If throttle position is above 80 %, MAP above 150 kPa, IAT temperature more than 20°C above ambient
if (bCastMsg.tps >= 80 && bCastMsg.map >= 150 && (((bCastMsg.clt-32)*5/9)-(ATaverage/10)) >= 20 && ICSCstatus == 0)
{
digitalWrite(ICSCpin, HIGH);
Serial.println("IC Spray ON");
ICSCstatus = 1;
}
//Or if IAT temperature more than 30°C above ambient and speed more than 30 km/h and spray was last on more than 15s ago
else if ((((bCastMsg.clt-32)*5/9)-(ATaverage/10)) >= 30 && bCastMsg.gps_speed*3.6 > 30 && ICSCstatus == 0 && ICSCcurrentMillis - ICSCOnMillis >= 15000)
{
digitalWrite(ICSCpin, HIGH);
Serial.println("IC Spray ON");
ICSCstatus = 1;
ICSCOnMillis = ICSCcurrentMillis;
}
else
{
digitalWrite(ICSCpin, LOW);
Serial.println("IC Spray OFF");
ICSCstatus = 0;
}
if(ICSCcurrentMillis - ICSCOnMillis >= 3000)
{
digitalWrite(ICSCpin, LOW);
Serial.println("IC Spray OFF");
ICSCstatus = 0;
}
}
}
Koodi: Valitse kaikki
#include <SPI.h>
#include <mcp2515.h> //https://github.com/autowp/arduino-mcp2515
#include <MegaCAN.h> //https://github.com/mantonakakis1/MegaCAN
//Sensor libraries
//Ambient temperature
#include <MBAmbientTemp.h>
AmbientTemp AT;
#define AT_EXE_INTERVAL 200 // How often Ambient Temperature is measured (ms)
unsigned long ATlastExecutedMillis = 0; // Variable to save the last executed time
//Oil Pressure
#include <MBOilPressure.h>
OilPressure OP;
#define OP_EXE_INTERVAL 50 // How often Oil Pressure is measured (ms)
unsigned long OPlastExecutedMillis = 0; // Variable to save the last executed time
//Fuel Amount
#include <MBFuelAmount.h>
FuelAmount FA;
#define FA_EXE_INTERVAL 100 // How often Fuel Amount is measured (ms)
#define FW_EXE_INTERVAL 100 // How often Fuel Warning is measured (ms)
unsigned long FAlastExecutedMillis = 0; // Variable to save the last executed time
unsigned long FWlastExecutedMillis = 0; // Variable to save the last executed time
//Outputs
//Fan Control
#define FC_EXE_INTERVAL 1000 // How often Fan Control algo runs (ms)
unsigned long FClastExecutedMillis = 0; // Variable to save the last executed time
const int FCpin = 36; // Physical pin
bool FCstatus;
//IC Spray Control
#define ICSC_EXE_INTERVAL 300 // How often IC Spray Control algo runs (ms)
unsigned long ICSClastExecutedMillis = 0; // Variable to save the last executed time
unsigned long ICSCOnMillis = 0; // Variable to save the last executed time
const int ICSCpin = 37; // Physical pin
bool ICSCstatus;
//Camshaft Control
#define CS_EXE_INTERVAL 200 // How often Fan Control algo runs (ms)
unsigned long CSlastExecutedMillis = 0; // Variable to save the last executed time
const int CSpin = 19; // Physical pin
bool CSstatus;
//Test variable for outputs
int output = 1;
//MegaCAN
#define CELSIUS // MegaCAN uses Fahrenheit, which is no good. This transforms broadcasted temperatures to Celsius
//MegaCAN
const uint32_t baseID = 1512; // Must set to match Megasquirt Settings!
const uint32_t finalID = baseID + 17; // Must set to match Megasquirt Settings configured in TunerStudio! The last group of data broadcasted.
//MCP2515 related
struct can_frame receivedFrame;
MCP2515 mcp2515(10); //CS at D10
MegaCAN MegaCAN; // For processed Megasquirt CAN protocol messages
MegaCAN_message_t recMsgMSC; // Stores received message from Megasquirt, Megasquirt CAN protocol
MegaCAN_message_t respMsgMSC; // Stores response message back to Megasquirt, Megasquirt CAN protocol
MegaCAN_broadcast_message_t bCastMsg; // Stores unpacked Megasquirt broadcast data, e.g. bCastMsg.rpm
struct can_frame respMsg; // Actual response message back to Megasquirt, MSCAN protocol
uint16_t GPIOADC[8] = { 0 }; // Stores values to send to Megasquirt, 4 ADCS for each message
uint16_t adc0 = 0;
uint16_t adc1 = 0;
uint16_t adc2 = 0;
uint16_t adc3 = 0;
uint16_t adc4 = 0;
uint16_t adc5 = 0;
uint16_t adc6 = 0;
uint16_t adc7 = 0;
//Variables for averaging of sensor values
//AT
const int ATnumReadings = 10;
int ATreadings[ATnumReadings]; // The readings from the analog input
int ATreadIndex = 0; // The index of the current reading
int ATtotal = 0; // The running total
int ATaverage = 0; // The average
//OP
const int OPnumReadings = 10;
int OPreadings[OPnumReadings]; // The readings from the analog input
int OPreadIndex = 0; // The index of the current reading
int OPtotal = 0; // The running total
int OPaverage = 0; // The average
//FA
const int FAnumReadings = 100;
int FAreadings[FAnumReadings]; // The readings from the analog input
int FAreadIndex = 0; // The index of the current reading
int FAtotal = 0; // The running total
int FAaverage = 0; // The average
//FW
const int FWnumReadings = 100;
int FWreadings[FWnumReadings]; // The readings from the input
int FWreadIndex = 0; // The index of the current reading
int FWtotal = 0; // The running total
int FWaverage = 0; // The average
void initializeCAN() {
mcp2515.reset();
mcp2515.setBitrate(CAN_500KBPS, MCP_8MHZ); //Megasquirt specific 500kbs
mcp2515.setNormalMode();
}
void canMShandler(const can_frame &msg) {
// For Megasquirt CAN protocol, MS is requesting data:
if ((msg.can_id & CAN_EFF_FLAG) != 0) { //Data request from MS uses extended flag, there may be a better way to implement this with more advanced applications, works fine for sending data to MS GPIOADC
sendDataToMS(msg); //Due to the extended flag, we assume this is a MS data request and run the function to send data to MS, passing the message received from MS to the sendDataToMS function
}
// For Megasquirt CAN broadcast data:
else { //Broadcast data from MS does not use extended flag, therefore a standard message from MS will contain broadcast data
//Unpack megasquirt broadcast data into bCastMsg:
MegaCAN.getBCastData(msg.can_id, msg.data, bCastMsg); //baseID fixed in library based on const parameter entered for baseID above - converts the raw CAN id and buf to bCastMsg format
if (msg.can_id == finalID) {
/*~~~Final message for this batch of data, do stuff with the data - this is a simple example~~~*/
Serial.print(bCastMsg.map); Serial.print(" | "); //should be kPa
Serial.print(bCastMsg.rpm); Serial.print(" | "); //should be rpm
Serial.println(bCastMsg.tps); //should be %
}
}
}
void sendDataToMS(can_frame msg) {
MegaCAN.processMSreq(msg.can_id, msg.data, recMsgMSC); // Unpack request message ("msg") from MS into recMsgMS
// Create a bitmask for output states
uint16_t outputStates = 0;
outputStates |= (FCstatus << 0); // Bit 0: Fan Control
outputStates |= (ICSCstatus << 1); // Bit 1: IC Spray Control
outputStates |= (CSstatus << 2); // Bit 2: Camshaft Control
// Store outputStates in adc4
adc4 = outputStates;
if (recMsgMSC.core.toOffset == 2) { //For GPIOADC0-3
GPIOADC[0] = adc0; //Ambient Temperature
GPIOADC[1] = adc1; //Oil Pressure
GPIOADC[2] = adc2; //Fuel Amount
GPIOADC[3] = adc3; //Fuel Warning. ADC is not the best solution for an on/off, but will do
MegaCAN.setMSresp(recMsgMSC, respMsgMSC, GPIOADC[0], GPIOADC[1], GPIOADC[2], GPIOADC[3]); //Packs the GPIOADC0-3 values into "respMsgMSC"
}
else if (recMsgMSC.core.toOffset == 10) { //For GPIOADC4-7
GPIOADC[4] = adc4; //Output states
GPIOADC[5] = adc5; //vacant
GPIOADC[6] = adc6; //vacant
GPIOADC[7] = adc7; //vacant
MegaCAN.setMSresp(recMsgMSC, respMsgMSC, GPIOADC[4], GPIOADC[5], GPIOADC[6], GPIOADC[7]); //Packs the GPIOADC4-7 values into "respMsgMSC"
}
// Send response to Megasquirt using MSCAN protocol:
respMsg.can_id = respMsgMSC.responseCore | CAN_EFF_FLAG; //CAN_EFF_FLAG added to the end of response message, otherwise MS will not use it
respMsg.can_dlc = sizeof(respMsgMSC.data.response);
for (int i = 0; i < respMsg.can_dlc; i++) {
respMsg.data[i] = respMsgMSC.data.response[i];
}
mcp2515.sendMessage(&respMsg); //Sends the GPIOADC values stored in respMsg over CAN to Mesasquirt
//Serial.println("Data sent to Megasquirt");
}
void setup()
{
while (!Serial);
Serial.begin(115200);
Serial.println("MAP | RPM | TPS");
initializeCAN();
pinMode(33, INPUT); //Fuel warning indicator switch
pinMode(FCpin, OUTPUT); //Fan Control
pinMode(ICSCpin, OUTPUT); //Intercooler spray
pinMode(CSpin, OUTPUT); //Camshaft Control
digitalWrite(FCpin, LOW);
digitalWrite(ICSCpin, LOW);
digitalWrite(CSpin, LOW);
//Setup Ambient Temp readings
for (int ATthisReading = 0; ATthisReading < ATnumReadings; ATthisReading++) //As long as thisReading is smaller than numReadings, add to thisReading
{
ATreadings[ATthisReading] = 0;
}
AT.init(A2, 40); //Current from D40 and measuring voltage from A2
//Setup Oil Pressure readings
for (int OPthisReading = 0; OPthisReading < OPnumReadings; OPthisReading++) //As long as thisReading is smaller than numReadings, add to thisReading
{
OPreadings[OPthisReading] = 0;
}
OP.init(A0, 35); //Current from D35 and measuring voltage from A0
//Setup Fuel Amount readings
for (int FAthisReading = 0; FAthisReading < FAnumReadings; FAthisReading++) //As long as thisReading is smaller than numReadings, add to thisReading
{
FAreadings[FAthisReading] = 0;
}
FA.init(A1, 32); //Current from D32 and measuring voltage from A1
}
void loop() {
onReceived(); //Read messages from CAN-bus
getAT(); //Read Ambient Temperature and handle signal
getOP(); //Read Oil Pressure and handle signal
getFA(); //Read Fuel Amount and handle signal
getFW(); //Read Fuel Warning switch and handle signal
//Outputs
FanControl();
ICSControl();
CSControl();
output_test();
}
void onReceived()
//Listen to CAN-bus and run canMShandler after
{
if (mcp2515.readMessage(&receivedFrame) == MCP2515::ERROR_OK)
{
canMShandler(receivedFrame);
/*
Serial.println("Received message:");
Serial.println(" ID: 0x" + String(receivedFrame.can_id, HEX));
Serial.println(" DLC: " + String(receivedFrame.can_dlc));
Serial.println(" Data: " + String(receivedFrame.data[0]) + " " +
String(receivedFrame.data[1]) + " " +
String(receivedFrame.data[2]) + " " +
String(receivedFrame.data[3]) + " " +
String(receivedFrame.data[4]) + " " +
String(receivedFrame.data[5]) + " " +
String(receivedFrame.data[6]) + " " +
String(receivedFrame.data[7]));
*/
}
}
void getAT()
{
unsigned long ATcurrentMillis = millis(); // Record current time
if (ATcurrentMillis - ATlastExecutedMillis >= AT_EXE_INTERVAL) //If elapsed time from last execution is more than the specified interval
{
ATlastExecutedMillis = ATcurrentMillis; // save the last executed time
//AT
AT.measure(5, 1024, 10000, 3007, 3848, false); //float VCC,int _ADC, float R1, int R25, int Beta, bool prints
ATtotal = ATtotal - ATreadings[ATreadIndex]; // subtract the last reading
ATreadings[ATreadIndex] = AT.ambienttempvalue * 10; // read from the sensor
ATtotal = ATtotal + ATreadings[ATreadIndex]; // add the reading to the total
ATreadIndex = ATreadIndex + 1; // advance to the next position in the array
if (ATreadIndex >= ATnumReadings) // if we're at the end of the array...
{
ATreadIndex = 0; // ...wrap around to the beginning
}
ATaverage = ATtotal / ATnumReadings; // calculate the average
adc0 = ATaverage; // Insert average to variable adc0
//Serial.println(adc0);
}
}
void getOP()
{
unsigned long OPcurrentMillis = millis(); // Record current time
if (OPcurrentMillis - OPlastExecutedMillis >= OP_EXE_INTERVAL) //If elapsed time from last execution is more than the specified interval
{
OPlastExecutedMillis = OPcurrentMillis; // save the last executed time
//OP
OP.measure(5, 1024, 100, 10, 69, 129, 184, false); //float VCC, int _ADC, float R1, int R_0BAR, int R_1BAR, int R_2BAR, int R_3BAR, bool prints
OPtotal = OPtotal - OPreadings[OPreadIndex]; // subtract the last reading
OPreadings[OPreadIndex] = OP.oilpressurevalue * 100; // read from the sensor
OPtotal = OPtotal + OPreadings[OPreadIndex]; // add the reading to the total
OPreadIndex = OPreadIndex + 1; // advance to the next position in the array
if (OPreadIndex >= OPnumReadings) // if we're at the end of the array...
{
OPreadIndex = 0; // ...wrap around to the beginning:
}
OPaverage = OPtotal / OPnumReadings; // calculate the average
adc1 = OPaverage; // Insert average to variable adc1
//Serial.println(adc1);
}
}
void getFA()
{
unsigned long FAcurrentMillis = millis(); // Record current time
if (FAcurrentMillis - FAlastExecutedMillis >= FA_EXE_INTERVAL) //If elapsed time from last execution is more than the specified interval
{
FAlastExecutedMillis = FAcurrentMillis; // save the last executed time
//FA
FA.measure(5, 1024, 10, 2, 78, false); //float VCC,int _ADC, float R1, int R_Full, int R_Empty, bool prints
FAtotal = FAtotal - FAreadings[FAreadIndex]; // subtract the last reading
FAreadings[FAreadIndex] = FA.fuelamountvalue * 100; // read from the sensor
FAtotal = FAtotal + FAreadings[FAreadIndex]; // add the reading to the total
FAreadIndex = FAreadIndex + 1; // advance to the next position in the array
if (FAreadIndex >= FAnumReadings) // if we're at the end of the array...
{
FAreadIndex = 0; // ...wrap around to the beginning
}
FAaverage = FAtotal / FAnumReadings; // calculate the average
adc2 = FAaverage; // Insert average to variable adc2
//Serial.println(adc2);
}
}
void getFW()
{
unsigned long FWcurrentMillis = millis(); // Record current time
if (FWcurrentMillis - FWlastExecutedMillis >= FW_EXE_INTERVAL) //If elapsed time from last execution is more than the specified interval
{
FWlastExecutedMillis = FWcurrentMillis; // save the last executed time
//FW
FWtotal = FWtotal - FWreadings[FWreadIndex]; // subtract the last reading
int sensorVal = digitalRead(33); // read port status:
if (sensorVal = LOW) // If the switch is closed...
{
FWreadings[FWreadIndex] = 1; //...reading is one
}
else
{
FWreadings[FWreadIndex] = 0; //...reading is zero
}
FWtotal = FWtotal + FWreadings[FWreadIndex]; // add the reading to the total
FWreadIndex = FWreadIndex + 100; // advance to the next position in the array
// if we're at the end of the array...
if (FWreadIndex >= FWnumReadings)
{
FWreadIndex = 0; // ...wrap around to the beginning
}
FWaverage = FWtotal / FWnumReadings; // calculate the average
adc3 = FWaverage; // Insert average to variable adc3
//Serial.println(adc3);
}
}
void FanControl()
{
unsigned long FCcurrentMillis = millis(); // Record current time
if (FCcurrentMillis - FClastExecutedMillis >= FC_EXE_INTERVAL) //If elapsed time from last execution is more than the specified interval
{
FClastExecutedMillis = FCcurrentMillis;
if (((bCastMsg.tps >= 80 && bCastMsg.rpm <= 500) && output == 1) || (bCastMsg.clt-32)*5/9 >= 90 && FCstatus == 0)
{
if(FCstatus == 0){output = output + 1;}
digitalWrite(FCpin, HIGH);
Serial.println("Fan ON");
FCstatus = 1;
}
else if((bCastMsg.clt-32)*5/9 <= 87 && FCstatus == 1)
{
digitalWrite(FCpin, LOW);
Serial.println("Fan OFF");
FCstatus = 0;
}
//Serial.println((bCastMsg.clt-32)*5/9);
}
}
void ICSControl()
{
unsigned long ICSCcurrentMillis = millis(); // Record current time
if (ICSCcurrentMillis - ICSClastExecutedMillis >= ICSC_EXE_INTERVAL) //If elapsed time from last execution is more than the specified interval
{
ICSClastExecutedMillis = ICSCcurrentMillis;
//If throttle position is above 80 %, RPM below 500 (test mode)
//Or if throttle position is above 80 %, MAP above 150 kPa, IAT temperature more than 20°C above ambient
//Or if IAT temperature more than 30°C above ambient and speed more than 30 km/h and spray was last on more than 15s ago
if ((bCastMsg.tps >= 80 && bCastMsg.rpm <= 500) && output == 2 || (bCastMsg.tps >= 80 && bCastMsg.map >= 150 && (((bCastMsg.clt-32)*5/9)-(ATaverage/10)) >= 20) || ((((bCastMsg.clt-32)*5/9)-(ATaverage/10)) >= 30 && bCastMsg.gps_speed*3.6 > 30 && ICSCcurrentMillis - ICSCOnMillis >= 15000))
{
digitalWrite(ICSCpin, HIGH);
if(ICSCstatus == 0){output = output + 1;}
//Serial.println("IC Spray ON");
if(ICSCstatus == 0)
{
ICSCOnMillis = ICSCcurrentMillis;
ICSCstatus = 1;
}
}
else
{
digitalWrite(ICSCpin, LOW);
//Serial.println("IC Spray OFF");
}
if(ICSCcurrentMillis - ICSCOnMillis >= 3000)
{
digitalWrite(ICSCpin, LOW);
//Serial.println("IC Spray OFF");
ICSCstatus = 0;
}
}
}
void CSControl()
{
unsigned long CScurrentMillis = millis(); // Record current time
if (CScurrentMillis - CSlastExecutedMillis >= CS_EXE_INTERVAL) //If elapsed time from last execution is more than the specified interval
{
CSlastExecutedMillis = CScurrentMillis;
if (((bCastMsg.tps >= 80 && bCastMsg.rpm <= 500) && output == 3) || (bCastMsg.rpm >= 1500 && bCastMsg.rpm <= 4200 && CSstatus == 0))
{
if(CSstatus == 0){output = output + 1;}
digitalWrite(CSpin, HIGH);
Serial.println("Camshaft ON");
CSstatus = 1;
}
else if((bCastMsg.rpm <= 1450 || bCastMsg.rpm >= 4250) && CSstatus == 1)
{
digitalWrite(CSpin, LOW);
Serial.println("Camshaft OFF");
CSstatus = 0;
}
}
}
void output_test(){
if(output > 3)
{
output = 1;
}
}
Koodi: Valitse kaikki
// Create a bitmask for output states
uint16_t outputStates = 0;
outputStates |= (FCstatus << 0); // Bit 0: Fan Control
outputStates |= (ICSCstatus << 1); // Bit 1: IC Spray Control
outputStates |= (CSstatus << 2); // Bit 2: Camshaft Control
// Store outputStates in adc4
adc4 = outputStates;
Koodi: Valitse kaikki
CoolantFan = bits, U16, 112, [0:0]
InterCoolerSpray = bits, U16, 112, [1:1]
Camshaftontrol = bits, U16, 112, [2:2]
Koodi: Valitse kaikki
entry = CoolantFan, "FanON", int, "%d"
entry = InterCoolerSpray, "ICSPrayON", int, "%d"
entry = Camshaftontrol, "CamshaftON", int, "%d"