├── ccTalk.cpp ├── ccTalk.h ├── examples └── ArduinoccTalk │ └── ArduinoccTalk.ino ├── headers.h └── library.properties /ccTalk.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "ccTalk.h" 3 | #include "headers.h" 4 | // 5 | 6 | //The millistimer class used for delays 7 | void milistimer::startt(int tdelay) {// start the timer witth delay in miliseconds. 8 | unsigned long temp; 9 | temp = millis(); 10 | target = temp + tdelay; 11 | }; 12 | 13 | bool milistimer::isready(void) {//return true if timer is expired 14 | unsigned long temp; 15 | temp = millis(); 16 | if (target - temp > 86400000) // one day 17 | return true; 18 | else 19 | return false; 20 | }; 21 | 22 | //constructor 23 | ccTalk::ccTalk(Stream *s) : stream(s) { 24 | RX_bytecount = 0; 25 | } 26 | 27 | const char* const ccTalk::RX_msg[] = {"RXidle","RXloop","RXansw","RXcomplete","RXflush","RXerr_unexpected_byte_in_idle","RXerr_no_loopback","RXerr_wrong_loopback","RXerr_answer_timeout",\ 28 | "RXerr_msg_length","RXerr_checksum_failed"}; 29 | 30 | size_t ccTalk::write(uint8_t c){ 31 | stream->write(c); 32 | }; 33 | 34 | int ccTalk::available(){ 35 | return stream->available(); 36 | }; 37 | 38 | int ccTalk::read(){ 39 | return stream->read(); 40 | }; 41 | 42 | int ccTalk::peek(){ 43 | return stream->peek(); 44 | }; 45 | 46 | void ccTalk::flush(){ 47 | stream->flush(); 48 | }; 49 | 50 | void ccTalk::cctsend(unsigned char command,unsigned char dest,unsigned char msglength,\ 51 | unsigned char D00,unsigned char D01,unsigned char D02,unsigned char D03,\ 52 | unsigned char D04,unsigned char D05,unsigned char D06,unsigned char D07){ 53 | unsigned char temp = 0; 54 | TX_buffer[0] = dest; 55 | TX_buffer[1] = msglength; 56 | TX_buffer[2] = 1; // implicit source , only for 8 bit checksum 57 | TX_buffer[3] = command; 58 | TX_buffer[4] = D00;TX_buffer[5] = D01;TX_buffer[6] = D02;TX_buffer[7] = D03; 59 | TX_buffer[8] = D04;TX_buffer[9] = D05;TX_buffer[10] = D06;TX_buffer[11] = D07; 60 | TX_buffer[msglength+4]=0; 61 | for (temp = 0 ; temp < msglength+4 ; temp++){// a simple checksum and send the message 62 | TX_buffer[msglength+4]-=TX_buffer[temp]; 63 | stream->write(TX_buffer[temp]); 64 | } 65 | stream->write(TX_buffer[msglength+4]);// and the simple checksum 66 | startrx();// Start the receiving the answer 67 | } 68 | 69 | void ccTalk::comm_init(){// init the serial port and flush RX buffer 70 | breakrx(); 71 | } 72 | 73 | int ccTalk::watchdog_poll(){ 74 | cctsend(simple_poll, 2, 0); 75 | while (RX_state < RXcomplete) { 76 | ccTalkReceive(); // wait for an answer or error 77 | } 78 | if (RX_state != RXcomplete) { 79 | return 0; 80 | } else { 81 | return 1; 82 | } 83 | 84 | } 85 | 86 | void ccTalk::device_reset(){ 87 | cctsend(reset_device, 2, 0); //ben added because credit buffer stays if power isn't reset 88 | while (RX_state < RXcomplete) { 89 | ccTalkReceive(); // wait for an answer or error 90 | } 91 | // if (RX_state != RXcomplete) //error handling 92 | } 93 | 94 | void ccTalk::device_init(){ 95 | cctsend(simple_poll, 2, 0); 96 | while (RX_state < RXcomplete) { 97 | ccTalkReceive(); // wait for an answer or error 98 | } 99 | // if (RX_state != RXcomplete) //error handling 100 | 101 | cctsend(reset_device, 2, 0); //ben added because credit buffer stays if power isn't reset 102 | while (RX_state < RXcomplete) { 103 | ccTalkReceive(); // wait for an answer or error 104 | } 105 | // if (RX_state != RXcomplete) //error handling 106 | 107 | for (int i = 0; i < 16 ; i++) coin_value[i] = 0; // Clean the coin value array 108 | 109 | // Get coin ID, filter garbage convert and store in coin_value as unsigned int 110 | for (unsigned char i = 1; i < 17; i++) { 111 | somedelay.startt(2);//for some unknown reason a little delay is needed between polls 112 | do { 113 | } while (!somedelay.isready()); 114 | cctsend(request_coin_id, 2, 1, i); 115 | while (RX_state < RXcomplete) { 116 | ccTalkReceive(); 117 | } 118 | if (RX_state != RXcomplete) { 119 | // if (RX_state != RXcomplete) //error handling 120 | //Serial.print(RX_msg[RX_state]);// Show the error if any 121 | //Serial.print(" at coin channel "); 122 | //Serial.println(i); 123 | break; 124 | } 125 | if ((RX_buffer[4] == 32) && (RX_buffer[4] == 32) && (RX_buffer[4] == 32) && (RX_buffer[4] == 32) && (RX_buffer[4] == 32) && (RX_buffer[4] == 32)) continue; 126 | if ((RX_buffer[4] == 46) && (RX_buffer[4] == 46) && (RX_buffer[4] == 46) && (RX_buffer[4] == 46) && (RX_buffer[4] == 46) && (RX_buffer[4] == 46)) continue; 127 | if ((65 > RX_buffer[4]) || (RX_buffer[4] > 90) || (65 > RX_buffer[5]) || (RX_buffer[5] > 90) || (65 > RX_buffer[9]) || (RX_buffer[9] > 90)) break; 128 | if ((48 > RX_buffer[6]) || (RX_buffer[6] > 57) || (48 > RX_buffer[7]) || (RX_buffer[7] > 57) || (48 > RX_buffer[8]) || (RX_buffer[8] > 57)) break; 129 | // printASCIIdata();// Print ASCII coin ID 130 | coin_value[i - 1] = (RX_buffer[6] - 48) * 100 + (RX_buffer[7] - 48) * 10 + RX_buffer[8] - 48; 131 | } 132 | //Serial.println("Coin values OK"); 133 | //Serial.println("Setting individual inhibits"); 134 | cctsend(modify_inhibit_status, 2, 2, 255, 255); //just enable all channels 135 | while (RX_state < RXcomplete) { 136 | ccTalkReceive(); 137 | } 138 | // if (RX_state != RXcomplete) //error handling 139 | //if (RX_buffer[3] == 0) Serial.println("OK"); 140 | //else { 141 | // Serial.println("Error setting inhibits"); 142 | //} 143 | 144 | //Serial.println("Setting master inhibit"); 145 | cctsend(modify_master_inhibit_status, 2, 1, 1); 146 | while (RX_state < RXcomplete) { 147 | ccTalkReceive(); 148 | } 149 | // if (RX_state != RXcomplete) //error handling 150 | //if (RX_buffer[3] == 0) Serial.println("OK"); 151 | //else { 152 | // Serial.println("Error setting master inhibit"); 153 | //} 154 | 155 | } 156 | 157 | char * ccTalk::get_master_inhibit(){ 158 | //Serial.println("Getting master inhibit"); 159 | cctsend(request_master_inhibit_status, 2, 0); 160 | while (RX_state < RXcomplete) { 161 | ccTalkReceive(); 162 | } 163 | // if (RX_state != RXcomplete) //error handling 164 | return printBINdata(); 165 | } 166 | 167 | void ccTalk::master_inhibit_off(){ 168 | //Serial.println("Setting master inhibit"); 169 | cctsend(modify_master_inhibit_status, 2, 1, 1); 170 | while (RX_state < RXcomplete) { 171 | ccTalkReceive(); 172 | } 173 | // if (RX_state != RXcomplete) //error handling 174 | // if (RX_buffer[3] == 0) Serial.println("OK"); 175 | 176 | } 177 | 178 | void ccTalk::master_inhibit_on(){ 179 | //Serial.println("Setting master inhibit"); 180 | cctsend(modify_master_inhibit_status, 2, 1, 0); 181 | while (RX_state < RXcomplete) { 182 | ccTalkReceive(); 183 | } 184 | // if (RX_state != RXcomplete) //error handling 185 | // if (RX_buffer[3] == 0) Serial.println("OK"); 186 | } 187 | 188 | char * ccTalk::get_inhibit(){ 189 | //Serial.println("Getting individual inhibit"); 190 | cctsend(request_inhibit_status, 2, 0); 191 | while (RX_state < RXcomplete) { 192 | ccTalkReceive(); 193 | } 194 | // if (RX_state != RXcomplete) //error handling 195 | return printBINdata(); 196 | } 197 | 198 | void ccTalk::inhibit_off(){ 199 | cctsend(modify_inhibit_status, 2, 2, 255, 255); //just enable all channels 200 | while (RX_state < RXcomplete) { 201 | ccTalkReceive(); 202 | } 203 | // if (RX_state != RXcomplete) //error handling 204 | // if (RX_buffer[3] == 0) Serial.println("OK"); 205 | } 206 | 207 | void ccTalk::inhibit_on(){ 208 | cctsend(modify_inhibit_status, 2, 2, 0, 0); //just disable all channels 209 | while (RX_state < RXcomplete) { 210 | ccTalkReceive(); 211 | } 212 | // if (RX_state != RXcomplete) //error handling 213 | // if (RX_buffer[3] == 0) Serial.println("OK"); 214 | 215 | } 216 | 217 | 218 | 219 | void ccTalk::diagnostic(){ 220 | cctsend(simple_poll, 2, 0); 221 | while (RX_state < RXcomplete) { 222 | ccTalkReceive(); // wait for an answer or error 223 | } 224 | // if (RX_state != RXcomplete) //error handling 225 | 226 | cctsend(reset_device, 2, 0); //ben added because credit buffer stays if power isn't reset 227 | while (RX_state < RXcomplete) { 228 | ccTalkReceive(); // wait for an answer or error 229 | } 230 | // if (RX_state != RXcomplete) //error handling 231 | 232 | cctsend(request_manufacturer_id, 2, 0); 233 | while (RX_state < RXcomplete) { 234 | ccTalkReceive(); 235 | } 236 | // if (RX_state != RXcomplete) //error handling 237 | // printASCIIdata(); // Print the manufacturer ID 238 | 239 | cctsend(request_equipment_category_id, 2, 0); 240 | while (RX_state < RXcomplete) { 241 | ccTalkReceive(); 242 | } 243 | // if (RX_state != RXcomplete) //error handling 244 | // printASCIIdata(); // Print the equipment category ID 245 | 246 | cctsend(request_product_code, 2, 0); 247 | while (RX_state < RXcomplete) { 248 | ccTalkReceive(); 249 | } 250 | // if (RX_state != RXcomplete) //error handling 251 | // printASCIIdata(); // Print the product code 252 | 253 | cctsend(request_software_revision, 2, 0); 254 | while (RX_state < RXcomplete) { 255 | ccTalkReceive(); 256 | } 257 | // if (RX_state != RXcomplete) //error handling 258 | // printASCIIdata(); // Print the Software revision 259 | 260 | } 261 | 262 | int ccTalk::read_credit(){ 263 | cctsend(read_buffered_credit_or_error_codes, 2, 0); 264 | while (RX_state < RXcomplete) { 265 | ccTalkReceive(); 266 | } 267 | if (RX_state != RXcomplete) { 268 | return -1; 269 | } 270 | 271 | somedelay.startt(2);//for some unknown reason a little delay is needed between polls 272 | do { 273 | } while (!somedelay.isready()); 274 | // find how many new events are queued, RX_buffer[4] data contains the event counter 275 | if (RX_buffer[4] >= coineventcounter) buffered_events = RX_buffer[4] - coineventcounter; 276 | else buffered_events = RX_buffer[4] + 255 - coineventcounter; 277 | 278 | if (buffered_events > 5) {// overflow,events lost, put some error handling here 279 | buffered_events = 0; 280 | coineventcounter = RX_buffer[4]; //Clear the queued events 281 | } 282 | 283 | credit = 0; 284 | while (buffered_events > 0) {// Read buffered events one by one 285 | buffered_events--; 286 | coineventcounter = (coineventcounter + 1) % 256;//increment event counter 287 | if (coineventcounter == 0) coineventcounter = 1; // skip 0 288 | if (RX_buffer[(buffered_events << 2) + 5] == 0) { // event A = 0 means an error or coin rejected 289 | return -1; 290 | //Serial.print("Some error or coin rejected, error code: "); 291 | //Serial.println(RX_buffer[(buffered_events << 2) + 6]);// then event B is the error code 292 | } else { 293 | credit += coin_value[RX_buffer[(buffered_events << 2) + 5] - 1]; 294 | //Serial.print("Sorter path "); 295 | //Serial.println(RX_buffer[(buffered_events << 2) + 6]); // event B show the sorter path 296 | } 297 | } 298 | return credit; //buffered credit 299 | } 300 | 301 | void ccTalk::breakrx(){ // stop transmission right away and flush the buffer 302 | //the transmission buffer might still send the remaining bytes 303 | // cctalkreceive job will put the RX_state to RX_idle when ready 304 | RX_state = RXflush; 305 | comt.startt(answertimeout); 306 | } 307 | 308 | void ccTalk::clearrxerror(){ 309 | RX_state = RXflush;// does not set the timer since it was allready set when the state was changed to error. 310 | } 311 | 312 | void ccTalk::startrx(){// put RX to wait for an answer . To use after cctsend only 313 | RX_state = RXloop; 314 | comt.startt(interbytetimeout); 315 | RX_bytecount = 0; 316 | } 317 | 318 | char * ccTalk::printASCIIdata() { // returns the ascii data field 319 | for (int i = 4 ; i < RX_buffer[1] + 4; i++) { 320 | //Serial.write(RX_buffer[i]); 321 | get_data[i-4] = RX_buffer[i]; 322 | } 323 | get_data[RX_buffer[1]+4] = (char)0; 324 | return get_data; 325 | } 326 | 327 | char * ccTalk::printBINdata() { // returns the bin data field as ASCII string 328 | length = 0; 329 | for (int i = 4 ; i < RX_buffer[1] + 4; i++) { 330 | length+= snprintf(get_data+length, MAXDATALENGTH-length, "%d ", RX_buffer[i]); 331 | } 332 | return get_data; 333 | } 334 | 335 | void ccTalk::ccTalkReceive() {// the main process , should be called often enough. 336 | unsigned char temprx; 337 | do {// at least one pass even there is no char in the buffer 338 | // as many passes as bytes in the receive buffer 339 | //Serial.println(RX_msg[RX_state]); //debugging 340 | switch (RX_state) { 341 | case RXidle: { // If a character was received then change the status to flush; 342 | if (stream->available()) { 343 | RX_state = RXflush; 344 | comt.startt(answertimeout);//set the flush timer 345 | temprx = stream->read();//blind read the received byte 346 | } 347 | break; 348 | } 349 | case RXloop: { 350 | if (stream->available()) { // ignore the timeout if there is a char on queue 351 | temprx = stream->read(); 352 | RX_buffer[RX_bytecount] = temprx; 353 | if (RX_buffer[RX_bytecount] != TX_buffer[RX_bytecount]) { //error , wrong loopback 354 | RX_state = RXerr_wrong_loopback; 355 | comt.startt(answertimeout); 356 | break; 357 | } else { // no loopback error 358 | RX_bytecount++; 359 | if (RX_bytecount > (RX_buffer[1] + 4)) { //loopback ready, prepare for the answer 360 | RX_bytecount = 0;// reset the byte counter 361 | RX_state = RXansw;// 362 | comt.startt(answertimeout);// set the timeout for the answer 363 | } else { //loopback in progress 364 | comt.startt(interbytetimeout);//set the timeout for the next byte 365 | } 366 | } 367 | } else { 368 | if (comt.isready()) { // timeout 369 | RX_state = RXerr_no_loopback;// Error 370 | comt.startt(answertimeout); 371 | } 372 | } 373 | break; 374 | } 375 | case RXansw: { 376 | if (stream->available()) { // ignore the timeout if there is a char on queue 377 | temprx = stream->read(); 378 | RX_buffer[RX_bytecount] = temprx; 379 | // skip source and destination check leaving them for later 380 | if ((RX_bytecount >= 1) && (RX_buffer[1] > maxDataLength)) { // check message legth 381 | RX_state = RXerr_msg_length; 382 | comt.startt(answertimeout); 383 | break; 384 | } 385 | RX_bytecount++; 386 | if (RX_bytecount > (RX_buffer[1] + 4)) { //message complete 387 | unsigned char checksum = 0; 388 | // do checksum 389 | for (RX_bytecount = 0; RX_bytecount++ ; RX_bytecount <= RX_buffer[1] + 4) { 390 | checksum = RX_buffer[RX_bytecount]; 391 | } 392 | if (checksum != 0) { //checksum error 393 | RX_state = RXerr_checksum_failed; 394 | comt.startt(answertimeout); 395 | break; 396 | } else {// successfull 397 | RX_state = RXcomplete;// no timeout needed , a message can be sent right away 398 | break; 399 | } 400 | }; 401 | } else { 402 | if (comt.isready()) { // timeout 403 | RX_state = RXerr_answer_timeout;// Error 404 | if (RX_bytecount > 0){//no reason to set the timeout if allready was a timeout 405 | comt.startt(answertimeout); 406 | } 407 | } 408 | } 409 | break; 410 | } 411 | case RXcomplete: { 412 | //do nothing, stay here until the main program does something 413 | // just ignore all other bytes received if a complete correct answer was received 414 | // they will be handled when going to Idle state 415 | break; 416 | } 417 | case RXflush: { 418 | if (stream->available()) { //read all bytes until answer timeout 419 | temprx = stream->read(); 420 | comt.startt(answertimeout); 421 | } 422 | if (comt.isready()) { // timeout 423 | RX_state = RXidle;// Error 424 | } 425 | break; 426 | } 427 | default: {// here are all errors 428 | // nothing can be done here we only keep an eye on the break length 429 | if (stream->available()) { //read all bytes, the timer is set where the error is found. 430 | temprx = stream->read();// 431 | comt.startt(answertimeout);//restart the timer if a character is received 432 | } 433 | } 434 | } 435 | } while (stream->available()); 436 | } 437 | -------------------------------------------------------------------------------- /ccTalk.h: -------------------------------------------------------------------------------- 1 | #ifndef ccTalk_h 2 | #define ccTalk_h 3 | #include "Arduino.h" 4 | 5 | #define MAXDATALENGTH 58 6 | 7 | class milistimer 8 | { 9 | public: 10 | void startt(int tdelay); // start the countdown with tdelay in miliseconds 11 | bool isready(void);// return true if timer expired 12 | private: 13 | unsigned long target; 14 | }; 15 | 16 | class ccTalk : public Stream { 17 | public: 18 | 19 | ccTalk(Stream *s=&Serial); 20 | 21 | size_t 22 | write(uint8_t c); 23 | int available(); 24 | int read(); 25 | int peek(); 26 | void flush(); 27 | 28 | // RX state machines coding 29 | enum RX_State_ {RXidle,RXloop,RXansw,RXcomplete,RXflush,RXerr_unexpected_byte_in_idle,RXerr_no_loopback,RXerr_wrong_loopback,RXerr_answer_timeout,\ 30 | RXerr_msg_length,RXerr_checksum_failed} RX_state; 31 | 32 | static const char* const RX_msg[]; 33 | //static const char* RX_msg[] = {"RXidle","RXloop","RXansw","RXcomplete","RXflush","RXerr_unexpected_byte_in_idle","RXerr_no_loopback","RXerr_wrong_loopback","RXerr_answer_timeout",\ 34 | "RXerr_msg_length","RXerr_checksum_failed"}; 35 | 36 | unsigned char RX_buffer[64];// the receive buffer 37 | unsigned char TX_buffer[64];// the transmit buffer , not really because is used only to format the message and to compare with loopback 38 | unsigned char RX_bytecount; // used to count the bytes received 39 | 40 | unsigned int coin_value[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // to store the coin value 41 | unsigned int coineventcounter;//used to follow the events from read credit or error codes 42 | unsigned int buffered_events; //how many events are queued 43 | int credit; 44 | 45 | const unsigned char maxDataLength = MAXDATALENGTH; // the maximum data field length 46 | const unsigned long interbytetimeout = 100;// the timeout for next byte in the same message 47 | const unsigned long answertimeout = 300;// the answer timeout , it might be longer for some pools like eeprom writing 48 | 49 | void ccTalkReceive(); //the main RX process to be called in loop 50 | int watchdog_poll(); 51 | // cctalk receive process functions , the main process should be called until RX_state >= RX_idle 52 | void comm_init();// opens the serial port and flush the RX buffer 53 | void device_init(); //resets device, disables inhibits and sets coin values 54 | void diagnostic();// runs initialization sequence 55 | void device_reset(); //just resets device 56 | char * get_master_inhibit(); //get master inhibit status 57 | void master_inhibit_on(); //disable coins 58 | void master_inhibit_off(); //enable coins 59 | char * get_inhibit(); //get individual inhibits 60 | void inhibit_on(); //disable coins (all individual channels) 61 | void inhibit_off(); //enable coins (all individual channels) 62 | int read_credit(); //get credits 63 | void breakrx();// flush the RX buffer - Usable from any RX state 64 | void clearrxerror();// flush the buffer without restarting the timer, usable only from RX error states 65 | 66 | 67 | void startrx();// init the RX process to wait for an answer , use after sending a pool with cctsend, 68 | // the main process should be called until RX_state >= RXcomplete 69 | 70 | 71 | // Send a pool command = cctalk pool byte , see headers.h 72 | // dest = destination field 40 for bill acceptor, 2 for coin acceptor etc 73 | // D00..D07 = data field , you dont need to fill all if the data field is shorter 74 | // if you need longer data field then fill the next bytes in the TX_buffer[12] and higher 75 | void cctsend(unsigned char command,unsigned char dest,unsigned char msglength,\ 76 | unsigned char D00=0,unsigned char D01=0,unsigned char D02=0,unsigned char D03=0, 77 | unsigned char D04=0,unsigned char D05=0,unsigned char D06=0,unsigned char D07=0); 78 | 79 | char * printASCIIdata(); //returns the ASCII data string 80 | 81 | char * printBINdata(); //returns the bin data field as ASCII string 82 | 83 | private: 84 | Stream 85 | *stream; 86 | 87 | char get_data[MAXDATALENGTH]; 88 | int length; 89 | 90 | milistimer comt; 91 | milistimer somedelay;// to handle the break after a comm error 92 | }; 93 | 94 | #endif 95 | -------------------------------------------------------------------------------- /examples/ArduinoccTalk/ArduinoccTalk.ino: -------------------------------------------------------------------------------- 1 | 2 | //ccTalk tutorial coin acceptor host example 3 | //Works with any stream based serial object 4 | //Open a stream and begin, then pass to a ccTalk object 5 | 6 | #include 7 | #include "ccTalk.h" 8 | #include "headers.h" 9 | 10 | NeoSWSerial mySerial(8,9); // RX, TX 11 | ccTalk SCA1(&mySerial); 12 | 13 | int credit; 14 | 15 | void setup() { 16 | Serial.begin(9600); 17 | mySerial.begin(9600); 18 | SCA1.comm_init(); 19 | while ( SCA1.RX_state != ccTalk::RXidle) { 20 | SCA1.ccTalkReceive(); 21 | } 22 | SCA1.device_init(); 23 | //verify inhibits are disabled, should print 255 255 24 | Serial.println("Getting inhibit status"); 25 | Serial.println(SCA1.get_inhibit()); 26 | 27 | //toggle inhibit to test functionality, should print 0 0 28 | Serial.println("Enabling inhibit"); 29 | SCA1.inhibit_on(); 30 | Serial.println("Getting inhibit status"); 31 | Serial.println(SCA1.get_inhibit()); 32 | 33 | SCA1.inhibit_off(); 34 | Serial.println("Ready to accept coins"); 35 | } 36 | 37 | void loop() { 38 | if (credit = SCA1.read_credit()){ 39 | Serial.print("Credit inserted: "); 40 | Serial.println(credit); 41 | } 42 | } -------------------------------------------------------------------------------- /headers.h: -------------------------------------------------------------------------------- 1 | // just the definitions for cctalk headers 2 | #define reset_device 1 3 | #define request_comms_status_variables 2 4 | #define clear_comms_status_variables 3 5 | #define request_comms_revision 4 6 | #define request_service_status 104 7 | #define data_stream 105 8 | #define request_escrow_status 106 9 | #define operate_escrow 107 10 | #define request_encrypted_monetary_id 108 11 | #define request_encrypted_hopper_status 109 12 | #define switch_encryption_key 110 13 | #define request_encryption_support 111 14 | #define read_encrypted_events 112 15 | #define switch_baud_rate 113 16 | #define request_USB id 114 17 | #define request_real_time_clock 115 18 | #define modify_real_time_clock 116 19 | #define request_cashbox_value 117 20 | #define modify_cashbox_value 118 21 | #define request_hopper_balance 119 22 | #define modify_hopper_balance 120 23 | #define purge_hopper 121 24 | #define request_error_status 122 25 | #define request_activity_register 123 26 | #define verify_money_out 124 27 | #define pay_money_out 125 28 | #define clear_money_counter 126 29 | #define request_money_out 127 30 | #define request_money_in 128 31 | #define read_barcode_data 129 32 | #define request_indexed_hopper_dispense_count 130 33 | #define request_hopper_coin_value 131 34 | #define emergency_stop_value 132 35 | #define request_hopper_polling_value 133 36 | #define dispense_hopper_value 134 37 | #define set_accept_limit 135 38 | #define store_encryption_code 136 39 | #define switch_encryption_code 137 40 | #define finish_firmware_upgrade 138 41 | #define begin_firmware_upgrade 139 42 | #define upload_firmware 140 43 | #define request_firmware_upgrade_capability 141 44 | #define finish_bill_table_upgrade 142 45 | #define begin_bill_table_upgrade 143 46 | #define upload_bill_tables 144 47 | #define request_currency_revision 145 48 | #define operate_bidirectional_motors 146 49 | #define perform_stacker_cycle 147 50 | #define read_opto_voltages 148 51 | #define request_individual_error_counter 149 52 | #define request_individual_accept_counter 150 53 | #define test_lamps 151 54 | #define request_bill_operating_mode 152 55 | #define modify_bill_operating_mode 153 56 | #define route_bill 154 57 | #define request_bill_position 155 58 | #define request_country_scaling_factor 156 59 | #define request_bill_id 157 60 | #define modify_bill_id 158 61 | #define read_buffered_bill_events 159 62 | #define request_cipher_key 160 63 | #define pump_rng 161 64 | #define modify_inhibit_and_override_registers 162 65 | #define test_hopper 163 66 | #define enable_hopper 164 67 | #define modify_variable_set 165 68 | #define request_hopper_status 166 69 | #define dispense_hopper_coins 167 70 | #define request_hopper_dispense_count 168 71 | #define request_address_mode 169 72 | #define request_base_year 170 73 | #define request_hopper_coin 171 74 | #define emergency_stop 172 75 | #define request_thermistor_reading 173 76 | #define request_payout_float 174 77 | #define modify_payout_float 175 78 | #define request_alarm_counter 176 79 | #define handheld_function 177 80 | #define request_bank_select 178 81 | #define modify_bank_select 179 82 | #define request_security_setting 180 83 | #define modify_security_setting 181 84 | #define download_calibration_info 182 85 | #define upload_window_data 183 86 | #define request_coin_id 184 87 | #define modify_coin_id 185 88 | #define request_payout_capacity 186 89 | #define modify_payout_capacity 187 90 | #define request_default_sorter_path 188 91 | #define modify_default_sorter_path 189 92 | #define keypad_control 191 93 | #define request_build_code 192 94 | #define request_fraud_counter 193 95 | #define request_reject_counter 194 96 | #define request_last_modification_date 195 97 | #define request_creation_date 196 98 | #define calculate_rom_checksum 197 99 | #define counters_to_eeprom 198 100 | #define configuration_to_eeprom 199 101 | #define acmi_unencrypted_product_id 200 102 | #define request_teach_status 201 103 | #define teach_mode_control 202 104 | #define display_control 203 105 | #define meter_control 204 106 | #define request_payout_absolute_count 207 107 | #define modify_payout_absolute_count 208 108 | #define request_sorter_paths 209 109 | #define modify_sorter_paths 210 110 | #define power_management_control 211 111 | #define request_coin_position 212 112 | #define request_option_flags 213 113 | #define write_data_block 214 114 | #define read_data_block 215 115 | #define request_data_storage_availability 216 116 | #define request_payout_highlow_status 217 117 | #define enter_pin_number 218 118 | #define enter_new_pin_number 219 119 | #define acmi_encrypted_data 220 120 | #define request_sorter_override_status 221 121 | #define modify_sorter_override_status 222 122 | #define modify_encrypted_inhibit_and_override_registers 223 123 | #define request_encrypted_product_id 224 124 | #define request_accept_counter 225 125 | #define request_insertion_counter 226 126 | #define request_master_inhibit_status 227 127 | #define modify_master_inhibit_status 228 128 | #define read_buffered_credit_or_error_codes 229 129 | #define request_inhibit_status 230 130 | #define modify_inhibit_status 231 131 | #define perform_self_check 232 132 | #define latch_output_lines 233 133 | #define send_dh_public_key 234 134 | #define read_dh_public_key 235 135 | #define read_opto_states 236 136 | #define read_input_lines 237 137 | #define test_output_lines 238 138 | #define operate_motors 239 139 | #define test_solenoids 240 140 | #define request_software_revision 241 141 | #define request_serial_number 242 142 | #define request_database_version 243 143 | #define request_product_code 244 144 | #define request_equipment_category_id 245 145 | #define request_manufacturer_id 246 146 | #define request_variable_set 247 147 | #define request_status 248 148 | #define request_polling_priority 249 149 | #define address_random 250 150 | #define address_change 251 151 | #define address_clash 252 152 | #define address_poll 253 153 | #define simple_poll 254 154 | #define factory_setup_and_test 255 155 | 156 | -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=cctcom 2 | version=1.0.0 3 | author=Ben Olayinka 4 | maintainer=Ben Olayinka 5 | sentence=Arduino Library for CCTalk using SoftwareSerial 6 | paragraph=Arduino Library for CCTalk using SoftwareSerial 7 | category=Device Control 8 | url= 9 | architectures=* 10 | --------------------------------------------------------------------------------