Show Posts
Pages: [1] 2 3 ... 5
1  Using Arduino / Programming Questions / Re: Cleaning up code, and reducing amount of typing on: February 25, 2014, 11:29:31 pm
ahh well, i can't be doing things with arduino's everyone has an interest in i guess,
Tho this time a 40 button usb joystick i thought would be an interesting thing, google is full of people asking how to do it, but none seem to give a completed example.


Of course now i have it working, i find out the sodding bus simulator only accepts directX inputs, so 32 buttons per joystick, FFS, 8 buttons i can't use, but need to.


So now i am looking for a way to run 2 instances of the 40 button joystick code at once on the uno, only reduced to 32 buttons,

There are just enough pins to run an 8x8 martix, 16 pins out of the 20, of which 3 can't be used anyway (0 and 1 because they are tied to the serial port, and pin 13 because of the onboard led),
2  Using Arduino / Programming Questions / Cleaning up code, and reducing amount of typing on: February 25, 2014, 12:59:13 pm
I am probably on a global shit list, so no one replies to any of my posts, but i'll try one last time,

i have been playing about making an UNO into a USB HID joystick, it's taken me a couple of days of playing around... half of that was time taken to put the UNO into DFU more, flash the 16u2 chip, unplug and re-plug the usb cable, open a joystick test proggy, find it's not working, UNO into DFU mode, flash back to serial.... repeat about 200 times.

But i have finally got a matrix keypad connected to an UNO, sending individual keypad buttons as USB joystick buttons, my script is:
Code:
/* USB HID stuff written by Darran Hunt,
hex file for flashing  the 16u2 chip is found on his site http://hunt.net.nz/users/darran/
*/

#include <Keypad.h> //keypad library

const byte ROWS = 4; //four rows
const byte COLS = 3; //three columns
//define characters for the buttons of the keypad
char keys[ROWS][COLS] = {
  {'1', '2', '3'},
  {'4', '5', '6'},  //electrical keypad layout
  {'7', '8', '9'},
  {'A', '0', 'B'}
};
byte rowPins[ROWS] = {5, 4, 3, 2,}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {8, 7, 6}; //connect to the column pinouts of the keypad
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS);


#define NUM_BUTTONS 40    //lovely buttons
#define NUM_AXES 8      //annoying axis not needed 

typedef struct joyReport_t {
  int16_t axis[NUM_AXES];
  uint8_t button[(NUM_BUTTONS + 7) / 8]; // 8 buttons per byte
} joyReport_t;

joyReport_t joyReport;

void setup()
{ keypad.addEventListener(keypadEvent); //to allow button press and release
  Serial.begin(115200); //talk to the pooter as fast as you can
  delay(200);


  for (uint8_t ind = 0; ind < 8; ind++) {
    joyReport.axis[ind] = ind * 1000;      //axis maths
  }

  for (uint8_t ind = 0; ind < sizeof(joyReport.button); ind++) {    //buttons maths
    joyReport.button[ind] = 0;
  }
}

// Send an HID report to the USB interface
void sendJoyReport(struct joyReport_t *report)
{
  Serial.write((uint8_t *)report, sizeof(joyReport_t));
}

// turn a button on
void setButton(joyReport_t *joy, uint8_t button)
{
  uint8_t index = button / 8;
  uint8_t bit = button - 8 * index;

  joy->button[index] |= 1 << bit;
}

// turn a button off
void clearButton(joyReport_t *joy, uint8_t button)
{
  uint8_t index = button / 8;
  uint8_t bit = button - 8 * index;

  joy->button[index] &= ~(1 << bit);
}

uint8_t button = 0; // current button




void loop() {
  char key = keypad.getKey();    //read which key is pressed
}

void keypadEvent(KeypadEvent key) {    //read key as pressed or released

  switch (keypad.getState()) {

 // read keys, send joystick buttons
    case PRESSED:
      if (key == '1')  {
        setButton(&joyReport, button = 0);
      }
      if (key == '2')  {
        setButton(&joyReport, button = 1);
      }
      if (key == '3')  {
        setButton(&joyReport, button = 2);
      }
      if (key == '4')  {
        setButton(&joyReport, button = 3);
      }
      if (key == '5')  {
        setButton(&joyReport, button = 4);
      }
      if (key == '6')  {
        setButton(&joyReport, button = 5);
      }
      if (key == '7')  {
        setButton(&joyReport, button = 6);
      }
      if (key == '8')  {
        setButton(&joyReport, button = 7);
      }
      if (key == '9')  {
        setButton(&joyReport, button = 8);
      }
      if (key == 'A')  {
        setButton(&joyReport, button = 9);
      }
      if (key == '0')  {
        setButton(&joyReport, button = 10);
      }
      if (key == 'B')  {
        setButton(&joyReport, button = 11);
      }
      break;

    case RELEASED:
      if (key == '1')  {
        clearButton(&joyReport, button = 0);
      }
      if (key == '2')  {
        clearButton(&joyReport, button = 1);
      }
      if (key == '3')  {
        clearButton(&joyReport, button = 2);
      }
      if (key == '4')  {
        clearButton(&joyReport, button = 3);
      }
      if (key == '5')  {
        clearButton(&joyReport, button = 4);
      }
      if (key == '6')  {
        clearButton(&joyReport, button = 5);
      }
      if (key == '7')  {
        clearButton(&joyReport, button = 6);
      } if (key == '8')  {
        clearButton(&joyReport, button = 7);
      }
      if (key == '9')  {
        clearButton(&joyReport, button = 8);
      }
      if (key == 'A')  {
        clearButton(&joyReport, button = 9);
      }
      if (key == '0')  {
        clearButton(&joyReport, button = 10);
      }
      if (key == 'B')  {
        clearButton(&joyReport, button = 11);
      }

      break;

  }
  sendJoyReport(&joyReport);  //send it via usb to the pooter
  delay(10);

}


This is only for a 12 button keypad, i want to use a 36 button keypad with it, and i really don't fancy adding all the extra 'if key == xx' bits manually,

i've often seen people do something that adds the numbers up by one as the code progresses, so a single line of code replaces  many lines, otent to turn on led's on pins 2 to 12 etc.

Would that work in this case?

Also, are there any glaring errors in my script?? things i don't need or could do differently,
wondering about the use of only 2 'break' commands, should i break after each button test? only one button will be pressed down at a time, and another input is not needed until the original button is released and a new one pressed,

And i hope this script can help anyone else trying to turn an UNO R3 into a USB joystick, as i found no completed scripts to do this for a 40 button joystick, only  few for PS3 sticks,
3  Using Arduino / Programming Questions / Re: UNO joystick, matrix inputs on: February 24, 2014, 01:25:19 pm
Well, i've been playing but not getting very far,

i've added the code for a basic 4 x 3 keypad to the joystick sketch, but i am stuck on how to make a keypad button press send a USB joystick button press,

my script so far...
Code:
/* Arduino USB 12 button matrix joypad */

/* USB HID stuff; Author: Darran Hunt
Matrix stuff by me. based on stock matrix kaypad lib.
 * Released into the public domain.
 */
#include <Keypad.h> //keypad library

const byte ROWS = 4; //four rows
const byte COLS = 3; //three columns
//define charecters for the buttons of the keypad
char keys[ROWS][COLS] = {
  {'1','2','3'},
  {'4','5','6'},    //electrical keypad layout
  {'7','8','9'},
  {'A','0','B'}
};
byte rowPins[ROWS] = {5, 4, 3, 2,}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {8, 7, 6}; //connect to the column pinouts of the keypad
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS);

#undef DEBUG

#define NUM_BUTTONS 40            //40 lovely buttons
#define NUM_AXES 8        // 8 axes, not needed, will delete later

typedef struct joyReport_t {
    int16_t axis[NUM_AXES];
    uint8_t button[(NUM_BUTTONS+7)/8]; // 8 buttons per byte
} joyReport_t;

joyReport_t joyReport;


void setup(void); 
void loop(void);
void setButton(joyReport_t *joy, uint8_t button);
void clearButton(joyReport_t *joy, uint8_t button);  //constantly sending usb data i guess
void sendJoyReport(joyReport_t *report);


void setup()
{
    Serial.begin(115200);
    delay(200);

    for (uint8_t ind=0; ind<8; ind++) {
joyReport.axis[ind] = ind*1000;
    }
    for (uint8_t ind=0; ind<sizeof(joyReport.button); ind++) {
        joyReport.button[ind] = 0;
    }
}

// Send an HID report to the USB interface
void sendJoyReport(struct joyReport_t *report)
{
#ifndef DEBUG
    Serial.write((uint8_t *)report, sizeof(joyReport_t));
#else
    // dump human readable output for debugging
    for (uint8_t ind=0; ind<NUM_AXES; ind++) {
Serial.print("axis[");
Serial.print(ind);
Serial.print("]= ");
Serial.print(report->axis[ind]);
Serial.print(" ");
    }
    Serial.println();
    for (uint8_t ind=0; ind<NUM_BUTTONS/8; ind++) {
Serial.print("button[");
Serial.print(ind);
Serial.print("]= ");
Serial.print(report->button[ind], HEX);
Serial.print(" ");
    }
    Serial.println();
#endif
}

// turn a button on
void setButton(joyReport_t *joy, uint8_t button)
{
    uint8_t index = button/8;
    uint8_t bit = button - 8*index;

    joy->button[index] |= 1 << bit;
}

// turn a button off
void clearButton(joyReport_t *joy, uint8_t button)
{
    uint8_t index = button/8;
    uint8_t bit = button - 8*index;

    joy->button[index] &= ~(1 << bit);
}

uint8_t button=0; // current button
bool press = true; // turn buttons on?

/* Turn each button on in sequence 1 - 40, then off 1 - 40
 * add values to each axis each loop
 */
void loop()
  { char key = keypad.getKey(); //gets keypad inputs
 
  /*Now what?
  how do i tell it to send joystick button 1 as pressed when keybad number 1 is pressed,
  jotstick button 2 as pressed on keypad button 2 and so on??
 
 
  The code below is what made the buttons turn on in sequence, then back off as well as move the axis.
 
 
    // Turn on a different button each time
    if (press) {
setButton(&joyReport, button);
    } else {
clearButton(&joyReport, button);
    }

    // Move all of the axes
     for (uint8_t ind=0; ind<8; ind++) {
joyReport.axis[ind] += 10 * (ind+1);
    }

    sendJoyReport(&joyReport);

    button++;
    if (button >= 40) {
       button = 0;
       press = !press;
    }
    delay(100); */
}

Please give me some pointers.
4  Using Arduino / Programming Questions / UNO joystick, matrix inputs on: February 23, 2014, 05:29:23 pm
i am absolutely useless at programming, i can't even figure out what should be something simple:
But i am determined to learn at least part of what i am doing with the arduino's.

I want to turn my uno (R3) into a usb hid joystick, i have done so using Darran Hunts 'UNO big joystick' http://hunt.net.nz/users/darran/

I like this particular version of the HID usb joysticks as it has the number of buttons i need, and it 'looks' simple,

So i have the following script on my UNO:
Code:
   /* Arduino USB Joystick HID demo */
    /* Author: Darran Hunt
     * Released into the public domain.
     */

    #define NUM_BUTTONS 40
    #define NUM_AXES 8        // 8 axes, X, Y, Z, etc
    typedef struct joyReport_t {
int16_t axis[NUM_AXES];
uint8_t button[(NUM_BUTTONS+7)/8]; // 8 buttons per byte
    } joyReport_t;

    joyReport_t joyReport;

    void setup()
    {
Serial.begin(115200);
delay(200);

    for (uint8_t ind=0; ind<8; ind++) {
    joyReport.axis[ind] = ind*1000;
}

for (uint8_t ind=0; ind<sizeof(joyReport.button); ind++) {
    joyReport.button[ind] = 0;
}
    }

    // Send an HID report to the USB interface
    void sendJoyReport(struct joyReport_t *report)
    {
Serial.write((uint8_t *)report, sizeof(joyReport_t));
    }

    // turn a button on
    void setButton(joyReport_t *joy, uint8_t button)
    {
uint8_t index = button/8;
uint8_t bit = button - 8*index;

    joy->button[index] |= 1 << bit;
    }

    // turn a button off
    void clearButton(joyReport_t *joy, uint8_t button)
    {
uint8_t index = button/8;
uint8_t bit = button - 8*index;

joy->button[index] &= ~(1 << bit);
    }

    uint8_t button=0; // current button
    bool press = true; // turn buttons on?
    /* Turn each button on in sequence 1 - 40, then off 1 - 40
     * add values to each axis each loop
     */
    void loop()
    {
// Turn on a different button each time
if (press) {
    setButton(&joyReport, button);
} else {
    clearButton(&joyReport, button);
}

/* Move all of the axes */
for (uint8_t ind=0; ind<8; ind++) {
    joyReport.axis[ind] += 10 * (ind+1);
}
sendJoyReport(&joyReport);
button++;
if (button >= 40) {
   button = 0;
   press = !press;
}
delay(100);
    }

And when i use 'flip' to load the 'big joystick.hex' to the 8u2, it works, upon unplugging and re-pluggig the UNP, it shows up as a 40 button, 8 axis joystick,
Of course it is only a demo script, so the buttons are turning on one at a time, then off one at a time, and the axis moving by them selves,

I need to replace the demo code with actual code that will read inputs from the digital pins of the UNO, and send out the relevant  joystick button presses.
i have no use for the axis, but i will leave it until much later before i see about removing those and changing the USB descriptors.

Can someone tell me what i need to change to get a single button press recognised, i.e. pin 2 connected to ground shows up as button 1 pressed on the joystick, and released when the connection is removed,
then i can hopefully work out how to get a few buttons working and move on from there,


Eventually i want to combine a 36 button keypad matrix script with the joystick script, so the buttons pressed on the keypad send joystick buttons to the game,

The button matrix script is:
Code:
#include <Keypad.h>
#include <LiquidCrystal.h>

const byte ROWS = 4; //four rows
const byte COLS = 9; //nine columns
char keys[ROWS][COLS] = {
  {'0','1','2','3','4','5','6','7','8'},
  {'9','A','B','C','D','E','F','G','H'},
  {'I','J','K','L','M','N','O','P','Q'},
  {'R','S','T','U','V','W','X','Y','Z'}
};
byte rowPins[ROWS] = {13, 12, 11, 10}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {9, 8, 7, 6, 5, 4, 3, 2, 1}; //connect to the column pinouts of the keypad

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
LiquidCrystal lcd(A5, A4, A3, A2, A1, A0);
 
void setup()

 
  lcd.begin(20, 1); // Specify how many columns and rows in the LCD unit
  lcd.clear();
}

void loop()
{
  char key = keypad.getKey();
 
  switch (key)
  {
     case '0':
       lcd.clear();
                lcd.print ("xxx");
     break;
     
     case '1':
       lcd.clear();
                lcd.print ("xxx");
     break;
     
     case 'A':
       lcd.clear();
                lcd.print ("xxx");
     break;
     
     case 'B':
       lcd.clear();
                lcd.print ("xxx");
     break;
     
     case 'C':
       lcd.clear();
                lcd.print ("xxx");
     break;  //and so on for 36 buttons
  } 
}

It is one i used to display different sentences on an LCD according to which button was pressed, so i guess that instead of the LCD bit, i need to 'print' the  button press letter to the joystick??
5  Using Arduino / Programming Questions / Re: non linear compensation on: January 18, 2014, 11:20:51 am
no, not smoothing the pwm at all, for now, want to get the needles of the real gauges following the simulated gauges first,

I believe the non linearity is built into the gauges, so it makes the important area of the scale more obvious to changes.... with the fuel gauge it moves faster and more visibly at the bottom... where you are likely to run out of fuel, and the water temp gauge, it shows larger steps in the 80 to 100 degree range, as thats the normal operating to overheating range,

I'm looking at the lookup table thing now, as that seems to be the way to sort this,
6  Using Arduino / Programming Questions / non linear compensation on: January 17, 2014, 10:36:01 pm
i use my arduino mega 1280 to turn on and off lights on a dashboard of a computer bus simulator, and also to position the needles on the gauges,

The gauges are standard automotive air core motor type gauges, 3 terminals on the back, + 24 volts in, earth and sender connection,
in the vehicle the sender would be a float level sensor for the fuel tank and thermistor type sensor for the water temp. usual range of 0 to 180 ohms (0 being FSD, 180 ohms being needle at the bottom) there is also an oil pressure gauge, the senders range the same but reversed, to 180 - 0 ohms, 0 ohms = FSD.

The sender connection of a gauge is connected to the collector of a NPN transistor, it's emitter connected to earth (and tied between the arduino and 24 volt power supply to the gauges) and the base of the transistor goes via a 1k resistor to an arduino PWM pin,

To move the needle the PWM output is varied,

This all works, BUT the gauges are not linear, and the output from the simulator is, i.e. if the simulators fuel gauge needle is pointing to half way, it sends out 50, if it's at 3/4, 75, and so on.
The arduino gets this data over the serial port, then translates the 0 - 100 inputs to 8 bit PWM output 0-255 steps,

But the real gauge's don't display that properly, as the scale is non linear and hence the needles move different amounts in the lower or upper half of the sweep.

The water temp gauge is the worst, on the dial you can easily see the non linearity,
The distance between the centres of the markings measured from the attached picture, re-sized to the exact real life size of 65mm diameter then measured in a drawing program:
50 to 60 = 3.7mm
60 to 70 = 5.5mm
70 to 80 = 8.3mm
80 to 90 = 9.5mm
90 to 100 = 9.5mm
100 to last marking = 6.2mm

The numbers represent degrees centigrade (they are from a European bus)

So when i run a sweeping PWM script on the arduino just running 0 - 255 - 0 and repeat, running the sweep very slowly you can clearly see the steps the needle moves in in the upper half of the dial, but below 80 the steps get smaller and smaller,
so running the sweep at a faster speed, it takes about 4 to 5 times as long for the needle to travel from 80 down to 50, as it does to travel from the top mark to 80.

The fuel gauge is kind of similar except the other way round, needle moves larger steps in the lower half, smaller steps in the upper half.

Annoyingly the oil pressure gauge is linear, the markings being spaced evenly and the needle making the same size steps throught the needle sweep.

Sorry for the long winded description, wanted to make sure i explained it properly,
so, i need to add some maths type stuff to the arduino script to alter the PWM steps depending on which part of the scale the needle is pointing in,

Maths is my absolute weakest subject, with programming not much stronger smiley but i can usually get scripts to do what i want eventually with help.

What kinds of things to i need to be looking at to fix my problem?
i imagine the way to do it is to make the PWM signal move multiple steps at the lower range for every one input movement step from the simulator.

Please be simple with me, i can imagine the code to be something along the lines of :
if input less than 15, output xx steps per input step,
if input between 15 and 30, output xx steps per input step, and so on until the largest distance between markings where 1 in = 1 out step,

The fuel gauge only has 5 markings, the distance between 1/2 - 3/4 - full being about equal, and empty to 1/4 being about half the distance as 1/4 to 1/2,
7  Using Arduino / Project Guidance / mega 1280 keeps loosing it's program on: October 14, 2013, 05:59:06 pm
I have an arduino mega 1280 that i use to control lights and gauges on a bus dashboard,

it's connected to the computer via a 2 foot usb cable directly to one of the USB ports (i.e. not via a hub or anything) no external power in to the arduino,

I have the arduino plugged into a large shield i made,  every digital and analog pin except for 6 of the analog pins go through a 500 ohm resistor to the base of a 2N2222 transistor,

Emitter to earth, and collector to a screw terminal,
The 6 analog pins that do not go through the resistors and transistors go straight to screw terminals, as i connect an LCD to those pins,

The bus dashboard's lights and gauges are fed 24 volts from a bench psu, earth tied to the arduino's via the shield, and the arduino simply puts a pin high to turn on a light, or alters a pins PWM to vary a gauge reading,

It all works ok, however since about 2 weeks ago i have found that every day when i start up the computer, start the bus driving simulator and try to connect to the arduino, nothing happens,

If i re-program the arduino with it's script, it will then connect to the bus sim fine and work, and i can shut the computer down, come back in a few hours and it's still working,

But leave it overnight, and it seems to be loosing the programming,   my mother board keeps power to the usb ports for charging mice and things, this is annoying as the trackIR led's stay on all night, so i've taken to switching the computer off at the wall, but the arduino lost it's programming when i left the computer on at the wall or off,

TOne thing i have noticed is that one of the gauges that is connected to analog pin 13 flicks when programming the board,
i deliberately left analog pin 0 and 1 empty as i believe they are tied to the serial port, but even if i disconnect pin 13, and re-assign the gauge to pin 10, whilst no other gauges flicker whilst programming, the arduino is still loosing it's programming over night.


Any ideas to what may be happening?

Is it possible to read the program from an arduino to the computer so i can see if it is still present in the morning? thinking something may just be blocking comms until i re-program the board,
and i will try unplugging the arduino from the shield, but is it known for a shield to ever cause an arduino to loose it's program???
8  Using Arduino / Programming Questions / Re: Timers conflicting? on: September 30, 2013, 05:33:39 am
Ahh right, let me explain:

The tone function is a variable frequency output i believe, basically a series of pulses that vary in number but stay the same in duration?,

Which is exactly what a car's rev counter and speedometer work with, i.e. one pulse per revolution of the engine, or per rotation of the prop shaft,

Hence the speedo is fed the tone signal that varies with the speed signal numbers given to it by the simulator, it goes via a transistor to give the speedo 24 volt pulses,

The other gauges want a varying resistance to earth (float arm moving a wiper on a resistance track in the fuel tank) So i feed them again via a transistor a varying PWM signal to try and simulate this.

It works, so i haven't looked for a better way to do the same job, but it is only now i am adding more items to the dashboard that i am finding things slowing down it seems,
i have 4 servo operated gauges to add next, so i wonder if they will cause problems too,

Apart from the 3 gauges that get PWM signals, the rev counter and speedo that get the tone signals, and some time soon the air pressure gauges that will get servo pulses (as the arduino dosent output a 0-12 bar air pressure output  smiley, i removed the bourdon tubes from the air gauges, and drive the needles with sub micro servo's)
The other outputs are simply on or off, working light bulbs (again via transistors as they are 24 volt bulbs)
Plus of course the lcd in the ticket machine, i want to add another lcd later, and put them on an I2C connection, as i'm running out of pins rapidly.
9  Using Arduino / Programming Questions / Re: Timers conflicting? on: September 29, 2013, 08:05:45 pm
Ahhh, so it shouldn't be the lcd part causing the problem then,

i'll be honest, i didn't write much of that code, i started a little bit of it, then the bloke who is writing the plugin .DLL that gets the data out of the simulator for the arduino to read had a go at writing the arduino script too,

we found it worked, so he kept at it, and i must admit i dont really understand all of it,

All i know is that the data comes out of the simulator as a bunch of letters and numbers, i.e. if 'a' is present in the data string, then the arduino turns on the pin that the 'ASR' light on the dashboard is connected to, and turns it off when 'a' is no longer present in the incoming data stream,

The gauges are given letters then values i think, so 'o34' results in the oil pressure gauge's needle pointing to 3.4 bar on the scale, which is done by driving the air core via a varying PWM signal, so simulate resistance to earth as the gauges would in the vehicle.

We can't directly read text from the simulator, so he assigned 3 digit numbers to the ticket preselection choices, modified the simulators code a little to send the code when ever the relevent text is on the simulated display, and the arduino puts the text on the real display,

We found that the display was pulsing/strobing/flashing when ever text was on it, and this was assumed to be due to the display being updated constantly, so he wrote a bit of code that stopped the display refreshing until a new text set was required,
at the same time he wrote in something to clear the display when ever nothing was received,


So i guess the problem is the time taken to run the script on the arduino now? with the lcd stuff clogging it up?
10  Using Arduino / Programming Questions / Re: Timers conflicting? on: September 28, 2013, 10:12:41 am
The script:


Code:
// Last updated: September 22th, 2013
// Using state machine pattern - based on Nick Gammon code


#include <LiquidCrystal.h>  //LCD library
#include <stdio.h>
#include <stdlib.h>

typedef enum {  NONE, GOT_I, GOT_O, GOT_R, GOT_o, GOT_T, GOT_S, GOT_B, GOT_H, GOT_b, GOT_h, GOT_P, GOT_F, GOT_A, GOT_W, GOT_V, GOT_w, GOT_r, GOT_k, GOT_a, GOT_t } states;
states state = NONE;
unsigned int currentValue;
unsigned int lastLCDMessage;

LiquidCrystal lcd(54, 55, 56, 57, 58, 59); //connections to the lcd

void setup ()
{
  Serial.begin (115200); //start serial comms
  TCCR4B = (TCCR4B & 0xF8) | 0x01 ; //adjust one of the timers to allow higher frequancy pwm for gauges
  state = NONE;
  lastLCDMessage = 998;
  pinMode(2, OUTPUT); //back lights
  pinMode(22, OUTPUT); //Light, Bus stop brakes
  pinMode(23, OUTPUT); //Switch, fan speed 3
  pinMode(24, OUTPUT); //Light, Buggy
  pinMode(25, OUTPUT); //Switch, heated mirrors
  pinMode(26, OUTPUT); //Light, Rear doors open
  pinMode(27, OUTPUT); //Switch Light, orange switch blank
  pinMode(28, OUTPUT); //Light, stop request
  pinMode(29, OUTPUT); //Switch, Rear fog
  pinMode(30, OUTPUT); //Not connected/bulb blown
  pinMode(31, OUTPUT); //Switch, Direct retarder
  pinMode(32, OUTPUT); //Light, Green dot circle
  pinMode(33, OUTPUT); //Switch, Gear D
  pinMode(34, OUTPUT); //Light, Inicators
  pinMode(35, OUTPUT); //Switch, Gear N
  pinMode(36, OUTPUT); //Light, High beam
  pinMode(37, OUTPUT); //Switch, cabin lights, 3rd in row
  pinMode(38, OUTPUT); //Light, Low oil Pressure
  pinMode(39, OUTPUT); //Switch, Buggy/rear door open
  pinMode(40, OUTPUT); //Light, Low air
  pinMode(41, OUTPUT); //Switch, School bus
  pinMode(42, OUTPUT); //Light, Brake warning
  pinMode(43, OUTPUT); //Switch, Gear, R
  pinMode(44, OUTPUT); //Light, Parking brake
  pinMode(45, OUTPUT); //Switch, Heated window?
  pinMode(46, OUTPUT); //Light, Bendy bus turning too tight
  pinMode(47, OUTPUT); //Switch, Heated side window
  pinMode(48, OUTPUT); //Light, Low coolant
  pinMode(49, OUTPUT); //Switch, Cabin lights, 4th in row
  pinMode(50, OUTPUT); //Light, High gear oil
  pinMode(51, OUTPUT); //Switch, Right hand front door
  pinMode(52, OUTPUT); //Light, Battery/no charge
  pinMode(53, OUTPUT); //Switch, Left hand front door
  //pins 54 to 59 used for LCD in ticket printer
  pinMode(60, OUTPUT); //Light, ASR
  pinMode(61, OUTPUT); //not working
  pinMode(62, OUTPUT); //not working
  pinMode(63, OUTPUT); //Light, Steering wheel with brake pads??
  pinMode(64, OUTPUT); //Light, ABS
  pinMode(65, OUTPUT); //not working
  pinMode(66, OUTPUT); //Switch, Hazards
  pinMode(67, OUTPUT); //Switch, Cabin lights, 2nd in row
  pinMode(68, OUTPUT); //Switch, Drivers cabin light, 1st in row
  pinMode(69, OUTPUT); //Switch, Park heater

lcd.begin(20, 1); // Specify how many columns and rows in the LCD unit
}

// Lights

void Read_BusStopLight(const unsigned int value)
{
  if (value == 1)
  {
        digitalWrite(28,HIGH);  //stop request light
  }
  else
  {
        digitalWrite(28,LOW);
  }
}

void Read_Blinker(const unsigned int value)
{
  if (value == 1)
  {
        digitalWrite(34,HIGH);  //indicators
  }
  else
  {
        digitalWrite(34,LOW);
  }
}

void Read_Highbeam(const unsigned int value)
{
  if (value == 1)
  {
        digitalWrite(36,HIGH);  //highbeam
  }
  else
  {
        digitalWrite(36,LOW);
  }
}

void Read_Battery(const unsigned int value)
{
  if (value == 1)
  {
        digitalWrite(52,HIGH);  //no charge warning light
  }
  else
  {
        digitalWrite(52,LOW);
  }
}

void Read_Handbrake(const unsigned int value)
{
  if (value == 1)
  {
        digitalWrite(44,HIGH);  //parking brake warning
  }
  else
  {
        digitalWrite(44,LOW);
  }
}

void Read_LowPressure(const unsigned int value)
{
  if (value == 1)
  {
        digitalWrite(40,HIGH);  //low air pressure warning
  }
  else
  {
        digitalWrite(40,LOW);
  }
}

void Read_ABS(const unsigned int value)
{
  if (value == 1)
  {
        digitalWrite(64,HIGH);  //ABS light
  }
  else
  {
        digitalWrite(64,LOW);
  }
}

void Read_RearDoor(const unsigned int value)
{
  if (value == 1)
  {
        digitalWrite(26,HIGH);  //rear door open light
  }
  else
  {
        digitalWrite(26,LOW);
  }
}

void Read_RetarderDirect(const unsigned int value)
{
  if (value == 1)
  {
        digitalWrite(31,HIGH);  //retarder switch light
  }
  else
  {
        digitalWrite(31,LOW);
  }
}

void Read_FourFlasher(const unsigned int value)
{
  if (value == 1)
  {
        digitalWrite(66,HIGH); //hazard flashers
  }
  else
  {
        digitalWrite(66,LOW);
  }
}

void Read_Backlight(const unsigned int value)
{
  if (value == 1)
  {
        digitalWrite(2,HIGH);  //instrument back lighting
  }
  else
  {
        digitalWrite(2,LOW);
  }
}

void Read_ASR(const unsigned int value)
{
  if (value == 1)
  {
        digitalWrite(60,HIGH);  //ASR light
  }
  else
  {
        digitalWrite(60,LOW);
  }
}

// Gauges

void Read_Temperature(const unsigned int value)
{
  analogWrite(13,map(value,0,100,0,215));
}

void Read_Rpm(const unsigned int value)
{
  tone(9, map(value,0,5700,55,423));  //rev counter
}

void Read_Oil(const unsigned int value)
{
  analogWrite(11,map(value,0,50,245,0));  //oil pressure
}

void Read_Fuel(const unsigned int value)
{
  analogWrite(12,map(value,0,100,0,0235));  //fuel level
}

void Read_Velocity(const unsigned int value)
{
  tone(10, map(value,0,1250,55,423));  //speedotachograph
}

// LCD

void Read_Ticket(const unsigned int value)
{
  if (value == lastLCDMessage)
  {
      // does nothing, avoids refreshing LCD with same message
  }
  else
  {
      // refreshes LCD
lastLCDMessage = value;
  switch (value)
  {
   case 999:
lcd.clear();
lcd.print ("Druckt...");
break;
   case 998:
lcd.clear();
break;
   case 0:
lcd.clear();
lcd.print ("Fahrschein Nor :2.70");
break;
   case 1:
lcd.clear();
lcd.print ("Kurzstr Norm : 1.70");
break;
   case 2:
lcd.clear();
lcd.print ("Tageskarte Nor :9.00");
break;
   case 3:
lcd.clear();
lcd.print ("Fahrschein Erm :1.70");
break;
   case 4:
lcd.clear();
lcd.print ("Kurzstr Erm : 1.20");
break;
   case 5:
lcd.clear();
lcd.print("KuDamm-Ticket : 1.00");
break;
   case 6:
lcd.clear();
lcd.print ("Tageskarte Erm :5.00");
break;
   case 7:
lcd.clear();
lcd.print ("Komb-Tageskarte:15.00");
break;
   case 8:
lcd.clear();
lcd.print ("Tageskarte Fam:10.00");
break;
   case 9:
lcd.clear();
lcd.print ("Komb-Tagesk Erm:7.00");
break;
default:
lcd.clear();
lcd.print ("I received an unexpected value.");
  }
  }
}

void handlePreviousState()
{
  switch (state)
  {
  case GOT_R:
    Read_Rpm(currentValue);
    break;
  case GOT_o:
    Read_Oil(currentValue);
    break;
  case GOT_T:
    Read_Temperature(currentValue);
    break;
  case GOT_S:
Read_BusStopLight(currentValue);
break;
  case GOT_B:
Read_Blinker(currentValue);
break;
  case GOT_H:
Read_Highbeam(currentValue);
break;
  case GOT_b:
Read_Battery(currentValue);
break;
  case GOT_h:
Read_Handbrake(currentValue);
break;
  case GOT_P:
Read_LowPressure(currentValue);
break;
  case GOT_F:
Read_Fuel(currentValue);
break;
  case GOT_A:
Read_ABS(currentValue);
break;
  case GOT_W:
Read_RearDoor(currentValue);
break;
  case GOT_V:
Read_Velocity(currentValue);
break;
  case GOT_w:
Read_FourFlasher(currentValue);
break;
  case GOT_r:
Read_RetarderDirect(currentValue);
break;
  case GOT_k:
Read_Backlight(currentValue);
break;
  case GOT_a:
Read_ASR(currentValue);
break;
  case GOT_I:
digitalWrite(23,HIGH);
break;
  case GOT_O:
digitalWrite(23,LOW);
break;
  case GOT_t:
Read_Ticket(currentValue);
break;
  }
  currentValue = 0;
}

void processIncomingByte (const byte c)
{
  if (isdigit (c))
  {
    currentValue *= 10;
    currentValue += c - '0';
  }
  else
  {

    handlePreviousState ();
    switch (c)
    {
    case 'I':
      state = GOT_I;
      break;
    case 'O':
      state = GOT_O;
      break;
    case 'R':
      state = GOT_R;
      break;
    case 'o':
      state = GOT_o;
      break;
    case 'T':
      state = GOT_T;
      break;
    case 'S':
      state = GOT_S;
      break;
    case 'B':
      state = GOT_B;
      break;
    case 'H':
      state = GOT_H;
      break;
    case 'b':
      state = GOT_b;
      break;
    case 'h':
      state = GOT_h;
      break;
case 'P':
 state = GOT_P;
 break;
case 'F':
 state = GOT_F;
 break;
case 'A':
 state = GOT_A;
 break;
case 'W':
 state = GOT_W;
 break;
case 'V':
 state = GOT_V;
 break;
case 'w':
 state = GOT_w;
 break;
case 'r':
 state = GOT_r;
 break;
case 'k':
 state = GOT_k;
 break;
case 'a':
 state = GOT_a;
 break;
case 't':
 state = GOT_t;
 break;
    default:
      state = NONE;
      break;
    }
  }  
  
}

void loop()
{
if (Serial.available())
processIncomingByte (Serial.read());
}
11  Using Arduino / Programming Questions / Timers conflicting? on: September 28, 2013, 10:12:22 am
I'm using my mega 1280 to take data from a bus simulator game on the pc, and run lights and gauges on a real dashboard,

I've just added a LCD to the board, and seem to have hit problems with the timers conflicting... i think,

Basically some code was added to stop the lcd constantly updating making it flash, and the gauges now react slowly and jerky, as if they are running in something like 4 bit mode, i.e. only a few steps from empty to full.

i 'think' this code that stops the lcd updating until a new value is present has caused the problem, but i could well be wrong,

My script is in my next post, as i exceed the character limit for a single post, can someone who knows more about this than me have a quick read and point out my probably simple error smiley
12  Using Arduino / Project Guidance / Re: Receive Pelco commands from cctv system, move servo's on: March 22, 2013, 07:37:28 pm
Right, i've found there are RS485 shields available, in america it seems so far, but i'll keep looking for a uk supplier... tho TBH it does look pretty simple to make my self.

http://www.robotshop.com/rs485-shield-arduino-3.html

That should get me the signal from the cctv system into the arduino safely,
i just need to figure out that complicated part of writing code to make the arduino do something with it

(i am not a coder, making pcb's, soldering, modifying hardware, no probs, but writing stuff to make the hardware do stuff is very very hard for me, not least because my spelling is atrocious, and slow due to arthritis, so many many mistakes are made)

Anyway, i believe that the pelco command for say pan right is sent once, and the cam pans untill the stop command is sent (the tx/rx led's on my joystick seem to veryify that)
So i need to listen for commands in hex format, then translate them to servo commands, i assume the stock servo library will handle the max rotation part of the servo, i.e. even if the pan right command hasnt been nulled with a stop command, the servo will not try to move past 180 degrees,

I don't need variable speed on the servo's, they are only going to move the camera's a little bit so i can view into the nests when the parents are blocking the view of the chicks where the cam is pointing to start with, but my joystick sends the variable speed commands... the more i move the joystick in a direction, the faster the cam pans... again i can see the tx/rx led's showing the commands are sent on each speed step i pass as the joystick moves over more,

So should i do something to ignore another pan right command after the first, thus ignoring the speed steps, untill a stop command has been recieved?


My thinking is thus, upon recieving the pan right command.... 'FF 03 00 01 01' i believe   FF= sync bit, 03= cam address (already got 2 ptz's on the system, 01 and 02) 00= the first command.. not used this time, 01= pan right, 01= speed slowest,
plus the checksum i imagine... then the arduino starts sending the pan servo pulses to rotate it right, increasing the pulse count so the servo moves round???

please dont laugh too hard, this is confusing and im struggeling.
13  Using Arduino / Project Guidance / Re: Receive Pelco commands from cctv system, move servo's on: March 22, 2013, 03:15:27 pm
I put the word "Pelco" into the search facility.

So did i... well, i think i put pelco and servo, and i found people wanting to do similar, but not getting anywhere,

I need to keep it all running on my existing system really, as i not only use the cctv dvr's keyboard/joystick to operate the camera's, but an infra red controller, plus web interface, central management software and mobile phone viewer,

i'll keep looking and check the links out, i read somewhere someone had found servo's that had been modified to accept pelco commands rather than the standard varying pulses from a RC system, but it was just a comment someone made, and no more info given.
14  Using Arduino / Sensors / Re: Digital potentiometer or similar??? on: March 21, 2013, 08:48:38 pm
Not sure how many steps i'd need to make the pointer move smoothly, i'd guess 255 steps would be more than enough, but that's a lot of resistors?

Other thing is i need to keep the 24 volts away from the arduino, i'm wondering about something like an opto coupler type thing....

I am wondering if a photo sensor or LDR can be had that can do 10 to 180 ohms, and handle 24 volts at 80 Ma that the gauge seems to pull,
put the LDR or similar in a dark tube one end, other end an led, control the led's brightness via PWM from the arduino, and get analog variable resistance from the LDR,

But i imagine it wouldent be as simple as that.
15  Using Arduino / Project Guidance / Receive Pelco commands from cctv system, move servo's on: March 21, 2013, 08:42:48 pm
Anyone know of a sketch for the arduino that can receive pelco D or P commands, as used in CCTV systems for pan, tilt, zoom camera's, and translate the pan and tilt commands into servo commands???

I have a few static camera's in my aviary that i would like to move about a little, i already have a couple of proper (and expensive) PTZ dome camera's in the roof, and i use the fixed camera's pointed at the nest sites,

I want to mount the camera's on a couple of standard hobby servo's, and control the servo's using my existing CCTV systems joystick controller, which sends the Pelco commands in RS485 format down a twisted pair cable.

so i guess first thing i need is an RS485 to RS232 converter for the arduino?

But as usual i have no idea how to do the coding, or if it can even be done, i've searched and only found other wanting to do similar, but no solutions.
Pages: [1] 2 3 ... 5