Milan API questions

Support for the Milan Intelligent interface, sold by Money Controls as the Paylink USB unit and for the earlier PCI card version.

Moderators: aardvark, davebush, Admin

Post Reply
John

Milan API questions

Post by John »

I am using a MCL PCI card, for which I need to write an interface to our software.
We do not have any peripherals ­ not yet anyway,­ but please have a look at the questions and advice me back. Your help will be greatly appreciated.


1. Enable /Disable individual acceptors and dispensers

1. Read the acceptors/ dispensers
2. For dispensers set the Inhibit to 1 to inhibit the dispenser
3. For acceptors inhibit is "this coin inhibited"
Is this the flag that I can use to inhibit the acceptor?
4. Write the acceptors/ dispensers details

2. If the EnableInterface called after an acceptor was inhibited, will this enable the acceptor?

3. There is a similar Enable/Disable interface for the dispensers?

4. CurrentValue questions.
4.1. Currentvalue returns the money in the lowest denomination of
the currency of all coins and notes read.
If a user inserts
- 1 pound - Currentvalue returns 1
- 10 pence - Currentvalue 10
- 1 pound - Currentvalue 100

Then if a user inserts the same amounts as above but the Current
value is only called at the and it will return 210

The question is really how do I get a notification that the
denomination changed?

The currency flag is for the denomination of the coins and notes or
for the currency like "$" or "£"


4.2. How do I set the currency? By configuring the Currency
from the blocks?
4.3. Where is the currency codes defined?


5.Read/WriteInterfaceblock
What is the definition of the Block?
davebush
Posts: 482
Joined: Fri Oct 22, 2004 12:20 pm

Post by davebush »

Hi John.

I hope you have our "Complete PC SDK" for reference, if you don't you can get it from http://www.aardvark.eu.com/products/milan/downloads.htm

Part of the point of the PCI card is devices independence, so if you can find *any* acceptors we support, you can test with those.

Answers to your questions are:
1.1 To inhibit / enable an acceptor set / clear the ACCEPTOR_INHIBIT bit in the AcceptorBlock.Status field.

1.2 To inhibit / enable a dispenser set / clear the DispenserBlock.Inhibit field (to 1 / 0).

1.3 To inhibit / enable a specific coin, set / clear the Acceptor.Coin[CoinNumber].Inhibit field.

and then Write the details back.

In all cases you find the correct block by checking (xxxxBlock.Unit & DP_GENERIC_MASK) == DP_COIN_ACCEPT_DEVICE, DP_NOTE_ACCEPT_DEVICE or DP_COIN_PAYOUT_DEVICE


EnableInterface is how you announce to the PCI card that you're ready to go.

Until you call EnableInterface everything is disabled / inhibited, regardless of the AcceptorBlock setting. After you call it, they will correspond to your settings (enabled by default).


CurrentValue increments for the life of the card. You read this value following the call to OpenMHE and before the call to EnableInterface to establish a starting point before any coins or notes are read. You keep track of value that has been used up and monitor for new coin / note insertions by increases in the returned value.

Our reference to lowest denomination is obviously confusing. This is not dynamic as you have assumed, but fixed. One Pound / Euro / Dollar is *always* 100.

The currency values and the CurrenyCode are determined automatically by querying the devices. The CurrenyCode is taken from a string returned by the acceptors, and so there is no predicatabilty to it. (We do not currently handle the situation where a device accepts more than one currency)

The interface blocks are described in the PDF manual in the SDK folder.

Finally, if you are are routing coins to a hopper, the algorithm is described in the manual. Although it looks slightly complicated, in practice it is very easy to program / use.
Aardvark software developer. Please put all communication on the problem through the board for the benefit of others.
John

Post by John »

Your reply has helped me to progress very fast.

But I have 4 more confusing questions.

1. Do you have an example for how to decode the return value of :
long SystemStatus (void) ;

2. Is there a Reset command?

3. Now the confusing bit:

"Associated with each coin is an (interface maintained) count of the total number of instances of the coin that have ever gone down that specific path (Coin.PathCount). This number is undisturbed over changes in the value of the specific path - i.e. it is related only to the coin, not to the path."

I don't understand "number of instances of the coin that have ever gone down that specific path" vs "is related only to the coin, not to the path.""

4. At interface initialisation this is zero for each coin, i.e. they will all be routed to the default destination.
The basic algorithm for applications is to set the specific path for each "payout" coin to the route that will take it to its dispenser and then detect, by operator input, that the dispenser is full.
4.1--- > At this point,----->> [John] the point when the dispenser is full----->the level (Coin.PathSwitchLevel) is set to the current path count (Coin.PathCount). From then on, whenever coin(s) are paid, the application increments the level (Coin.PathSwitchLevel) by the number of coins paid out. (This number is available in the dispenser detail field Dispenser.Count)
4.2 ---> The interface will, consequently, send coins to the
dispenser until ----->>>it is again full and then automatically switch to the cash box, with no further input from the application.

So what happens when the dispenser is full 4.1. or 4.2?
davebush
Posts: 482
Joined: Fri Oct 22, 2004 12:20 pm

Post by davebush »

1/ I'm sorry but the SystemStatus call is currently a placeholder, we've not yet implemented any anything in this area.:oops:

2/ There's no (apparent) need for an application to issue a reset command - all the internal subsystems continue past errors. The entire card does not cope with devices being replaced and there is a debugging facility that allows a developer to reset the card, intended for use in fault finding when either the peripherals have been changed or you're trying to get a clear trace of an error.

3/ Coin routing:
There are two routes associated with a coin: Coin.Path (the specific / Hopper path) and the Coin.DefaultPath (the default Cashbox path). The comment is pointing out that changes in the value of Coin.Path don't affect the value accumulated in Coin.PathCount. i.e. if 6 coins are routed to path 4, and you then change the path to 2 and route another 5 to there, then PathCount will be 11.

4.1 is setting the initial conditions, the operator / application identifies that the dispenser is full. Setting Coin.PathSwitchLevel to Coin.PathCount essentially notifies the card of this fact. (This will be during some sort of re-fill operation)

4.2 is a description of how the card automatically detects that the dispenser must again be full (based on counting coins in and out).

Both are "when the dispenser is full", 4.2 describes the automatic operation of the card.
Last edited by davebush on Fri Oct 22, 2004 2:00 pm, edited 1 time in total.
Aardvark software developer. Please put all communication on the problem through the board for the benefit of others.
John

Post by John »

I almost feel I want to say "Aha" :D

It really helps that you explain the things so clearly.

Thank for your speedy answer.
davebush
Posts: 482
Joined: Fri Oct 22, 2004 12:20 pm

Post by davebush »

Hi John,

The fundamental principle behind the operation of the Milan PCI Card is that all reporting to the PC takes place in terms of totals (and sometimes states), not events. As there are no events, you can’t possibly miss them!

The basic idea is that, before you issue EnableInterface, you capture a snapshot of all the totals you are interested in. (In your case, this is all the individual notes/coins as well as CurrentValue.) You then enable the interface and monitor the totals for changes. The difference between your saved values and the values you read is the “current unused credit”. You can either treat this change internally as an event, and pass it on to the rest of your program before updating your saved totals, or you can regard it directly as the users “current credit” and update your saved totals when he “spends” some of it.

If you wish to, you will have no problems ignoring CurrentValue and just monitoring the coins/notes directly. You are reading information from PCI bus memory and so a scan will only take microseconds.

Alternatively, you can use changes in CurrentValue as a “flag” to indicate that a scan should be undertaken - having spotted a change in CurrentValue, you remember the new value and then scan all the coins/notes comparing the values read with those you’ve saved.

In the (very rare) circumstance where a coin is registered after you find a change in CurrentValue but before you complete the scan, you will find the CurrentValue has changed as soon as you start monitoring it again. The scan that follows will however find no change.

Using this algorithm, you will correctly register every update, and although you will occasionally do a coin/note scan the finds no change, you will never fail to scan when a change is waiting.

I trust this is clear
:wink:
Aardvark software developer. Please put all communication on the problem through the board for the benefit of others.
Post Reply