Access Control Using RFID MIFARE CARD

Dependencies:   MFRC522 NextionLCD

Files at this revision

API Documentation at this revision

Comitter:
shivanandgowdakr
Date:
Tue Aug 21 11:18:56 2018 +0000
Commit message:
Access Control Using MIFARE RFID Card, and with details displayed on Nextion LCD;

Changed in this revision

.gitignore Show annotated file Show diff for this revision Revisions of this file
Card.cpp Show annotated file Show diff for this revision Revisions of this file
Card.h Show annotated file Show diff for this revision Revisions of this file
MFRC522.lib Show annotated file Show diff for this revision Revisions of this file
NextionLCD.lib Show annotated file Show diff for this revision Revisions of this file
README.md Show annotated file Show diff for this revision Revisions of this file
Time.cpp Show annotated file Show diff for this revision Revisions of this file
Time.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed-os.lib Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r a5d3db2f2625 .gitignore
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.gitignore	Tue Aug 21 11:18:56 2018 +0000
@@ -0,0 +1,4 @@
+.build
+.mbed
+projectfiles
+*.py*
diff -r 000000000000 -r a5d3db2f2625 Card.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Card.cpp	Tue Aug 21 11:18:56 2018 +0000
@@ -0,0 +1,80 @@
+
+#include "MFRC522.h"
+#include "Card.h"
+
+#define     MIFARE_MOSI                 PA_7
+#define     MIFARE_MISO                 PA_6
+#define     MIFARE_SCLK                 PA_5
+#define     MIFARE_CS                   PA_4
+#define     MIFARE_RESET                PB_4
+
+MFRC522    mfrc522(MIFARE_MOSI,MIFARE_MISO,MIFARE_SCLK,MIFARE_CS,MIFARE_RESET);
+//MFRC522    mfrc522 (PA_7, PA_6, PA_5, PD_14, PD_15);
+
+bool New_Card=false,Read_Card=false;
+
+extern char  CARD_UID= {'\0'};
+MFRC522::MIFARE_Key key;
+void MIFARE_Init(void)
+
+{
+    mfrc522.PCD_Init();
+
+}
+
+
+
+void Read_Card_Details(char *CARD_UID)
+{
+    memset(CARD_UID,'\0',9);
+    for (uint8_t i = 0; i < 6; i++)
+        key.keyByte[i] = 0xFF;
+  
+    // Look for new cards
+    
+    if (  mfrc522.PICC_IsNewCardPresent()) {
+         wait_ms(50);
+            New_Card=true;
+    }
+    
+    // Select one of the cards
+    
+    if (  mfrc522.PICC_ReadCardSerial()) {
+       
+         wait_ms(50);
+        Read_Card=true;
+    }
+
+   
+    if(Read_Card==true && New_Card==true) {
+        char str1[3],str2[3],str3[3],str4[3];
+        getHexa(mfrc522.uid.uidByte[0], str1);
+        getHexa(mfrc522.uid.uidByte[1], str2);
+        getHexa(mfrc522.uid.uidByte[2], str3);
+        getHexa(mfrc522.uid.uidByte[3], str4);
+        CARD_UID[0]=str4[0];
+        CARD_UID[1]=str4[1];
+        CARD_UID[2]=str3[0];
+        CARD_UID[3]=str3[1];
+        CARD_UID[4]=str2[0];
+        CARD_UID[5]=str2[1];
+        CARD_UID[6]=str1[0];
+        CARD_UID[7]=str1[1];
+        CARD_UID[8]='\0';
+        printf("CARD_UID :   %s\r\n",CARD_UID);
+        Read_Card=false;
+        New_Card=false;
+    }
+}
+
+void getHexa(char checkSum, char *str)
+{
+    char strtemp[3];
+
+    memset(strtemp, 0x00, sizeof(strtemp));
+    sprintf(strtemp, "%02X", checkSum);
+    memcpy(str, strtemp, 2);
+
+    return;
+}
+
diff -r 000000000000 -r a5d3db2f2625 Card.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Card.h	Tue Aug 21 11:18:56 2018 +0000
@@ -0,0 +1,15 @@
+
+#ifndef MBED_CARD_H
+#define MBED_CARD_H
+#include "mbed.h"
+
+
+void MIFARE_Init(void);
+void Read_Card_Details(char *CARD_UID);
+void getHexa(char checkSum, char *str);
+
+
+
+
+
+#endif
\ No newline at end of file
diff -r 000000000000 -r a5d3db2f2625 MFRC522.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MFRC522.lib	Tue Aug 21 11:18:56 2018 +0000
@@ -0,0 +1,1 @@
+https://os.mbed.com/users/shivanandgowdakr/code/MFRC522/#0ee2c6d9ee0d
diff -r 000000000000 -r a5d3db2f2625 NextionLCD.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/NextionLCD.lib	Tue Aug 21 11:18:56 2018 +0000
@@ -0,0 +1,1 @@
+http://os.mbed.com/users/grantphillips/code/NextionLCD/#72f3dadfab71
diff -r 000000000000 -r a5d3db2f2625 README.md
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/README.md	Tue Aug 21 11:18:56 2018 +0000
@@ -0,0 +1,57 @@
+# Getting started with Blinky on mbed OS
+
+This guide reviews the steps required to get Blinky working on an mbed OS platform.
+
+Please install [mbed CLI](https://github.com/ARMmbed/mbed-cli#installing-mbed-cli).
+
+## Import the example application
+
+From the command-line, import the example:
+
+```
+mbed import mbed-os-example-blinky
+cd mbed-os-example-blinky
+```
+
+### Now compile
+
+Invoke `mbed compile`, and specify the name of your platform and your favorite toolchain (`GCC_ARM`, `ARM`, `IAR`). For example, for the ARM Compiler 5:
+
+```
+mbed compile -m K64F -t ARM
+```
+
+Your PC may take a few minutes to compile your code. At the end, you see the following result:
+
+```
+[snip]
++----------------------------+-------+-------+------+
+| Module                     | .text | .data | .bss |
++----------------------------+-------+-------+------+
+| Misc                       | 13939 |    24 | 1372 |
+| core/hal                   | 16993 |    96 |  296 |
+| core/rtos                  |  7384 |    92 | 4204 |
+| features/FEATURE_IPV4      |    80 |     0 |  176 |
+| frameworks/greentea-client |  1830 |    60 |   44 |
+| frameworks/utest           |  2392 |   512 |  292 |
+| Subtotals                  | 42618 |   784 | 6384 |
++----------------------------+-------+-------+------+
+Allocated Heap: unknown
+Allocated Stack: unknown
+Total Static RAM memory (data + bss): 7168 bytes
+Total RAM memory (data + bss + heap + stack): 7168 bytes
+Total Flash memory (text + data + misc): 43402 bytes
+Image: .\.build\K64F\ARM\mbed-os-example-blinky.bin
+```
+
+### Program your board
+
+1. Connect your mbed device to the computer over USB.
+1. Copy the binary file to the mbed device.
+1. Press the reset button to start the program.
+
+The LED on your platform turns on and off.
+
+## Troubleshooting
+
+If you have problems, you can review the [documentation](https://os.mbed.com/docs/latest/tutorials/debugging.html) for suggestions on what could be wrong and how to fix it.
diff -r 000000000000 -r a5d3db2f2625 Time.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Time.cpp	Tue Aug 21 11:18:56 2018 +0000
@@ -0,0 +1,190 @@
+#include "mbed.h"
+#include "Time.h"
+#include <string>
+
+
+
+
+
+int Date_Time_Setting(struct tm curt,char *str)
+{
+    int len=0;
+    len= strlen(str);
+   // printf("len = %d",len);
+    if(len < 14)
+        return 0;
+
+    curt.tm_mday = ( str[0]-0x30)*10+(str[1]-0x30);
+    curt.tm_mon  = ( str[2]-0x30)*10+(str[3]-0x30) -1;
+    curt.tm_year = (( str[4]-0x30)*1000 + (str[5]-0x30)*100 + (str[6]-0x30)*10 + (str[7]-0x30)) -1900 ;
+
+    curt.tm_hour=(str[8]-0x30)*10+(str[9]-0x30);
+    curt.tm_min=(str[10]-0x30)*10+(str[11]-0x30);
+    curt.tm_sec=(str[12]-0x30)*10+(str[13]-0x30);
+
+    time_t epoch = mktime(&curt);
+    if (epoch == (time_t) -1) {
+        error("Error in clock setting\n");
+        // Stop here
+    }
+    set_time(epoch);
+    return 1;
+}
+
+
+int iSetTerminalTime(char *tstring)
+{
+    int ret=0;
+    struct tm curt;
+
+    ret = Date_Time_Setting(curt,tstring);
+
+    if(ret == 1) {
+         wait(1);
+         
+       // Display_LCD(0,0,"     DATE-TIME     ");
+//        Display_LCD(0,1,"   SET SUCCESS   ");
+        printf("Date Time Set succesfully\r\n");
+
+    } else {
+       // Display_LCD(0,0,"     DATE-TIME     ");
+//        Display_LCD(0,1,"      SET FAILURE  ");
+        printf("Date Time Set Failure \r\n");
+
+    }
+    wait(2);
+//   Clear_LCD();
+
+    return ret;
+}
+
+
+int chk_time (char *str)
+{
+    int HH,MM,SS;
+    HH=(str[0]-0x30)*10+(str[1]-0x30);
+    MM=(str[2]-0x30)*10+(str[3]-0x30);
+    SS=(str[4]-0x30)*10+(str[5]-0x30);
+    if ( HH < 0 || HH > 23 || MM < 0 || MM > 59 || SS < 0 || SS > 59 )
+        return -1;
+    return 1;
+}
+
+int chk_date (char *str)
+{
+    int epos_date=0,epos_month=0,epos_year=0;
+    epos_date  = ( str[0]-0x30)*10+(str[1]-0x30);
+    epos_month = ( str[2]-0x30)*10+(str[3]-0x30);
+    epos_year  = ( str[4]-0x30)*1000+ (str[5]-0x30)*100 + (str[6]-0x30)*10 + (str[7]-0x30);
+
+
+    if ( epos_month < 1 || epos_date < 1 || epos_date > 31 || epos_month > 12  ||  epos_year < 2008 ) return ERROR ;
+
+    else if(epos_month == 1 || epos_month == 3 || epos_month == 5 || epos_month == 7 ||                                                                     epos_month == 8 || epos_month ==10 ||epos_month == 12) {
+
+        if (epos_date > 31)
+            return -1;
+    }
+
+    else  if (epos_month == 4 || epos_month == 6 || epos_month == 9 || epos_month == 11) {
+
+        if (epos_date > 30)
+            return -1;
+    }
+
+    else if  (epos_month == 2 )
+
+    {
+        if ( !(epos_year%400) || (epos_year%100 != 0 && epos_year%4==0 ) ) {
+            if (epos_date > 29 ) return -1;
+        }
+
+        else  if( epos_date > 28 ) return -1;
+    }
+    return 1;
+}
+
+void  Get_Date_Time(char *date_string,char *time_string, char *DTSTRING)
+{
+    time_t curr_time;
+    tm * curr_tm;
+    time(&curr_time);
+    curr_tm = localtime(&curr_time);
+    strftime(date_string,10,"%Y%m%d",curr_tm);
+    strftime(time_string,10,"%H%M%S",curr_tm);
+    strftime(DTSTRING,20,"%Y%m%d%H%M%S",curr_tm);
+}
+
+void  Get_Date_Time(char *date_string,char *time_string)
+{
+    time_t curr_time;
+    tm * curr_tm;
+    time(&curr_time);
+    curr_tm = localtime(&curr_time);
+    strftime(date_string,10,"%Y%m%d",curr_tm);
+    strftime(time_string,10,"%H%M%S",curr_tm);
+  
+}
+
+void  Get_Date_Time_Display( char *DTSTRING)
+{
+    time_t curr_time;
+    tm * curr_tm;
+    time(&curr_time);
+    curr_tm = localtime(&curr_time);  
+    strftime(DTSTRING,29,"%Y/%m/%d              %H:%M",curr_tm);
+  
+}
+
+void  Get_Date_Time( char *DTSTRING)
+{
+    time_t curr_time;
+    tm * curr_tm;
+    time(&curr_time);
+    curr_tm = localtime(&curr_time);  
+    strftime(DTSTRING,20,"%Y%m%d%H%M%S",curr_tm);
+}
+
+void  Get_Date_Time_Trns( char *DTSTRING)
+{
+    time_t curr_time;
+    tm * curr_tm;
+    time(&curr_time);
+    curr_tm = localtime(&curr_time);  
+    strftime(DTSTRING,20,"%d%m%Y%H%M%S",curr_tm);
+}
+
+
+
+int is_6_O_Clock(void)
+{ 
+char dat[9]={'\0'};
+char tim[9]={'\0'};
+int HH,MM;
+Get_Date_Time(dat,tim); 
+    HH=(tim[0]-0x30)*10+(tim[1]-0x30);
+    MM=(tim[2]-0x30)*10+(tim[3]-0x30);
+       
+    if((HH==6) &&(MM <30))
+    {
+      // printf("%d:%d\r\n",HH,MM);
+       return 1;       
+        }   
+        else
+        {
+           
+           // printf("%d:%d\r\n",HH,MM);
+            return 0;
+        }
+}
+
+int Get_Hours(void)
+{
+char dat[9]={'\0'};
+char tim[9]={'\0'};
+int HH,MM;
+    Get_Date_Time(dat,tim); 
+    HH=(tim[0]-0x30)*10+(tim[1]-0x30);
+    MM=(tim[2]-0x30)*10+(tim[3]-0x30);
+    return HH;
+}
\ No newline at end of file
diff -r 000000000000 -r a5d3db2f2625 Time.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Time.h	Tue Aug 21 11:18:56 2018 +0000
@@ -0,0 +1,19 @@
+
+#ifndef MBED_TIME_H
+#define MBED_TIME_H
+#include "mbed.h"
+
+
+int Date_Time_Setting(struct tm curt,char *str);
+int iSetTerminalTime(char *tstring);
+int chk_time (char *str);
+int chk_date (char *str);
+void  Get_Date_Time(char *date_string,char *time_string, char *DTSTRING);
+void  Get_Date_Time( char *DTSTRING);
+void  Get_Date_Time_Trns( char *DTSTRING);
+int is_6_O_Clock(void);
+void  Get_Date_Time(char *date_string,char *time_string);
+void  Get_Date_Time_Display( char *DTSTRING);
+int Get_Hours(void);
+
+#endif
\ No newline at end of file
diff -r 000000000000 -r a5d3db2f2625 main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Tue Aug 21 11:18:56 2018 +0000
@@ -0,0 +1,230 @@
+#include "mbed.h"
+ #include "NextionLCD.h"
+ #include "Time.h"
+ #define  PASSWORD 11111
+ 
+#include "MFRC522.h"
+#include "Card.h"
+ 
+RawSerial pc(USBTX,USBRX);
+NextionLCD lcd(D1, D0);     //Tx, Rx
+Thread Menu;
+Thread DispTime;
+Thread DispName;
+
+DigitalOut led1(LED1);
+DigitalOut led2(LED2);
+DigitalOut led3(LED3);
+DigitalOut relay(D8);
+
+
+volatile char c;
+uint8_t Present_State=0;
+uint8_t Previous_State=0;
+uint8_t Back=0;
+void Page1(void);
+void Page2(void);
+void Page3(void);
+void Page4(void);
+void Main_Menu(void);
+void flip(void);
+
+ 
+ char prevPage='\0';
+//bool flag=true;
+char Cand_Name[25]={'\0'};
+ char Time_Disp[30]={'\0'};
+ 
+ void Display_Details(void);
+ 
+void pc_recv()
+{      
+    while(pc.readable()) 
+    {
+      c=pc.getc();    
+    }
+}
+
+
+void Menu_Selection()
+{  
+   
+    while(1)
+    {
+             pc_recv();  
+        switch (c)
+        {
+       case '1':  
+                    Main_Menu();
+                    c='\0';
+                    wait(1);
+               break;
+               
+       case '2':
+                Page1();
+                c='\0';
+                wait(1);
+              break;
+                
+       case '3':
+                Page2();
+                c='\0';
+                wait(1);
+             break;
+       case '4':
+                Page3();
+                c='\0';
+                wait(1);
+               break;
+               
+       case '5': 
+                Page4();
+                c='\0';
+                wait(1);
+               break;  
+       default: 
+                    //lcd.DrawString(0,0,480,40,2,WHITE,BLACK,0,2, "Flash Master Card to Edit");      
+//                    Display_Details();
+                    wait(1);
+                break;  
+        }
+    }   
+}
+
+void Display_Time(void)
+{
+  while(true)
+  {
+    Get_Date_Time_Display(Time_Disp);
+    lcd.DrawString(0,0,480,40,2,BLACK,WHITE,0,0,Time_Disp); 
+    lcd.DrawString(0,295,480,25,1,BLACK,WHITE,0,0,"Powered by Exultsoft Technolies Pvt. Ltd.");
+    wait(60);
+    memset(Time_Disp,'\0',30);
+  }
+ 
+}
+ int main() 
+ {    
+      char CARDNO[30]={'\0'};
+      lcd.ClrScr(BLACK);      
+      lcd.DrawString(0,100,480,40,2,WHITE,BLACK,0,2,  "##############################"); 
+      lcd.DrawString(0,150,480,40,2,YELLOW,BLACK,0,0, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
+      lcd.DrawString(0,200,480,40,2,BLUE,BLACK,0,0,   "------------------------------");
+      lcd.ClrScr(BLACK);
+      wait(10); 
+      iSetTerminalTime("27072018111213");
+      Menu.start(callback(Menu_Selection));
+      DispTime.start(callback(Display_Time));
+      DispName.start(callback(Display_Details));  
+     
+      int success=-1;
+      while(true)
+      {
+      MIFARE_Init();
+      Read_Card_Details(CARDNO);
+      
+     success= strcmp(CARDNO,"17D6C66B");
+         if(success==0)
+         {
+         flip();
+         wait(1);
+         }
+      }
+ }
+
+
+
+
+void Main_Menu(void)
+{   
+      lcd.DrawString(0,40,480,40,2,WHITE,BLACK,0,0, "1. MAIN MENU "); 
+      lcd.DrawString(0,80,480,40,2,YELLOW,RED,0,0,"2. OPTION ONE  ");
+      lcd.DrawString(0,120,480,40,2,BLUE,GREEN,0,0, "3. OPTION TWO ");
+      lcd.DrawString(0,160,480,40,2,BROWN,WHITE,0,0,"4. OPTION THREE ");
+      lcd.DrawString(0,200,480,40,2,RED,YELLOW,0,0,  "5. OPTION FOUR ");
+      lcd.DrawString(0,240,480,40,2,GREEN,BLUE,0,0,"6. OPTION FIVE");
+      wait(1);
+      Present_State=1; Previous_State=0;
+}
+
+void Page1(void)
+{   
+      lcd.DrawString(0,40,480,40,2,WHITE,BLACK,0,2,   "1. MAIN MENU "); 
+      lcd.DrawString(0,80,480,40,2,YELLOW,RED,0,0,  "2. PAGE 1  OPTION ONE  ");
+      lcd.DrawString(0,120,480,40,2,BLUE,GREEN,0,0, "3. PAGE 1  OPTION TWO ");
+      lcd.DrawString(0,160,480,40,2,WHITE,GRAY,0,0, "4. PAGE 1  OPTION THREE ");
+      lcd.DrawString(0,200,480,40,2,RED,YELLOW,0,0, "5. PAGE 1  OPTION FOUR ");
+      lcd.DrawString(0,240,480,40,2,GREEN,BLUE,0,0, "6. PAGE 1  OPTION FIVE");
+      wait(1);
+      Present_State=2; Previous_State=0;
+}
+
+void Page2(void)
+{   
+      lcd.DrawString(0,40,480,40,2,WHITE,BLACK,0,2,   "1. MAIN MENU "); 
+      lcd.DrawString(0,80,480,40,2,YELLOW,RED,0,0,  "2. PAGE 2  OPTION ONE  ");
+      lcd.DrawString(0,120,480,40,2,BLUE,GREEN,0,0, "3. PAGE 2  OPTION TWO ");
+      lcd.DrawString(0,160,480,40,2,WHITE,GRAY,0,0, "4. PAGE 2  OPTION THREE ");
+      lcd.DrawString(0,200,480,40,2,RED,YELLOW,0,0, "5. PAGE 2  OPTION FOUR ");
+      lcd.DrawString(0,240,480,40,2,GREEN,BLUE,0,0, "6. PAGE 2  OPTION FIVE");
+      wait(1);
+      Present_State=3; Previous_State=0;
+}
+
+void Page3(void)
+{   
+      lcd.DrawString(0,40,480,40,2,WHITE,BLACK,0,2,   "1. MAIN MENU "); 
+      lcd.DrawString(0,80,480,40,2,YELLOW,RED,0,0,  "2. PAGE 3  OPTION ONE  ");
+      lcd.DrawString(0,120,480,40,2,BLUE,GREEN,0,0, "3. PAGE 3  OPTION TWO ");
+      lcd.DrawString(0,160,480,40,2,WHITE,GRAY,0,0, "4. PAGE 3  OPTION THREE ");
+      lcd.DrawString(0,200,480,40,2,RED,YELLOW,0,0, "5. PAGE 3  OPTION FOUR ");
+      lcd.DrawString(0,240,480,40,2,GREEN,BLUE,0,0, "6. PAGE 3  OPTION FIVE");
+      wait(1); 
+  
+Present_State=4; Previous_State=0; 
+}
+
+void Page4(void)
+{   
+       lcd.DrawString(0,40,480,40,2,WHITE,BLACK,0,2,   "1. MAIN MENU "); 
+      lcd.DrawString(0,80,480,40,2,YELLOW,RED,0,0,  "2. PAGE 4  OPTION ONE  ");
+      lcd.DrawString(0,120,480,40,2,BLUE,GREEN,0,0, "3. PAGE 4  OPTION TWO ");
+      lcd.DrawString(0,160,480,40,2,WHITE,GRAY,0,0, "4. PAGE 4  OPTION THREE ");
+      lcd.DrawString(0,200,480,40,2,RED,YELLOW,0,0, "5. PAGE 4  OPTION FOUR ");
+      lcd.DrawString(0,240,480,40,2,GREEN,BLUE,0,0, "6. PAGE 4  OPTION FIVE");
+      wait(1);
+      Present_State=0; Previous_State=0;
+}
+
+void Display_Details(void)
+{    
+   while(1)
+   { 
+     Thread::signal_wait(0x2);
+     memcpy(Cand_Name,"        Good Morning",20);
+     int hours=Get_Hours();
+     if(hours>=0 && hours <12) 
+     lcd.FillRectangle(0,40,480,255,BLUE);
+     lcd.DrawString(0,40,480,40,2,WHITE,BLUE,0,2,Cand_Name); 
+     lcd.DrawString(0,80,480,40,2,WHITE,BLUE,0,2,"Name of CARD Holder");  
+     lcd.DrawString(0,120,480,40,2,WHITE,BLUE,0,2,"     Have a Great Day ");  
+     memset(Cand_Name,'\0',25);
+     relay=0;  
+     wait(1);
+     relay=1;
+     wait(2);
+     lcd.FillRectangle(0,40,480,255,BLUE);
+     
+     }
+}
+
+
+void flip(void)
+{
+   led1=!led1;
+   led2=!led2;
+   led3=!led3;
+   DispName.signal_set(0x02); 
+  
+}
+
diff -r 000000000000 -r a5d3db2f2625 mbed-os.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-os.lib	Tue Aug 21 11:18:56 2018 +0000
@@ -0,0 +1,1 @@
+https://github.com/ARMmbed/mbed-os/#50bd61a4a72332baa6b1bac6caccb44dc5423309