Need help with code for HID

Hi all, I need help with my code, I`m not good at it sorry.

This is my code:

// Arduino Leonardo Rev3.0 
void setup() {
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
}

// the loop routine runs over and over again forever:
void loop() {
  // read the input on analog pin 0:  
  int analogValue = analogRead(A0);
  // print out the value you read:
  Serial.println(analogValue);
  delay(100);        // delay in between reads for stability
  if (analogValue > 870 && analogValue < 890) // read the analogue input into variable analogValue
  {
   //ACC is in the OFF Pos
   Serial.print("ACC OFF");
   delay(1);
  }
  else
  if (analogValue > 950 && analogValue < 965)
  {
   //ACC is in the ON Pos
   Serial.print("ACC ON");
   delay(1);
  }
   else
   if (analogValue > 985 && analogValue < 995)
  {
   //ACC is in the ON Pos and RET is Pressed
   Serial.print("ACC ON+RET");
   delay(1);
  }
  else
  if (analogValue > 1000 && analogValue < 1011)
  {
   //ACC is in the ON Pos and RES is Pressed
   Serial.print("ACC ON+RES");
   delay(1);
  }
   else
   if (analogValue > 1012 && analogValue < 1025)
  {
   //ACC is in the ON Pos and ACC is Pressed
   Serial.print("ACC ON+ACC");
   delay(1);
  }
}

What it does:
It measures a 2-wire 5 button cruise control operating lever. All 5 buttons are on the same 2-wire with no option to wire all 5 buttons separate so we need to stick with 2-wire. Each button has a unique resistor value so every button outputs a different voltage. My voltage is 5v so for example button 1 outputs 4 volt, button 2 outputs 3 volt etc. Dont worry about the values, my code above handles them perfect and already serial.print the correct pushed button so thats done.

What I need:
My code needs if/else and I dont know how to do that, so thats where I need your help.

If button # is pressed, then keyboard.print #

I want these keyboard.prints:
When ACCoff = TRUE, THEN keyboard.print("c");
When ACCon = TRUE, THEN keyboard.print("c");

These two above need to send a "C" whenever they change state. In the game activating or deactivating the cruisecontrol is done by pressing a keyboard "C". Unfortunately there is no discrete ON or OFF letter in this game so they both need to send the same character.

When the ACCret = TRUE, THEN keyboard.print("8");
When the ACCres = TRUE, THEN keyboard.print("7");
When the ACCacc = TRUE, THEN keyboard.print("9");

Your help is much appreciated!

Do you want the statements like Keyboard.print("c"); to be executed continuously during period that the button is pressed or only once per button press ?

Below is an example of the easier case:
If that is no good, look at button de-bounce techniques.

  if (analogValue > 870 && analogValue < 890) // read the analogue input into variable analogValue
  {
   //ACC is in the OFF Pos
   Serial.print("ACC OFF");
   Keyboard.print("c");
   delay(1);
  }

If that is no good, look at button de-bounce techniques.

It's not de-bounce that's needed for the other case, it's state change detection so that the character is sent when the input values enters the required range rather than when it is in the required range.

There is a StateChangeDetection example in the IDE. It uses a digital input but the principle is the same for analogue input.

Yes. That is even better worded than mine. If is the case that he wants one action per button press, then he'll probably also want to reject multiple button presses within a specific period of time, which is why I spoke about de-bounce. Anyway, lets see if he comes back.

6v6gt:
Yes. That is even better worded than mine. If is the case that he wants one action per button press, then he'll probably also want to reject multiple button presses within a specific period of time, which is why I spoke about de-bounce. Anyway, lets see if he comes back.

Yes that`s exactly what I need! 1 keyboard.print per press and then wait till next press.

Two exceptions; ACC+RES and ACC+RET. These two need to keep sending while pressed with a minimum delay in between.

If you don`t mind I would like to go for the non de-bounce first, would you be willing to mod my code in the first post? Your help would be much appropriated and credited on my blog!

Here is something to get you started.

  if ((analogValue > 870 && analogValue < 890) && ACC_OFF == false) //print message if ACC has just been turned off
  {
   //ACC is in the OFF Pos
   Serial.print("ACC OFF");  
   ACC_OFF = true;
   delay(1);
  }

You need a new boolean variable (ACC_OFF) which you need to set to true or false at appropriate stages in the program. I have not looked much further in your program but you can expand the idea to other states.

Do yourself a favor, work through a C++ beginners tutorial.

If something does not work as expected in the first place, search for the reason.
"It didn't work" is no reason, it is not even slight hint.

You need to learn the basics of C or C++. It is very easy.

You need to practice the transformations from

  • 'problem description' over
  • 'strategy to solve the problem' to
  • 'code that solves the problem'.
    All of the three steps require different knowledge, skills and a lot of practice.

Get your hands dirty. :wink:

Ok I added booleaans to my code, but I`m not sure if this is the way go.

// Arduino Leonardo Rev3.0 
// This code is for all Scania 4-Series
// This code is build to control the Scania 4-Series ACC (ACC is short for CruiseControl) via HID (Human Interface Device)
// Copyright by Jeroen van der Velden

boolean ACCoff = false;
boolean ACCon = false;
boolean ACCret = false;
boolean ACCres = false;
boolean ACCacc = false;

void setup() {
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
}

// the loop routine runs over and over again forever:
void loop() 
{
  // read the input on analog pin 0:  
  int analogValue = analogRead(A0);
  // print out the value you read:
  Serial.println(analogValue);
  delay(100);        // delay in between reads for stability
  if (analogValue > 870 && analogValue < 890) // read the analogue input into variable analogValue
  {
   //ACC is in the OFF Pos
   Serial.print("ACC OFF");
   ACCoff = true;
   delay(1);
  }
  else
  if (analogValue > 950 && analogValue < 965)
  {
   //ACC is in the ON Pos
   Serial.print("ACC ON");
   ACCon = true;
   delay(1);
  }
   else
   if (analogValue > 985 && analogValue < 995)
  {
   //ACC is in the ON Pos and RET is Pressed
   Serial.print("ACC ON+RET");
   ACCret = true;
   delay(1);
  }
  else
  if (analogValue > 1000 && analogValue < 1011)
  {
   //ACC is in the ON Pos and RES is Pressed
   Serial.print("ACC ON+RES");
   ACCres = true;
   delay(1);
  }
   else
   if (analogValue > 1012 && analogValue < 1025)
  {
   //ACC is in the ON Pos and ACC is Pressed
   Serial.print("ACC ON+ACC");
   ACCacc = true;
   delay(1);
  }
}

// Jeroen van der Velden
// https://hackaday.io/project/8448-real-dashboard-truck-simulator

Remember, this is my goal:

When ACCoff = TRUE, THEN serial.print("c");
When ACCon = TRUE, THEN serial.print("c");

These two above need to send a "C" whenever they change state. In the game activating or deactivating the cruisecontrol is done by pressing a keyboard "C". Unfortunately there is no discrete ON or OFF letter in this game so they both need to send the same character.

When the ACCret = TRUE, THEN serial.print("8");
When the ACCres = TRUE, THEN serial.print("7");
When the ACCacc = TRUE, THEN serial.print("9");

The board needs to wait for each button press, not causing a loop. ACCacc and ACCret need to keep sending their character (with minimum delay in between) while being pressed.

These two above need to send a "C" whenever they change state.

Then your requirements are not what they state. They should be

When ACCoff becomes TRUE, THEN serial.print("c");
When ACCon becomes TRUE, THEN serial.print("c");

I still fail to see why you need two variables (ACCon and ACCoff) when the ACC can only be on or off

Why not

if (currentACCstate != previousACCstate)
{
  Serial.print("c");
}

I have 3 switches:

1: Acc (Cruise Control Accelerate speed)
2: Ret (Cruise Control Retrieve speed)
3: Res (Cruise Control Resume from last speed)

I have one toggle Switch:

Cruisecontrol ON/OFF

I want the ON/OFF to toggle a keyboard character "C" when used.
I want button 1 to send a "7"
I want button 2 to send an "8"
I want button 3 to send a "9"

The code should pause after each change (no loop). The 10k Restistor is a pull-up resistor for debounce.

Anyone?

Resistor Values:

Code I think is right for this

This code was used in the video link above:

// Arduino Leonardo Rev3.0 
// This code is for all Scania 4-Series
// ACC HID control for ETS2
void setup() {
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
}

// the loop routine runs over and over again forever:
void loop() {
  // read the input on analog pin 0:  
  int analogValue = analogRead(A0);
  // print out the value you read:
  Serial.println(analogValue);
  delay(100);        // delay in between reads for stability
  if (analogValue > 870 && analogValue < 890) // read the analogue input into variable analogValue
  {
   //ACC is in the OFF Pos
   Serial.print("ACC OFF");
   delay(1);
  }
  else
  if (analogValue > 950 && analogValue < 965)
  {
   //ACC is in the ON Pos
   Serial.print("ACC ON");
   delay(1);
  }
   else
   if (analogValue > 985 && analogValue < 995)
  {
   //ACC is in the ON Pos and RET is Pressed
   Serial.print("ACC ON+RET");
   delay(1);
  }
  else
  if (analogValue > 1000 && analogValue < 1011)
  {
   //ACC is in the ON Pos and RES is Pressed
   Serial.print("ACC ON+RES");
   delay(1);
  }
   else
   if (analogValue > 1012 && analogValue < 1025)
  {
   //ACC is in the ON Pos and ACC is Pressed
   Serial.print("ACC ON+ACC");
   delay(1);
  }
}

// Jeroen van der Velden
// https://hackaday.io/project/8448-real-dashboard-truck-simulator

Found help elsewhere! Thanks!

YouTube video of the device working!

//Copyright S.M.Taylor 2016
//Released under by-nc-sa Non-Commercial Share Alike 
//http://creativecommons.org/licenses/by-nc-sa/2.5/
#include "Keyboard.h"
int lockpin = 13;
bool oldstate=false;
bool debugmode=false;
bool keystate=false;
char outchar=' ';
const int acctrip =200;
const int restrip =400;
const int rettrip = 600;
const int onlimit = 650;
const int offlimit =1000;
void setup() {
  pinMode(lockpin,INPUT_PULLUP); //no need for a pullup.
  // open the serial port 
  Serial.begin(9600);
}

void loop() {
  int analogValue = analogRead(A0);
  debugmode=digitalRead(lockpin);
  if (debugmode==false) 
    Keyboard.begin();
   else
    Keyboard.end(); 
  if (analogValue>offlimit) 
    keystate=false;
    else keystate=true;
  if (oldstate != keystate)
     {oldstate=keystate;
      if (debugmode==false)
       Keyboard.write('c');
       else
       Serial.println ('c');
     }  
 
  if ((analogValue <= onlimit)&&(analogValue>=acctrip))  
   {if (analogValue>rettrip) outchar='8';
      else if (analogValue >restrip) outchar='7';
       else if (analogValue>acctrip) outchar='9';
      
    if (debugmode==false)
      Keyboard.write(outchar);
      else
      {Serial.print(outchar);
       Serial.print("  ");
       Serial.println(analogValue);
       };
    }
    //analogvalue in keyscan limit
      else
      {Serial.print("No char ");
      Serial.println(analogValue);
      }
      
    delay(200);
}