Wednesday, December 16, 2015

GSM SIM Card for External Data Storage with Allen-Bradley PLC and Arduino UNO plus USB Host Shield




The application of a simple way to use external data storage using the GSM SIM card through 250 phonebook memory. in the phone book there is a name and phone number,  alphabets for name and numbers for phone number.
for write data to phonebook GSM SIM Card using USB Smart Card Reader and Arduino and USB Host Shiled.
Arduino periodically read data from the Allen-Bradley PLC memory and transfer to USB Smart Card Reader.
some examples of the use of this application are:
  1. Total product per shift / day : cards that have been written are taken, then replace it with a new card to be written again.
  2. Productivity per employee : every employee has one card,  the employee's card inserted into the card reader, then PLC write the number of products produced by the employee.
  3. Store the number of alarms per day, per week, per month
  4. Parameter data store, and etc.

This animation about total product produced per employee:
GSM SIM Card for Total Product Storage per Employee

Video demonstration:

GSM SIM Card for External Data Storage on Allen-Bradley PLC using Arduino and USB Smart Card Reader




Hardware of GSM SIM Card for Allen-Bradley PLC

  1. USB Smart Card Reader
  2. Allen-Bradley PLC , I use Allen Bradley MicroLogix 1000 PLC
  3.  Arduino UNO
  4. Arduino USB Host Shield
  5. GSM SIM Card
  6. RS232 PLC Cable for Allan-Bradley PLC
  7. Adapter for Arduino
  8. TTL to RS232 Module


Hardware Connections of GSM SIM Card for Allen-Bradley PLC

Please read my article about  USB Smart Card Reader and Allen-Bradley PLC



Software of GSM SIM Card for Allen-Bradley PLC

  1. I use Arduino software 1.6.6
  2. Arduino Libraries, click here
  3. Copy-paste DF1 and USBHostShields2 folder  to ..\arduino-nightly\libraries
  4. GSM SIM Card Edit Software, click here


Project file of GSM SIM Card for Allen-Bradley PLC

  1. For Arduino, click here
  2. For Allen Bradley MicroLogix 1000 PLC, click here


GSM SIM Card Phonebook Before and After Written by Allen-Bradley PLC

1. GSM SIM Card Phonebook BEFORE Written by Allen-Bradley PLC

GSM SIM Card Before Written by Allen-Bradley PLC

2. GSM SIM Card Phonebook AFTER Written by Allen-Bradley PLC

GSM SIM Card After Written by Allen-Bradley PLC


GSM SIM Card Phonebook Setting on Allen-Bradley PLC Ladder Programming

1. SIM Card Phone Book Index in N7:1 memory of MicroLogix 1000 PLC

Fill with number from 1 to 250

GSM SIM Card Phone Book Index in N7:1


2. SIM Card Phone Book Name in N7:2 to N7:17 memory of MicroLogix 1000 PLC

Fill with ASCII Character, example: T character with ASCII 84.

GSM SIM Card Phone Book Name in N7:2 to N7:17


3. SIM Card Phone Book Tel Num in N7:18 memory of MicroLogix 1000 PLC

Fill with number from 0 to 32767, No negative value

GSM SIM Card Phone Book Tel Num in N7:18



Arduino Code of GSM SIM Card for Allen-Bradley PLC

#include <usbhub.h>
#include <DF1.h>

#define DF1destination 1
#define DF1baud 9600
#define DF1format SERIAL_8N1
#define DF1timeout 1000


enum
{
  DF1PACKET1,
  DF1PACKET2,
  DF1TOTAL_NO_OF_PACKETS
};
DF1Packet DF1packets[DF1TOTAL_NO_OF_PACKETS];

DF1packetPointer DF1packet1 = &DF1packets[DF1PACKET1];
DF1packetPointer DF1packet2 = &DF1packets[DF1PACKET2];

unsigned int DF1writeRegs[1];
unsigned int DF1readRegs[28];


USB Usb;
USB_DEVICE_DESCRIPTOR buf;
uint8_t addr;
uint8_t rcode;
uint8_t PLC_State;
unsigned long next_timeout;
bool Smart_Card_Reader_USB_Run = false;
uint8_t Inc_Order;


uint8_t Sparam1[10] =  {0x62,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x00,0x00};
uint8_t Rparam1[21] =  {0x80,0x0b,0x00,0x00,0x00,0x00,0x01,0x00,0x80,0x00,0x3b,0x18,0x11,0xc1,0x43,0x01,0x10,0x09,0x05,0x07,0x77};

uint8_t Sparam2[15] =  {0x61,0x05,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x11,0x00,0x00,0x0A,0x00};
uint8_t Rparam2[15] =  {0x82,0x05,0x00,0x00,0x00,0x00,0x02,0x00,0x80,0x00,0x11,0x00,0x00,0x0a,0x00};

uint8_t Sparam3[17] =  {0x6F,0x07,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0xA0,0xA4,0x00,0x00,0x02,0x7F,0x10};
uint8_t Rparam3[12] =  {0x80,0x02,0x00,0x00,0x00,0x00,0x03,0x00,0x80,0x00,0x9f,0x16};

uint8_t Sparam4[17] =  {0x6F,0x07,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0xA0,0xA4,0x00,0x00,0x02,0x6F,0x3A};
uint8_t Rparam4[12] =  {0x80,0x02,0x00,0x00,0x00,0x00,0x04,0x00,0x80,0x00,0x9f,0x0f};

uint8_t Swrite[45] =  {0x6F,0x23,0x00,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0xA0,0xDC,0xFA,0x04,0x1E,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x0B,0x81,0xF0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
uint8_t Rwrite[12] =  {0x80,0x02,0x00,0x00,0x00,0x00,0x05,0x00,0x80,0x00,0x90,0x00};

                             
void setup() {
    if (Usb.Init() == -1){
      //OSC did not start
      //smart card reader not recognized
      while(1);   
    }


  PLC_State=0;
  Inc_Order=0;

DF1_construct(DF1packet1, DF1destination, DF1_WRITE_N7, 0, 1, DF1writeRegs);

DF1_construct(DF1packet2, DF1destination, DF1_READ_N7, 1, 28, DF1readRegs);

DF1_configure(&Serial, DF1baud, DF1format, DF1timeout, DF1packets, DF1TOTAL_NO_OF_PACKETS);

}

void loop() {
  DF1_update();
  Smart_Card_Fill_Data();
  Usb.Task();
  if( Usb.getUsbTaskState() == USB_STATE_RUNNING )
  {
  Smart_Card_Reader_USB_Run = true;
  if((millis() > next_timeout) && PLC_State>1)PLC_State=1;

            switch(PLC_State) {
                    case 0: // USB Smart Card Reader Find 
                            rcode = USB_Smart_Card_Reader_Configuration();
                            if(rcode){
                              //smart card reader not detected
                              while(1);
                            }else{
                              PLC_State=1;
                            }
                            break;

                            
                      case 1: // GSM SIM Card Reader Detect
                            rcode = GSM_SIM_Card_Reader ();
                            if (rcode==0x02){ //smart card reader not detecting card
                                PLC_State=1;
                            }
                            
                            if (rcode==0x03){ //smart card reader detecting card
                                next_timeout= millis() + 1000;                            
                                PLC_State=2;
                            }

                            break;

                      case 2 :
                            Sparam1[6]=Inc_Order;
                            rcode =  Smart_Card_Reader_PhoneBook_Write(sizeof(Sparam1),Sparam1,sizeof(Rparam1),Rparam1,Inc_Order);
                            if(rcode==0){
                              PLC_State=3;
                              Inc_Order++;                                                           
                            }
                          break;


                        case 3 :
                            Sparam2[6]=Inc_Order;
                            rcode =  Smart_Card_Reader_PhoneBook_Write(sizeof(Sparam2),Sparam2,sizeof(Rparam2),Rparam2,Inc_Order);
                            if(rcode==0){
                              PLC_State=4; 
                              Inc_Order++;                                                           
                            }
                          break;

                        case 4 :
                            Sparam3[6]=Inc_Order;
                            rcode =  Smart_Card_Reader_PhoneBook_Write(sizeof(Sparam3),Sparam3,sizeof(Rparam3),Rparam3,Inc_Order);
                            if(rcode==0){
                              PLC_State=5;
                              Inc_Order++;                                                            
                            }
                          break;

                        case 5 :
                            Sparam4[6]=Inc_Order;
                            rcode =  Smart_Card_Reader_PhoneBook_Write(sizeof(Sparam4),Sparam4,sizeof(Rparam4),Rparam4,Inc_Order);
                            if(rcode==0){
                              PLC_State=6;
                              Inc_Order++;                                                            
                            }
                          break;
                          
                        case 6 :                                
                                if(Swrite[12]==0x00 || Swrite[33]==0xFF)PLC_State=7;                                
                                Swrite[6]=Inc_Order;
                                rcode =  Smart_Card_Reader_PhoneBook_Write(sizeof(Swrite),Swrite,sizeof(Rwrite),Rwrite,Inc_Order);
                                if(rcode==0){
                                  PLC_State=7;
                                  Inc_Order++;                                                            
                                }                                                        
                              break;
                          
                        case 7 :
                                next_timeout= millis() + 1000; 
                                rcode = GSM_SIM_Card_Reader ();
                                if (rcode==0x03){
                                  if(Smart_Card_Write_Check())PLC_State=6;  
                                }
                                if (rcode==0x02){
                                  PLC_State=1;                                                                    
                                }
                              break;
                          
                             
            }
            
  }else{
    if(Smart_Card_Reader_USB_Run){
        //smart card reader error
        asm volatile ("  jmp 0"); 
    }
  }

}


void Smart_Card_Reader_GetAddresses(UsbDevice *pdev)
{
    UsbDeviceAddress adr;
    adr.devAddress = pdev->address.devAddress;
    addr = adr.devAddress;
}

uint8_t USB_Smart_Card_Reader_Configuration() {
  uint8_t rcode;
  Usb.ForEachUsbDevice(&Smart_Card_Reader_GetAddresses);
  rcode = Usb.getDevDescr(addr, 0, sizeof (USB_DEVICE_DESCRIPTOR), (uint8_t*) & buf);
  if (rcode) {
    return (rcode);
  }else{
    rcode = Usb.setConf(addr, 0, buf.bNumConfigurations);
    return (rcode);            
  }        
  return (USB_STATE_ERROR);
}

uint8_t GSM_SIM_Card_Reader (){
  uint8_t rcode;
  uint8_t  buf[64];
  uint16_t rcvd=0;
  rcode = BULK_IN(0x43,&rcvd, buf, 1);
  if(rcode)
    return rcode; 

  if (rcvd==2){
    if(buf[0]==0x50){
      DF1writeRegs[0] = buf[1];
      return buf[1];
    }
  }
    
return (1);
}


bool Smart_Card_Write_Check() { 
  uint8_t index =0;
  if(Swrite[12]!=DF1readRegs[index])return true;
  
  for(uint8_t i=15;i<=30;i++){  
    index++;     
    if(Swrite[i]!=DF1readRegs[index])return true;
  } 

  for(uint8_t i=33;i<=42;i++){  
    index++; 
    if(Swrite[i]!=DF1readRegs[index])return true;
  } 

return false;
}


void Smart_Card_Fill_Data() {
  uint8_t index =0;
  Swrite[12]=DF1readRegs[index];
  
  for(uint8_t i=15;i<=30;i++){  
      index++;  
      Swrite[i]=DF1readRegs[index];
      if(Swrite[i]==0)Swrite[i]=0xFF;
  } 


uint8_t  buf[3]={0xFF,0xFF,0xFF};
index++;
Decimal_SIM_Data_Number(DF1readRegs[index], buf);

uint8_t st=0;
uint8_t  buf2[3]={0xFF,0xFF,0xFF};
for(uint8_t i=0;i<3;i++){ 
   if(buf[i]!=0xFF){
    buf2[st]=buf[i];
    st++; 
   }   
}

  for(uint8_t i=33;i<=42;i++){
         
     if(i>=33 && i<=35){
      Swrite[i]= buf2[i-33]; 
     }else{
      Swrite[i]=0xFF;
     }

     if(Swrite[i]==0)Swrite[i]=0xFF;      
  } 

}



uint8_t Smart_Card_Reader_PhoneBook_Write(uint16_t nbytes, uint8_t* data,uint16_t ncbytes,uint8_t* cdata,uint16_t incbytes) {
 uint8_t rcode;
 rcode =  BULK_OUT(0x25,nbytes,data); 
 if(rcode)
    return rcode;

  uint8_t  buf[64];
  uint16_t rcvd=0;
  rcode = BULK_IN(0x46,&rcvd, buf, 10);
  if(rcode)
    return rcode;  
 
  if (rcvd==ncbytes){  
       cdata[6] = incbytes;
       for(uint8_t i=0;i<ncbytes;i++){          
          if(buf[i]!=cdata[i])return (1);
       } 
      return (0);
    }

return (1);
}



uint8_t BULK_OUT(uint8_t vHXFR,uint16_t nbytes, uint8_t* data) {
    Usb.bytesWr(rSNDFIFO, nbytes, data);
    Usb.regWr(rSNDBC, nbytes);
    Usb.regWr(rHXFR, vHXFR);
    while(!(Usb.regRd(rHIRQ) & bmHXFRDNIRQ)); //wait for the completion IRQ
    Usb.regWr(rHIRQ, bmHXFRDNIRQ); //clear IRQ             
  return (0);
}


uint8_t BULK_IN(uint8_t vHXFR,uint16_t *pktsize, uint8_t* data, unsigned long timeout) {
  unsigned long timeout_start = millis() + timeout;
    
  while((long)(millis() - timeout_start) < 0L) {
    Usb.regWr(rHXFR, vHXFR);
      if((Usb.regRd(rHIRQ) & bmRCVDAVIRQ)==bmRCVDAVIRQ){
      uint16_t buff_pktsize = Usb.regRd(rRCVBC);
      *pktsize = buff_pktsize;
      data = Usb.bytesRd(rRCVFIFO, buff_pktsize, data);
      Usb.regWr(rHIRQ, bmRCVDAVIRQ); // Clear the IRQ & free the buffer     
      return (0);   
      }   
   }      
             
  return (1);
}


void Decimal_SIM_Data_Number(uint16_t decata, uint8_t* hexdata) {
String str;
str=String(decata);

uint16_t b[6]={0,0,0,0,0,0};
int i;
  for(i=0;i<6;i++){
    if(str.length()==i)break;
    b[i] = (byte)(str[i]-0x30); 
  } 


int d=2;
  for(int c=(i-1);c>=0;c-=2){
    if(i==1){
      hexdata[d] =  (b[c]& 0x0F) | 0xF0;
    }else{
      hexdata[d] =  (b[c-1]& 0x0F) | (b[c] <<4);
    }
   if(d==0)break;
   d--;
  }
 
}



Labels:









Newer Post Older Post Home

You may also like these ebook:

Get Free PLC eBook directly sent to your email,
and email subscription to program-plc.blogspot.com




We hate SPAM. Your information is never sold or shared with anyone.

Your Email Will Be 100% Secured !

Your email is stored safely on Google FeedBurner