Linux Format forums Forum Index Linux Format forums
Help, discussion, magazine feedback and more
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

USB Experiment board

 
Post new topic   Reply to topic    Linux Format forums Forum Index -> Programming
View previous topic :: View next topic  
Author Message
jimdog



Joined: Fri Oct 02, 2009 4:31 pm
Posts: 4

PostPosted: Fri Oct 02, 2009 4:39 pm    Post subject: USB Experiment board Reply with quote

Hi

Iḿ working on a project to receive a pulse signal from an old coin acceptor mechanism and convert it to a usb signal so I can build a new jukebox for an autonomous social centre I am involved with.

To do this I have got hold of a USB experiment board as shown here:

http://www.elexp.com/tst_bkit.htm

It uses the (quite common) CY7C6300A-PC microcontroller to translate input to usb signals on 8 of its pins. There is a driver in the kernel for this chip - cypress_cy7c63 - which I have modprobed in. The problem I am having is that the hardware isn correctly identified and so is not associating with the driver, meaning the endpoints are not exposed in /proc/bus/usb/ (which I have mounted via fstab) and so I cannot read/write any signals to the device.

Is there a way of telling the USB subsytem or HAL to associate the driver when the hardware is inserted? I have searched everywhere to find a solution and am at my wits end :-/

Taking the specific hardware out, it could be a general question as to how to modify hardware idś that lsusb shows and so associate that id with a particular driver.

Hereś some output which will hopefully help with this:


Code:
lsusb

Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 004 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 008: ID 0fc5:1222 Delcom Engineering I/O Development Board
Bus 001 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub




Code:
cat /proc/bus/usb/devices

...output cut...

T:  Bus=01 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#=  1 Spd=12  MxCh= 6
B:  Alloc=  0/900 us ( 0%), #Int=  0, #Iso=  0
D:  Ver= 1.10 Cls=09(hub  ) Sub=00 Prot=00 MxPS=64 #Cfgs=  1
P:  Vendor=1d6b ProdID=0001 Rev= 2.06
S:  Manufacturer=Linux 2.6.27-7-generic ohci_hcd
S:  Product=OHCI Host Controller
S:  SerialNumber=0000:00:02.0
C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=  0mA
I:* If#= 0 Alt= 0 #EPs= 1 Cls=09(hub  ) Sub=00 Prot=00 Driver=hub
E:  Ad=81(I) Atr=03(Int.) MxPS=   2 Ivl=255ms

T:  Bus=01 Lev=01 Prnt=01 Port=02 Cnt=01 Dev#=  8 Spd=1.5 MxCh= 0
D:  Ver= 1.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs=  1
P:  Vendor=0fc5 ProdID=1222 Rev= 0.09
S:  Manufacturer=Delcom Engineering
S:  Product=USB IO Controller
S:  SerialNumber=5286
C:* #Ifs= 1 Cfg#= 1 Atr=80 MxPwr=250mA
I:* If#= 0 Alt= 0 #EPs= 0 Cls=00(>ifc ) Sub=00 Prot=00 Driver=(none)


Code:
lsmod

cypress_cy7c63         11648  0
ipv6                  263972  14
af_packet              25728  2
binfmt_misc            16904  1
rfcomm                 44432  0
bridge                 56980  0
stp                    10628  1 bridge
bnep                   20480  2
sco                    18308  2
l2cap                  30464  6 rfcomm,bnep
bluetooth              61924  6 rfcomm,bnep,sco,l2cap
vboxnetadp             89704  0
vboxnetflt             96520  0
vboxdrv               131752  1 vboxnetflt
kvm_amd                33164  0
kvm                   142912  1 kvm_amd
ppdev                  15620  0
powernow_k8            22148  0
cpufreq_ondemand       14988  2
cpufreq_userspace      11396  0
cpufreq_conservative    14600  0
cpufreq_stats          13188  0
freq_table             12672  3 powernow_k8,cpufreq_ondemand,cpufreq_stats
cpufreq_powersave       9856  0
sbs                    19464  0
pci_slot               12552  0
video                  25104  0
output                 11008  1 video
container              11520  0
sbshc                  13440  1 sbs
battery                18436  0
iptable_filter         10752  0
ip_tables              19600  1 iptable_filter
x_tables               22916  1 ip_tables
ac                     12292  0
parport_pc             39204  0
lp                     17156  0
parport                42604  3 ppdev,parport_pc,lp
snd_ens1371            30880  2
snd_hda_intel         381488  3
psmouse                45200  0
gameport               19468  1 snd_ens1371
serio_raw              13444  0
pcspkr                 10624  0
evdev                  17696  6
snd_ac97_codec        111652  1 snd_ens1371
nvidia               6909268  36
ac97_bus                9856  1 snd_ac97_codec
snd_pcm_oss            46848  0
snd_seq_dummy          10884  0
agpgart                42184  1 nvidia
snd_seq_oss            38528  0
snd_mixer_oss          22784  1 snd_pcm_oss
i2c_core               31892  1 nvidia
snd_seq_midi           14336  0
snd_rawmidi            29824  2 snd_ens1371,snd_seq_midi
snd_pcm                83204  4 snd_ens1371,snd_hda_intel,snd_ac97_codec,snd_pcm_oss
snd_seq_midi_event     15232  2 snd_seq_oss,snd_seq_midi
snd_seq                57776  6 snd_seq_dummy,snd_seq_oss,snd_seq_midi,snd_seq_midi_event
snd_seq_device         15116  5 snd_seq_dummy,snd_seq_oss,snd_seq_midi,snd_rawmidi,snd_seq
snd_timer              29960  2 snd_pcm,snd_seq
snd                    63268  21 snd_ens1371,snd_hda_intel,snd_ac97_codec,snd_pcm_oss,snd_seq_oss,snd_mixer_oss,snd_rawmidi,snd_pcm,snd_seq,snd_seq_device,snd_timer
soundcore              15328  1 snd
shpchp                 37908  0
snd_page_alloc         16136  2 snd_hda_intel,snd_pcm
pci_hotplug            35236  1 shpchp
wmi                    14504  0
button                 14224  0
ext3                  133256  3
jbd                    55444  1 ext3
mbcache                16004  1 ext3
sd_mod                 42264  5
crc_t10dif              9984  1 sd_mod
sr_mod                 22212  0
cdrom                  43168  1 sr_mod
sg                     39732  0
pata_acpi              12160  0
ata_generic            12932  0
ahci                   37132  4
pata_amd               18692  0
forcedeth              61328  0
ehci_hcd               43276  0
libata                177312  4 pata_acpi,ata_generic,ahci,pata_amd
scsi_mod              155212  4 sd_mod,sr_mod,sg,libata
ohci_hcd               31888  0
dock                   16656  1 libata
usbcore               148848  4 cypress_cy7c63,ehci_hcd,ohci_hcd
dm_mirror              26880  0
dm_log                 17924  1 dm_mirror
dm_snapshot            26276  0
dm_mod                 63432  3 dm_mirror,dm_log,dm_snapshot
thermal                23708  0
processor              42156  2 powernow_k8,thermal
fan                    12548  0
fbcon                  47648  0
tileblit               10880  1 fbcon
font                   16512  1 fbcon
bitblit                13824  1 fbcon
softcursor              9984  1 bitblit
fuse                   60828  3


Many thanks for any help anyone can give
Back to top
View user's profile Send private message
Bazza
LXF regular


Joined: Sat Mar 21, 2009 11:16 am
Posts: 1393
Location: Loughborough

PostPosted: Sat Oct 03, 2009 4:24 pm    Post subject: Reply with quote

Hi jimdog...

Sadly I can`t answer your question as it stands,
however had you considered using the current
Arduino Dev Board which is much cheaper AND
versatile.

It mates with USB but has a built in FTDI Serial
IC to convert to to pseudo-RS232 to control
the PIC. It comes complete with SW for usage
on Windows and/or Linux, (I`ll let the bosses on
here point to the LXF mag article on how to
install on Linux). It appears as dev/ttyUSBx
where x is a single digit number.

The board has several analogue and digital
I/Os and is remarkable value for money AND
with a simple home brew discrete component
board will mate easily to an RS232 port also...

The best of both worlds... :D

I`ve already done so to mate with my serial
only AMIGA A1200 AND my USB only notebook...

Just a thought...
_________________
73...

Bazza, G0LCU...

Team AMIGA...
Back to top
View user's profile Send private message
AndyBaxman
LXF regular


Joined: Tue Oct 04, 2005 9:47 am
Posts: 520

PostPosted: Mon Oct 05, 2009 9:11 am    Post subject: Reply with quote

If you don't need it for anything else (and the motherboard has one), you could use one or more of the serial port control lines.
_________________
Bomb #20: "Let there be light"
Back to top
View user's profile Send private message
Bazza
LXF regular


Joined: Sat Mar 21, 2009 11:16 am
Posts: 1393
Location: Loughborough

PostPosted: Mon Oct 05, 2009 6:01 pm    Post subject: Reply with quote

Hi AndyBaxman...

The parallel port is probably better as almost complete
control of the data, status and control I/O addresses
are easy. Also they are at TTL level...

This lines in the parallel port are at either logic 1 or
0 at TTL whereas the RS232 serial port is + or - 3 to 12V
NRZ...

Just a thought...
_________________
73...

Bazza, G0LCU...

Team AMIGA...
Back to top
View user's profile Send private message
jimdog



Joined: Fri Oct 02, 2009 4:31 pm
Posts: 4

PostPosted: Wed Oct 07, 2009 12:25 pm    Post subject: Progress so far Reply with quote

Hiya

I've now sort of split this problem into two approaches which I'll briefly explain. I feel I'm getting a little closer to a solution which is great because I'm hearing distant murmerings of the ability of linux to be adaptable enough to do this, when a proprietary windows device could just be bought and plugged in. The future of Linux at the club depends on me being able to make this jukebox work Smile

Ok so first, regarding the I/O board that appears in lsusb, having hunted around I have found a kernel mode driver for the board at

http://sourceforge.net/projects/delcom-usbio/

which also includes a utility to make and reveal the device nodes. Only problem i, I haven't the foggiest how to compile and use it. If I try using gcc or g++ as I would normally for C projects, it exits with a huge amount of errors and wont compile. If I do manage to solve that with your help, how do I insert the new module into the running kernel or would I need to compile a custom kernel from scratch?

The second approach I have thought of for this is that I have a USB to serial converter which I can use as a serial input. The basic layout of the pins on the coin acceptor is as follows (roughly)

Pin 0 - +12V (Which I will take from the PSU)
Pin 1 - 0V
Pin 2 - emits high on £1 coin being inserted
pin 3 - 50p
pin 4 - 20p
pin 5 - 10p
pin 6 - Inhibit £1 ie rejects that coin if high
pin 7 - inhibit 50p
pin 8 - inhibit 20p
pin 9 - inhibit 10p

So there is a ribbon cable which comes from the mechanism and which I will take into the computer through serial (or usb) input.

So at this stage, I need to work out the following if I am to use serial. Firstly, if I want to receive a pulse from pins 2-5, which pins on the serial port should I use and where would these appear in the filesystem. For example if somebody enters a £1 coin, it would cause /dev/tty? to be high, ie if I did "cat /dev/tty?" it would return 1, else it would be 0.

In the same but reverse way, if I did "echo 1 > /dev/tty?" to one of the pins associated with 6-9 it would inhibi those coins from being accepted.


In a nutshell, the program I want to write is as follows once I get the interface working.

    Person enters coin (say 50p)

    program is polling the input pins and detects that /dev/tty? (pin 3) is high (1)

    program sets the inhibit pins (pins 6-9) high (1) to stop any other coins being entered for a short period of time to allow pin 3 to reset to low once the coin has passed.

    Program outputs a hex code for a key combination (eg alt+1) to stdin. This is because the jukebox softtware we have allows you to specify a key press to add credits which seems the easiest way to do it. A there won't be a keyboard attached, this seems ok to do and makes it easy for bar volunteers to attach a keyboard and add free credits.

    Program then resets the inhibitors to low after checking that all of the coin input pins are in their low state and continues polling.


I vaguely know how I would do this wth a bash script, but that seems a bit heavy duty for such a simple task so maybe it could be done with C or Python?

I hope that makes some kind of sense. I'm really grateful for the help already given. Hopefully we can crack this soon Smile
Back to top
View user's profile Send private message
AndyBaxman
LXF regular


Joined: Tue Oct 04, 2005 9:47 am
Posts: 520

PostPosted: Wed Oct 07, 2009 3:43 pm    Post subject: Reply with quote

Perhaps a simpler ( and maybe more elegant) solution would be to offload the coin-op management to something like a PIC microcontroller which could be used to emulate a PS/2 keyboard. You could then read the key input to determine coins entered and also double as a custom keyboard to select songs, etc.

PIC developer / prototyping boards are available from Maplin, etc. They are fun to program and there will certainly be a PIC that has the I/O you need.

A quick Google for Pic based keyboard emulator found plenty of hits, including this:

http://www.piclist.com/tecHREF/microchip/picboard.htm

You should be able to modify the circuit and code to implement a device that can read a custom keyboard matrix and read / set your coin mech lines.

The PIC code could just send a keycode on coin insert, or could implement a timer itself and send codes on session start / end.
_________________
Bomb #20: "Let there be light"
Back to top
View user's profile Send private message
Bazza
LXF regular


Joined: Sat Mar 21, 2009 11:16 am
Posts: 1393
Location: Loughborough

PostPosted: Wed Oct 07, 2009 8:35 pm    Post subject: Reply with quote

Hi jimdog...

> The second approach I have thought of for this is
> that I have a USB to serial converter which I can
> use as a serial input. The basic layout of the pins
> on the coin acceptor is as follows (roughly)

> Pin 0 - +12V (Which I will take from the PSU)
> Pin 1 - 0V
> Pin 2 - emits high on £1 coin being inserted
> pin 3 - 50p
> pin 4 - 20p
> pin 5 - 10p
> pin 6 - Inhibit £1 ie rejects that coin if high
> pin 7 - inhibit 50p
> pin 8 - inhibit 20p
> pin 9 - inhibit 10p

AT WHAT LEVELS?
TTL or other...

> So there is a ribbon cable which comes from the
> mechanism and which I will take into the computer
> through serial (or usb) input.

> So at this stage, I need to work out the following
> if I am to use serial. Firstly, if I want to receive a
> pulse from pins 2-5, which pins on the serial port
> should I use and where would these appear in
> the filesystem. For example if somebody enters a
> £1 coin, it would cause /dev/tty? to be high, ie if I
> did "cat /dev/tty?" it would return 1, else it would be 0.

Be very aware of USB to <something> adaptors.

Windows is fairly friendly and gives the user/coder
some useful means of accessing them. E.G. a USB to
games port for example.
A USB to serial gives the coder a COMx: port although
it is in fact a USB device and the port can be accessed
from an MS-DOS prompt easily to set it up using MODE.EXE.

However Linux in all its wisdom allocates the dev/tty? NOT
as dev/tty? but dev/ttyUSB? where "?" is a single digit
number. I suspect yours will be ttyUSB0 in the dev/ drawer.

Please note logic 1 on a(n) RS232 style serial port is -3
to -12V NOT +3 to +12V. This is NRZ, (None Return to Zero)
so be VERY AWARE.

You will need some sort conversion HW if the logic on the
coin slot has TTL or any 0 voltage on it or is switching say
greater than 9V to ground etc, etc...

I hope this helps...

BTW AndyBaxman`s PIC method seems a fair alternative
if you have some limited coding experience.
_________________
73...

Bazza, G0LCU...

Team AMIGA...
Back to top
View user's profile Send private message
AndyBaxman
LXF regular


Joined: Tue Oct 04, 2005 9:47 am
Posts: 520

PostPosted: Thu Oct 08, 2009 10:57 am    Post subject: Reply with quote

Bazza wrote:


BTW AndyBaxman`s PIC method seems a fair alternative
if you have some limited coding experience.


Hmm, you'd need somewhat more than limited coding experience to do this project anyway.

PICs are actually a doddle to work with, both electrically and programatically. They need few external components and their I/O ports can source or sink 25mA allowing them to drive LEDs and small relays directly.

And PIC assembly language is very straightforward compared to x86 assem and you don't have all of the linking hassles you get with C.

Another advantage of the keyboard emulator is you can emit any keycode sequence when a key is pressed or a coin inserted (or the timer expires if you do it that way), so you may be able to implement this jukebox with no coding on the Linux box (merely emit the right keycodes to control Xine, Amarok, etc).
_________________
Bomb #20: "Let there be light"
Back to top
View user's profile Send private message
jimdog



Joined: Fri Oct 02, 2009 4:31 pm
Posts: 4

PostPosted: Thu Nov 19, 2009 1:11 pm    Post subject: Nearly There! One more hurdle to overcome Reply with quote

Hi All

Sorry for the late reply, been distracted by other things so just getting back to this project now. Thanks loads for all your replies - I'm very nearly there so just have one more minor problem to solve and it will work perfectly.
So here's the lowdown on where I'm up to starting with the hardware:

Found a really useful site for the specific coin mech (ME111 - 15W) I have here:


http://www.markscotford.com/marscon.html

Which gave me all the info I needed for the pinouts. The main power supply (12V) comes from a drive connector for the PSU of the machine I am using for the jukebox. The +5V is being fed into the 10p and 50p inhibit channels, and 0V is going into the 20p and £1 channels so they don't float. The Vcom (common voltage that comes out of the outputs when a coin is inserted) is receiving 12V. I have attached 2 relays next to the usb interface board, so that when a coin (£1 or 20p) is inserted, the relay is triggered by the +12V that it receives from the Vcom channel and the relevant pin on the microcontroller is set to low (default when switched on is high). Ok, so the hardware is all there and working perfectly, so now on to the receiving end for the USB signal.

I managed to find a C library for this interface board after much searching about here:

http://www.sourcefiles.org/Programming/Libraries/Networking/libdelcom-0.2.tgz

There were some example programs floating about which worked great with my board, so I set about modifying one of these to suit my needs. I also needed to figure out a way of sending the output to the currently focused X-window rather than outputting to the terminal and so settled on using the keysim.h and xtest.h libraries to spoof an x input signal. The upshot of all this bashing about is the following program which works great except for one minor problem which I will explain below.

Code:

#include <stdio.h>
#include "libdelcom.h"
#include <X11/Xlib.h>
#include <X11/keysym.h>
#include <X11/extensions/XTest.h>

int main(void)
{
   Display *display;
   unsigned int keycode;
   display = XOpenDisplay(NULL);

   int i,pos,ret;
   struct delcom_info dd;
   ret = delcom_init(&dd,0);
   if(ret==0) {
      printf("Device not found... Sorry\n");
      return 0;
   }
   delcom_select_device(&dd,0);

   struct delcom_packet payload;

   pos = 0;
   int bit0, bit1, bit0old, bit1old;
   while(1) {
      // Read in the registers
      payload.MajorCmd    = 0x0b;
      payload.MinorCmd    = 0x00;
      payload.DataLSB     = 0x00;
      payload.DataMSB     = 0x00;
      for(i=0; i<8; i++) payload.DataExtension[i]=0;
      delcom_send_command(&dd, &payload);
      bit0 = (0x01 & payload.DataExtension[0]) ? 1 : 0;
      bit1 = (0x02 & payload.DataExtension[0]) ? 1 : 0;
      if((bit0 != bit0old) || (bit1 != bit1old)) {
         if((bit0old != bit0) && (bit1old != bit1))
            printf("Beginning Program\n");
         else if((bit0old == 0) && (bit1old == 0)) {
            if((bit0 == 1) && (bit1 == 0)) {
                pos--;
            }
            else if((bit0 == 0) && (bit1 == 1)) {
                pos++;
            }
         }
         
         if(bit0 == 0) {

         keycode = XKeysymToKeycode(display, XK_A);
         XTestFakeKeyEvent(display, keycode, True, 0);
         XTestFakeKeyEvent(display, keycode, False, 0);
         XFlush(display);
         printf("\n");
         
         }

         else if(bit1 == 0) {

         keycode = XKeysymToKeycode(display, XK_B);
                        XTestFakeKeyEvent(display, keycode, True, 0);
                        XTestFakeKeyEvent(display, keycode, False, 0);
                        XFlush(display);
         printf("\n");
                  
         }

         bit0old = bit0;
         bit1old = bit1;
                  
      }
   }

   delcom_close(&dd);

   return 0;
}


I compiled this with the following command:

Quote:
~/Desktop/Delcom/libdelcom $ gcc main.c -o main2 -lusb libdelcom.o -lX11 -lXtst


This works brilliantly - the usb interface is registered fine, the program recognises the input from the coin mechanism, the only problem is that when a coin is inserted, it outputs 4 instances of the key press and gets the \n wrong like so:

Quote:

Beginning Program
bbb
baa
aabb
bb


I realise that this will be something to do with the amount of time that the Vcom output is fed to the pin with the relay (around 1000ms I think) so basically I need to either put a sleep() somewhere (but I have no idea where/how to include this) or to check within the while loop if this is the first time that the pin has been registered as low within this timescale, and if so to only do the XTEST command once until the pin is reset back to high.

Any thoughts on this would be gratefully received. Everything else is working great, it's just this final hurdle to overcome Smile
Back to top
View user's profile Send private message
Bazza
LXF regular


Joined: Sat Mar 21, 2009 11:16 am
Posts: 1393
Location: Loughborough

PostPosted: Thu Nov 19, 2009 10:20 pm    Post subject: Reply with quote

Hi jimdog...

Here is an idea...

You could try a simple, (CPU hogging... ;o), while loop as
a temporary addition. See the end for example code.

I think you`ll need it at the point shown in your code below...
(Note my `childish` coding method. ;o)

If there are any typos then I will apologise but I have read
it many times and can`t see any.

It is inelegant and professional coders will snub it, but it is
worth a try however......


Code:
[snip]
            delcom_send_command(&dd, &payload);
            bit0 = (0x01 & payload.DataExtension[0]) ? 1 : 0;
            bit1 = (0x02 & payload.DataExtension[0]) ? 1 : 0;
            /* THIS IS WHERE I THINK THE FUNCTION........ */
            /* timedelay(); */
            /* ........SHOULD GO. */
            if((bit0old != bit0) && (bit1old != bit1)) {
[snip]
}
/* Final bracket of your code. */
/* Place the function here... */


This method means you can put the delay anywhere
without affecting your basic code in anyway.

It requires NO dependances, NO defines, nothing and adds very
little to the executable size.

All it does is eat up CPU cycles and therefore slows down the
program at ANY point in which the function call is placed.

This is the example code:-
NOTE:- the brackets at the end of the `return(0)`
statements/keywords may not be needed under GCC...

Code:

/* NOTE:- FROM HERE........ */

/* Note:- No includes, defines or structures... */
/* Compiled using Dice-C and VBCC inside WinUAE */
/* on this quad core 2.4GHz machine... */

/* Program start... */
int main()

/* This is the main body to test a function called timedelay(). */
{
   /* Call the timedelay function. */
   timedelay();
   /* When done return back to calling routine as OK. */
   return(0);
}
/* Program end. */

/* ........TO HERE IS FOR DEMONSTRATION ONLY. */


/* Function start. */
/* This is the timedelay function, `n` is changed and recompiled each time... */
int timedelay()
{
   /* Assign long integers to allow for high speed CPUs. */
   /* Note that the maximum positive values are 31 bits long. */
   long int m;
   long int n;

   /* Set the `n` value by trial and error, needs recompiling everytime. */
   m=0;
   n=10000;

   /* Use the while statement. */
   while(m<n) m=m+1;

   /* Return back to the calling routine. */
   return(0);
}
/* Function end. */


Keep us informed... :)
_________________
73...

Bazza, G0LCU...

Team AMIGA...
Back to top
View user's profile Send private message
jimdog



Joined: Fri Oct 02, 2009 4:31 pm
Posts: 4

PostPosted: Tue Nov 24, 2009 5:12 pm    Post subject: Reply with quote

w00t

I think I might have cracked it (though in a remarkably fudgey way). The answer was in the fact that I was registering both bit0/bit1 and the previous value at bit0old/bit1old. This means, that if a coin is inserted the values might look as follows: Taking bit0 (£1 coin) as an example~

Code:

---bit0 value-|-bit0old value---
------------------------------

        1                   1           //normal state if no coin inserted
        1                   1           //loops waiting for input
        1                   1
        0                   1           //coin inserted (£1) - bit0 = 0
        0                   0           //bit0old set to 0 on this loop
        0                   0           //duration of coin insertion
        1                   0           //coin acceptor pin reset high
        1                   1           //bit0old becomes high
        1                   1           //while loop continues


So looking at this table, there are 2 unique combinations of bit0 and bit0old, at the point of coin insertion where the relay triggers (0,1), and at the point of relay release (1,0). This meant that I had 2 unique instances to play with which were not dependant on any time delay in the relay being switched (which by having moving parts is bound to be imprecise). Therefore, I took one of these instances and modified the code to trigger the Xkeypress on that event like so:

Code:


...
   pos = 0;
   int bit0, bit1, bit0old, bit1old;
   while(1) {
      // Read in the registers
      payload.MajorCmd    = 0x0b;
      payload.MinorCmd    = 0x00;
      payload.DataLSB     = 0x00;
      payload.DataMSB     = 0x00;
      for(i=0; i<8; i++) payload.DataExtension[i]=0;
      delcom_send_command(&dd, &payload);
      bit0 = (0x01 & payload.DataExtension[0]) ? 1 : 0;
      bit1 = (0x02 & payload.DataExtension[0]) ? 1 : 0;
      if((bit0 != bit0old) || (bit1 != bit1old)) {
         if((bit0old != bit0) && (bit1old != bit1))
            printf("Beginning Program\n");
         else if((bit0old == 0) && (bit1old == 0)) {
            if((bit0 == 1) && (bit1 == 0)) {
                pos--;
            }
            else if((bit0 == 0) && (bit1 == 1)) {
                pos++;
            }
         }

         if ((bit0 == 1) && (bit0old == 0)) {
         keycode = XKeysymToKeycode(display, XK_A);
         XTestFakeKeyEvent(display, keycode, True, 0);
         XTestFakeKeyEvent(display, keycode, False, 0);
         XFlush(display);
         

         }
         else if ((bit1 == 1) && (bit1old == 0)) {
         keycode = XKeysymToKeycode(display, XK_B);
                        XTestFakeKeyEvent(display, keycode, True, 0);
                        XTestFakeKeyEvent(display, keycode, False, 0);
                        XFlush(display);
         
         }
         else {
         printf("\n");
         }

         bit0old = bit0;
         bit1old = bit1;
         
         
      }
   }
...


This works, but it takes a couple of loops to set itself up correctly - on the firs loop it correctly displays the "beginning program" message, but on the second it outputs "a" (which is the pound coin entered signal), which suggests I still need to tidy it up a little.

Does anyone have any suggestions as to how I could do this (bearing in mind it does work as is, but for learning C I'm trying to get it perfect), and also how to build in some kind of failsafe, so that if the process dies for any reason, it will respawn another instance (so noone gets their money swallowed by the machine if this coin acceptance program mysteriously dies). Is there a way to do this either in the program itself, or in the init bash script I intend to use to launch it when the machine is switched on?

Many thanks

JimDog
Back to top
View user's profile Send private message
View previous topic :: View next topic  
Display posts from previous:   
Post new topic   Reply to topic    Linux Format forums Forum Index -> Programming All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
Linux Format forums topic RSS feed 


Powered by phpBB © 2001, 2005 phpBB Group


Copyright 2011 Future Publishing, all rights reserved.


Web hosting by UKFast