Advertisement
Guest User

Untitled

a guest
Jan 31st, 2017
111
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.12 KB | None | 0 0
  1. /*
  2. espRFIDRelaycontroller by Duncan McPherson
  3.  
  4. Use a RFID-RC522 and ESP8266-12e to control a relay to activate
  5. a machine for authorised users. Pick up the list of authorised users from an MQTT server.
  6.  
  7. */
  8.  
  9. #include <EEPROM.h> // To read and write PICC's UIDs from/to EEPROM
  10. #include <SPI.h> // RC522 Module uses SPI protocol
  11. #include <MFRC522.h> // Library for Mifare RC522 Device
  12. #include <ESP8266WiFi.h> // To use WiFi to communicate with the mothership
  13. #include <IPStack.h>
  14. #include <Countdown.h>
  15. #include <MQTTClient.h> // Library for MQTT publishing and subscribing to get the authorised users from the mothership
  16. #include <ArduinoJson.h> // To parse the incoming messages
  17.  
  18.  
  19. const uint8_t relayPin = 16; // Nominate a pin to control the relay
  20.  
  21.  
  22. // ************* Stuff for reading cards with MFRC522 *******************
  23. boolean successfulRead = false; // Whether or not a card has been read
  24. byte presentedCard[4]; // The UID of the card just presented
  25. const uint8_t ss_pin = 4; // Nominate a pin to slave select the MFRC522
  26. const uint8_t rst_pin = 5; // Nominate a pin to reset the MFRC522
  27. MFRC522 mfrc522(ss_pin, rst_pin); // define the MFRC522
  28.  
  29. // ************* Stuff for seting up WiFi ******************************
  30. const char* ssid = "mcphersons";
  31. const char* password = "ericthered";
  32. WiFiClient wiFiClient;
  33.  
  34.  
  35. // ************* Stuff for setting up MQTT client subscriptions ********
  36. char* mqttBroker = "192.168.0.2";
  37. int port = 1883;
  38. char* clientID = "GeorgeLathenby";
  39. char* user = "duncandoo_lathe";
  40. char* pw = ".........";
  41. char* topic = "confidential/somakeit/space/tags/#";
  42. int arrivedCount = 0;
  43.  
  44. IPStack ipstack(wiFiClient);
  45. MQTT::Client<IPStack, Countdown, 50, 1> client = MQTT::Client<IPStack, Countdown, 50, 1>(ipstack);
  46. MQTT::Message message;
  47.  
  48. char* topicTag = "confidential/somakeit/space/tags/ffffffff"; // example of MQTT topic we need
  49.  
  50.  
  51. // ************* Stuff for JSON parsing *****************************
  52. StaticJsonBuffer<128> jsonBuffer;
  53. char* json = "{\"member_id\": \"007\",\"member_name\":\"George Lathenby\",\"roles\":[1,3,9,11]}";
  54.  
  55. void setup() {
  56. //pinMode(LED_BUILTIN, OUTPUT); // intialize the builtin led pin which
  57. // will be used to denote activation and Rx.
  58. pinMode(relayPin, OUTPUT); // Initialize the relayPin
  59. digitalWrite(relayPin, LOW); // Make sure the relay is off at the start
  60. Serial.begin(115200); // start a serial port
  61. SPI.begin(); // start SPI bus
  62. mfrc522.PCD_Init(); // start the MFRC522
  63. EEPROM.begin(512); // start the EEPROM and define it's size
  64.  
  65.  
  66. //run once to set the initial storedCard for testing then wipe it
  67.  
  68. // // byte storedCard[4] = { 0x29, 0x80, 0xc, 0x3b };
  69. // EEPROM.write( 0, 1 );
  70. // for ( byte i = 0 ; i < 4 ; i++ ) {
  71. // EEPROM.write( i+1 , storedCard[i] );
  72. // }
  73. // EEPROM.commit();
  74.  
  75. }
  76.  
  77.  
  78. void loop() {
  79. Serial.print("Present your card to be assessed.");
  80.  
  81. do {
  82. successfulRead = getID(); // Check if a card has been read successfully
  83. }
  84. while (!successfulRead); // go no further until a card is read successfully
  85.  
  86. if (checkID(presentedCard)) {
  87. digitalWrite(relayPin, HIGH); // Turn the relay on
  88. boolean relayState = digitalRead(relayPin);
  89. Serial.printf("You may use the lathe. The relay should be on and it is %u.\n", relayState);
  90.  
  91. //Check for new users
  92. connectWiFi();
  93. connectMQTT();
  94.  
  95. while (true) {
  96. //leave the relay on or some other stuff that might happen, like a time limit
  97. Serial.println("Waiting for message");
  98. client.yield(1000);
  99.  
  100. addNewUsers( checkMessage( topicTag , json ) );
  101. //digitalWrite(relayPin, LOW);
  102. }
  103. }
  104. else {
  105. //keep the relay off
  106. digitalWrite(relayPin, LOW); // Just to make sure
  107. boolean relayState = digitalRead(relayPin);
  108. Serial.printf("You are not authorised. Extermination will now commence. The relay should be off and it is %u.\n", relayState);
  109. Serial.println("If you think you really should be able to use the lathe present your card again and I'll check with the mothership...");
  110.  
  111. //Double check for new users
  112. connectWiFi();
  113. connectMQTT();
  114.  
  115. char buf[100];
  116. strcpy(buf, "Hello World! QoS 0 message");
  117. message.qos = MQTT::QOS0;
  118. message.retained = false;
  119. message.dup = false;
  120. message.payload = (void*)buf;
  121. message.payloadlen = strlen(buf)+1;
  122. int rc = client.publish(topicTag, message);
  123. client.yield(5000);
  124.  
  125. addNewUsers( checkMessage( topicTag , json ) );
  126.  
  127. //It would be nice to put a bit here to allow a different card to interrupt the connecting to WiFi and MQTT, to run in parallel
  128. }
  129. }
  130.  
  131.  
  132. // Function to check for card being read //
  133. boolean getID() {
  134. if ( ! mfrc522.PICC_IsNewCardPresent()) {
  135. delay(500); // Look for a card being presented every 500ms until one is found
  136. return false;
  137. }
  138.  
  139. if ( ! mfrc522.PICC_ReadCardSerial()) {
  140. // Check the card that has been found has been read
  141. return false;
  142. }
  143.  
  144. Serial.print("Card UID: ");
  145. for (byte i = 0; i < 4; i++) {
  146. presentedCard[i] = mfrc522.uid.uidByte[i]; // Print the UID to serial as hex values
  147. Serial.print(presentedCard[i], HEX);
  148. }
  149. Serial.println();
  150. mfrc522.PICC_HaltA(); // Stop reading the card and tell it to switch off
  151. return true;
  152. }
  153.  
  154.  
  155. // function to check a card against list stored in EEPROM
  156. boolean checkID( byte testCard[] ) {
  157. byte users = EEPROM.read(0); //EEPROM[0] stores the number of authorised cards that need to be checked against
  158. byte storedCard[4]; // The UID of a card read from memory
  159.  
  160. for ( byte user = 0 ; user < users ; user++) {
  161. for ( byte i = 0 ; i < 4 ; i++) {
  162. storedCard[i] = EEPROM.read( user * 4 + 1 + i ); //each UID is 4 bytes long and takes up 4 slots in EEPROM
  163. }
  164.  
  165. boolean match = true; // assume there is a match
  166. for ( byte i = 0; i < 4; i++ ) {
  167. if ( testCard[i] != storedCard[i]) {
  168. match = false; // if any byte doesn't match fail
  169. }
  170. }
  171. if (match) {
  172. Serial.print("Welcome user number ");
  173. Serial.println(user, DEC);
  174. return true;
  175. }
  176. else {
  177. return false;
  178. }
  179. }
  180. }
  181.  
  182.  
  183. //function to connect to Wifi
  184. void connectWiFi() {
  185. delay(10);
  186. Serial.print("Connecting to ");
  187. Serial.println(ssid);
  188.  
  189. WiFi.begin(ssid, password);
  190.  
  191. while (WiFi.status() != WL_CONNECTED) {
  192. delay(500);
  193. Serial.print(".");
  194. }
  195. Serial.println("");
  196. Serial.print("WiFi connected to IP address ");
  197. Serial.println(WiFi.localIP());
  198. }
  199.  
  200. //function to connect to MQTT server
  201. void connectMQTT() {
  202.  
  203. Serial.print("Connecting to ");
  204. Serial.print(mqttBroker);
  205. Serial.print(":");
  206. Serial.println(port);
  207.  
  208. int rc = ipstack.connect(mqttBroker, port);
  209. if (rc != 1)
  210. {
  211. Serial.print("rc from TCP connect is ");
  212. Serial.println(rc);
  213. }
  214.  
  215. Serial.println("MQTT connecting");
  216. MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
  217. data.MQTTVersion = 3;
  218. data.clientID.cstring = clientID;
  219. data.username.cstring = user;
  220. data.password.cstring = pw;
  221. rc = client.connect(data);
  222. if (rc != 0)
  223. {
  224. Serial.print("rc from MQTT connect is ");
  225. Serial.println(rc);
  226. }
  227. Serial.println("MQTT connected");
  228.  
  229. rc = client.subscribe(topic, MQTT::QOS1, messageArrived);
  230. if (rc != 0)
  231. {
  232. Serial.print("rc from MQTT subscribe is ");
  233. Serial.println(rc);
  234. }
  235. Serial.print("MQTT subscribed to topic: ");
  236. Serial.println(topic);
  237. }
  238.  
  239.  
  240. // function to handle callbacks from MQTT broker
  241. void messageArrived(MQTT::MessageData& md) {
  242. MQTT::Message &message = md.message;
  243. char* topic = md.topicName.cstring;
  244.  
  245. Serial.print("Message ");
  246. Serial.print(++arrivedCount);
  247. Serial.print(" arrived: qos ");
  248. Serial.print(message.qos);
  249. Serial.print(", retained ");
  250. Serial.print(message.retained);
  251. Serial.print(", dup ");
  252. Serial.print(message.dup);
  253. Serial.print(", packetid ");
  254. Serial.println(message.id);
  255. Serial.print("Topic ");
  256. Serial.println(topic);
  257. Serial.print("Payload ");
  258. Serial.println((char*)message.payload);
  259.  
  260. json = (char*)message.payload;
  261. topicTag = (char*)topic;
  262.  
  263. }
  264.  
  265.  
  266. // function to check if message contains a new authorised user
  267. byte* checkMessage(char *topicTag , char *json ) {
  268. JsonObject &root = jsonBuffer.parseObject(json);
  269. byte len1 = sizeof(root["roles"]) / sizeof(root["roles"][0]);
  270. int roles[len1];
  271. for ( byte i = 0 ; i < len1 ; i++ ) {
  272. roles[i] = root["roles"][i];
  273. }
  274.  
  275. byte len2 = sizeof(roles) / sizeof(roles[0]);
  276. byte newUser[4] = { 0xff, 0xff, 0xff, 0xff };
  277.  
  278. for ( byte i ; i < len2 ; i++ ) {
  279. if ( roles[i] == 11 ) { // check if the list of roles includes 11, which is lathe user
  280. char *UID = &topicTag[strlen(topicTag)-8];
  281. for ( byte i = 0 ; i < 4 ; i++ ) {
  282. newUser[i] = UID[i];
  283. }
  284. }
  285. }
  286.  
  287.  
  288. return newUser;
  289. }
  290.  
  291. // function to write new authorised cardNumber into EEPROM
  292. void addNewUsers(byte newUser[]) {
  293. byte users = EEPROM.read(0); //EEPROM[0] stores the number of authorised cards that need to be checked against
  294. byte storedCard[4]; // The UID of a card read from memory
  295.  
  296. for ( byte user = 0 ; user < users ; user++) { // Check if the newUser is already in EEPROM by comparing against every user
  297. for ( byte i = 0 ; i < 4 ; i++) {
  298. storedCard[i] = EEPROM.read( user * 4 + 1 + i ); //each UID is 4 bytes long and takes up 4 slots in EEPROM
  299. }
  300.  
  301. boolean match = true; // assume there is a match
  302. for ( byte i = 0; i < 4; i++ ) {
  303. if ( newUser[i] != storedCard[i]) {
  304. match = false; // if any byte doesn't match fail
  305. }
  306. }
  307. if (match) {
  308. Serial.print("User is already authorised and is number ");
  309. Serial.println(user, DEC);
  310. }
  311. else {
  312. users += users; // increment the number of users
  313. EEPROM.write(0, users);
  314. for ( byte i = 0 ; i < 4 ; i++ ) {
  315. EEPROM.write( users * 4 + 1 + i , newUser[i] );
  316. }
  317. EEPROM.commit();
  318. }
  319. }
  320.  
  321. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement