По просьбам выкладываю весь исходный код автомойки на arduino.
Описание см. Arduino на автомойке и Arduino на автомойке ч.2.
UPD:
Под катом только исходный код. Предназначен только для тех, кому интересно общение arduino и купюроприёмника типа CashCode по протоколу CCNet. Прочим прошу не тратить своё время зря.
Описание см. Arduino на автомойке и Arduino на автомойке ч.2.
UPD:
Под катом только исходный код. Предназначен только для тех, кому интересно общение arduino и купюроприёмника типа CashCode по протоколу CCNet. Прочим прошу не тратить своё время зря.
#include <SPI.h>
#include <Ethernet.h>
#include <SoftwareSerial.h>
//#include <MFRC522.h>
#include <EEPROM.h>
#include <string.h>
//#include <avr/wdt.h>
//#include "ICMPPing.h"
#define POLYNOMIAL 0x08408
uint8_t reset[] = {0x02, 0x03, 0x06, 0x30, 0x41, 0xB3};
uint8_t ack[] = {0x02, 0x03, 0x06, 0x00, 0x0C2, 0x82};
uint8_t poll[] = {0x02, 0x03, 0x06, 0x33, 0xDA, 0x81};
uint8_t enable[]={0x02, 0x03, 0x0C, 0x34, 0, 0, 0x7C, 0, 0, 0, 0x66, 0xC1};
/*
uint8_t stack[] = {0x02, 0x03, 0x06, 0x35, 0xEC, 0xE4};
uint8_t sec[] = {0x02, 0x03, 0x09, 0x32, 0x00, 0x00, 0x00, 0x26, 0x1F};
uint8_t GetSt[]={0x02, 0x03, 0x06, 0x31, 0xC8, 0xA2};
uint8_t Ident[]={0x02, 0x03, 0x06, 0x37, 0xFE, 0xC7};
uint8_t GetBT[]={0x02, 0x03, 0x06, 0x41, 0x4F, 0xD1};
uint8_t Return[]={0x02, 0x03, 0x06, 0x36, 0x77, 0xD6};
uint8_t Hold[]={0x02, 0x03, 0x06, 0x38, 0x09, 0x3F};
uint8_t ExtBD[]={0x02, 0x03, 0x06, 0x3A, 0x1B, 0x1C};
uint8_t ReqSt[]={0x02, 0x03, 0x06, 0x60, 0xC4, 0xE1};
uint8_t DiBT[]={0x02, 0x03, 0x0C, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x0C};*/
#define max7219_reg_decodeMode 0x09
#define max7219_reg_intensity 0x0a
#define max7219_reg_scanLimit 0x0b
#define max7219_reg_shutdown 0x0c
#define max7219_reg_displayTest 0x0f
const unsigned char alf[] = {0,
28, 34, 34, 34, 34, 34, 34, 28, // 0
8, 24, 8, 8, 8, 8, 8, 28,// 1
28, 34, 2, 4, 8, 16, 32, 62, // 2
28, 34, 2, 4, 2, 2, 34, 28, //3
34, 34, 34, 34, 62, 2, 2, 2,
62, 32, 32, 60, 2, 2, 2, 60,
28, 32, 32, 60, 34, 34, 34, 28,
62, 2, 2, 4, 8, 16, 32, 32,
28, 34, 34, 28, 34, 34, 34, 28,
28, 34, 34, 30, 2, 2, 2, 28
};
#define DIN 16
#define CS 17
#define CLK 18
//#define RST_PIN 8
//#define SS_PIN 9
//MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance MISO 12, MOSI 11, SCK 13
//byte admin_key[][4] = { { 0x99, 0x3C, 0x16, 0xDB }, { 0x16, 0x95, 0x59, 0x7B }, { 0x46, 0x93, 0xF1, 0x74 }, { 0x03, 0x1F, 0x17, 0xDB }};
void(* resetFunc) (void) = 0;
SoftwareSerial mySerial(14, 15); // RX, TX
byte system100[]={92, 53, 96, 34};
//IPAddress pingAddr(192,168,1,1); // публичный DNS
//SOCKET pingSocket = 0;
//int timePing = 0;
//int pingFAIL = 0; // счётчик фейлов
//ICMPPing ping(pingSocket, (uint16_t)random(0, 255));
//EthernetClient client;
EthernetServer server(80);
char SAM; //номер ящика
unsigned long timeCount=0;
bool waitACK=0;
char count=0;
char LNG=6;
uint8_t c;
uint8_t z1=0;
uint8_t z2=0;
uint8_t old=1;
char rele=0;
char rOld=0;
bool keydown=0;
unsigned long timeAllRele=1000;
unsigned long timeRele=0;
unsigned long lightOff=0;
unsigned long sendPoll=0;
char posPay; //позиция кеша
char posErr; //позиция ошибок
char clientline[100];
unsigned long resetTime;
void setup()
{
//wdt_enable(WDTO_8S);
//delay(2000);
//if(EEPROM.read(30)==1) { EEPROM.write(30, 0); resetFunc(); }
//EEPROM.write(30, 1);
pinMode(DIN,OUTPUT); pinMode(CS,OUTPUT); pinMode(CLK,OUTPUT); digitalWrite(CS, HIGH);
initLed();
pinMode(2, OUTPUT); pinMode(3, OUTPUT); pinMode(4, OUTPUT); pinMode(5, OUTPUT); pinMode(6, OUTPUT); pinMode(7, OUTPUT); digitalWrite(7, HIGH); //свет
pinMode (A5, INPUT); //кнопки
if(EEPROM.read(10)==255 && EEPROM.read(11)==255) { EEPROM.write(10, 0); EEPROM.write(11, 0); } //бабки на табло младший байт первый
posPay=EEPROM.read(99);
if(posPay<0 || posPay>99) { EEPROM.write(99, 0); posPay=0; }
posErr=EEPROM.read(199);
if(posErr<0 || posErr>99) { EEPROM.write(199, 0); posErr=0; }
SAM=EEPROM.read(0);
Serial.begin(9600);
Serial.print(SAM, DEC); Serial.print(" "); Serial.print(posPay, DEC); Serial.print(" "); Serial.print(posErr, DEC);Serial.println(" begin");
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED-SAM };
//byte gate[]={192, 168, 1, 1};
//byte mask[]={255,255,255,0};
IPAddress ip(192, 168, 1, 100+SAM);
Ethernet.begin(mac, ip);//, gate, gate, mask
server.begin();
delay(200);
Serial.print("server is at ");
Serial.println(Ethernet.localIP());
mySerial.begin(9600);
delay(200);
rOld=EEPROM.read(9);
if(rOld<0 || rOld>8) EEPROM.write(9, 0); //сохранение функции
else setRele(rOld);
resetTime=millis();
// mfrc522.PCD_Init();// Init MFRC522
}
void loop()
{
//if(millis()-resetTime>600000) resetFunc(); //перезагрузка через 10 минут
if(millis()-sendPoll>200) { sendCCNET(poll);} // посыл пула //wdt_reset();сброс вотчдога и
/*if (Serial.available()) {
char s=Serial.read(); //int pay=Serial.parseInt();
if(s=='0') { Serial.print("RESET"); sendCCNET(reset); waitACK=1; count=0; }
if(s=='1') { printNumber(100); EEPROM.write(100+posPay, 4); posPay++; EEPROM.write(99, posPay); }
if(s=='3') { sendInfo(); }
}
if(millis()-timePing>10000)
{
timePing=millis();
ICMPEchoReply echoReply = ping(pingAddr, 2);
if (echoReply.status == SUCCESS) pingFAIL=0; else { Serial.println("pingFAIL"); if(++pingFAIL>3) resetFunc(); }
//initLed();
}*/
int key = analogRead (5);
//Serial.println(key);
if(keydown && key<20) keydown=0;
if(key>300 && key<315 && !keydown) setRele(6); //ключ
if(key>330 && key<400 && !keydown) setRele(0);//стоп
if(!keydown && rele==0 && (EEPROM.read(10)>0 || EEPROM.read(11)>0))
{
if(key>920 && key<980) setRele(1);
if(key>810 && key<870) setRele(2);
if(key>720 && key<780) setRele(3);
if(key>600 && key<640) setRele(4);
if(key>420 && key<480) setRele(5);
}
if(rele>0 && rele<=5 && (millis()-timeRele)>timeAllRele) { if(printNumber(-1)==0) setRele(0); timeRele+=timeAllRele; }
if(lightOff>0 && (millis()-lightOff)>10000) { digitalWrite(7, HIGH); lightOff=0; } //свет
for (int sock = 0; sock < MAX_SOCK_NUM; sock++) {
EthernetClient sclient = server.available_(sock);
if (sclient) myserver(sclient);
//serverWorks2(sclient);
}
delay(30);
// Look for new cards
// if ( mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial()) dump_byte_array(mfrc522.uid.uidByte, mfrc522.uid.size);
}
void sendCCNET(uint8_t *com)
{
for(char i=0; i<com[2]; i++) mySerial.write(com[i]);
if(com[3]!=0) { waitACK=1; count=0; sendPoll=millis(); }
while(waitACK)
{
if(millis()-sendPoll>300) waitACK=0; // макс. время приема ответа
if(mySerial.available()) {
c=mySerial.read();
if(count==2) LNG=c;
if(count==3) z1=c;
if(count==4) z2=c;
count++;
}
if(count<LNG) continue;
waitACK=0;
if(z1>0 && z1<255) sendCCNET(ack);
if(z1==0x10 || z1==0x11 || z1==0x12) { sendCCNET(reset); } //Serial.print("POWER UP RESET ");
if(z1==0x19) { sendCCNET(enable); } //Serial.print("DISABLED ENABLE ");
if(z1==70) { sendCCNET(reset); } //Serial.print("PAUSE RESET ");
if(old!=z1)
{
/*Serial.print(z1, HEX); Serial.print(" "); Serial.println(z2, HEX);
if(z1==0x14) Serial.println("IDLING");
if(z1==0x00) Serial.println("ACK"); if(z1==0xFF) Serial.println("NAK");
if(z1==0x13) Serial.println("INIT"); if(z1==0x15) Serial.println("ACCEPTING");
if(z1==0x17) Serial.println("STACKING"); if(z1==0x30) Serial.println("INVALID COMMAND");
if(z1==0x41) Serial.println("DROP CASSETTE FULL");
if(z1==0x44) Serial.println("JAM IN STACKER"); if(z1==0x42) Serial.println("DROP CASSETTE REMOVED");
if(z1==0x47) { Serial.print("Generic Failure codes "); Serial.println(z2, HEX); sendInfo("err", String(z2)); }
if(z1==0x1C) { Serial.print("Generic rejecting code "); Serial.println(z2, HEX); sendInfo("err", String(z2)); } */
if(z1>0x20 && z1<0x81 && posErr<100) { EEPROM.write(200+posErr, z1==0x47 || z1==0x1C ? z2 : z1); posErr++; EEPROM.write(199, posErr); } // sendInfo("err", String(z1));
}
old=z1;
if(z1==0x81) { Serial.print("PACKED, STACKED."); Serial.println(z2); int pay=0;
if(z2==2) pay=10; if(z2==3) pay=50; if(z2==4) pay=100; if(z2==5) pay=500; if(z2==6) pay=1000; if(z2==7) pay=5000;
if(pay>0) { printNumber(pay); if(posPay<100) { EEPROM.write(100+posPay, z2); posPay++; EEPROM.write(99, posPay);}
z2=0; }
}
}
}
void setRele(char r)
{
if(r && r!=rOld) { rOld=r; delay(30); return; } //дребезг
rele=r;
keydown=1;
for(char i=1;i<6;i++) digitalWrite(i+1, HIGH);
if(r==6) r=1; //ключ
if(r) { digitalWrite(r+1, LOW); timeRele=millis(); timeAllRele=60000/EEPROM.read(r); }
EEPROM.write(9, r);
delay(20);
initLed();
if(r==0 && (posPay>5 || posErr>5)) sendInfo();
}
void setCommand(byte command, byte value)
{
digitalWrite(CS, LOW);
for (int i=0; i<4; i++) { shiftOut(DIN,CLK, MSBFIRST, command); shiftOut(DIN,CLK, MSBFIRST, value); }
digitalWrite(CS, HIGH);
}
void initLed()
{
setCommand(max7219_reg_scanLimit, 0x07);
setCommand(max7219_reg_decodeMode, 0x00); // using an led matrix (not digits)
setCommand(max7219_reg_shutdown, 0x01); // not in shutdown mode
setCommand(max7219_reg_displayTest, 0x00); // no display test
setCommand(max7219_reg_intensity, 1);
int n=printNumber(0);
}
int printNumber(int add)
{
int n=EEPROM.read(10)+EEPROM.read(11)*256;
if(add!=0) { n+=add; EEPROM.write(10, n%256); EEPROM.write(11, n>>8); }
int k;
for (char i=1; i<=8; i++)
{
digitalWrite(CS, LOW);
for (char j=3; j>=0; j--) { k=n/pow(10,j); shiftOut(DIN,CLK, MSBFIRST,i); shiftOut(DIN,CLK, MSBFIRST,alf[i+(k%10)*8]); }
digitalWrite(CS, HIGH);
}
if(n>0) { digitalWrite(7, LOW); lightOff=0; } else lightOff=millis(); //свет
return n;
}
void myserver(EthernetClient client)
{
//EthernetClient client = server.available();
int index = 0;
Serial.println("new client");
while (client.available()) {
char c = client.read();
if(index<99) clientline[index] = c;
index++;
//Serial.print(c);
}
//Serial.println(clientline);
char *t;
t=strstr(clientline, "timer");
if (t!=NULL) { t+=5; char timer=*t; t+=2; int value=(*t-48)*10; t++; value+=*t-48; EEPROM.write(timer-48, value);
Serial.print("timer "); Serial.print(timer); Serial.print(" value "); Serial.println(value, DEC);
}
t=strstr(clientline, "pay");
if (t!=NULL) { t+=4; int value=(*t-48)*100; t++; value+=(*t-48)*10; t++; value+=*t-48; printNumber(value);
Serial.print("pay is "); Serial.println(value, DEC);
}
if(strstr(clientline, "reset")!=NULL) resetFunc(); //перезагрузка setup(); //
if(strstr(clientline, "water")!=NULL) digitalWrite(2, LOW); //вода
if(strstr(clientline, "pena")!=NULL) digitalWrite(3, LOW); //пена
if(strstr(clientline, "vosk")!=NULL) digitalWrite(4, LOW); //воск
t=strstr(clientline, "box"); if(t!=NULL) { t+=4; EEPROM.write(0, *t-48); } // setup(); resetFunc(); } //изменение номера бокса
client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html"); client.println("Connection: close"); client.println();
client.println("<!DOCTYPE HTML>"); client.println("<html>");
client.print("box is "); client.print(EEPROM.read(0)); client.println("<br />");
client.print("cashcode is "); client.print(z1, HEX); client.println("<br />");
for (int j = 1; j < 6; j++) {
client.print("timer "); client.print(j); client.print(" is "); client.print(EEPROM.read(j)); client.println("<br />");
}
client.println("</html>");
delay(100);
// close the connection:
client.stop();
}
char sendInfo()
{
//if(!posErr && !posPay) return 0;
EthernetClient client;
char j;
String out="sam="+String(EEPROM.read(0))+"&pka="+String(EEPROM.read(13)); //pka
if(posPay)
{
out+="&pays=";
for(j=0; j<posPay; j++) { out+=String(EEPROM.read(100+j))+"-"; }
}
if(posErr)
{
out+="&errs=";
for(j=0; j<posErr; j++) { out+=String(EEPROM.read(200+j))+"-"; }
}
if (client.connect(system100, 80) || client.connect(system100, 80) || client.connect("www.host.ru", 80))
{
Serial.println("GET /control/sinh/get_money.php?"+out+" HTTP/1.1");
client.println("GET /control/sinh/get_money.php?"+out+" HTTP/1.1");
client.println("Host: www.host.ru");
client.println("Connection: keep-alive");
client.println();
} else { Serial.println("connection failed"); return 0; }
delay(100);
char chr13=0;
bool ok=0;
char c;
while (client.available())
{
c=client.read();
Serial.print(c);
if(chr13==2 && c=='o') ok=1; else if(c==13) chr13++; else if(c!=10) chr13=0;
}
client.stop();
//if(!ok) return (0);
posPay=0; EEPROM.write(99, posPay);
posErr=0; EEPROM.write(199, posErr);
return (1);
}