วันศุกร์ที่ 8 กุมภาพันธ์ พ.ศ. 2562

microcontroller 6

IoT based Web controlled Home Automation using PIC Microcontroller and Adafruit IO



IoT based Web controlled Home Automation using PIC Microcontroller and Adafruit IO



Component Required

  1. ESP8266
  2. PIC microcontroller(PIC16f877A)
  3. 12V 5A Electromagnetic Relay Module -1
  4. 12v Power supply (12V/1A or above) -1
  5. LM7805 Voltage Regulator -1
  6. LM317 Regulator -1
  7. 10k ohm Resistor -1
  8. 1k Resistor – 3
  9. 10k Pot – 1
  10. 1k Pot -1
  11. 16x2 LCD
  12. 1000uF capacitor -1
  13. 10uF capacitor -2
  14. Wires for connection
  15. 18.432 MHz Crystal oscillator -1
  16. LED -2
  17. 22pF capacitor -2
  18. BreadBoard or PCB (optional)

Project Code



#define _XTAL_FREQ 18432000
#include <xc.h>
#include<pic.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
// BEGIN CONFIG
#pragma config FOSC = HS // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT enabled)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = ON // Brown-out Reset Enable bit (BOR enabled)
#pragma config LVP = OFF // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)
//END CONFIG
 
#define uchar unsigned char
#define uint unsigned int
 
#define LCDPORTDIR TRISA
#define LCDPORT PORTA
#define RS RE1
#define EN RE0
 
#define relay1dir TRISC0
#define relay2dir TRISC1
#define relay3dir TRISC2
#define relay4dir TRISC4
#define relay1 RC0
#define relay2 RC1
#define relay3 RC2
#define relay4 RC4
 
#define leddir TRISC3
#define led RC3
 
#define txDir TRISD0
#define tx RD0
 
#define HIGH 1
#define LOW 0
 
#define maxRetry 3
 
#define buflen 95
 
volatile char buf[95];
uchar buf1[70];
uchar buf2[15];
int retry;
int restartFlag=0;
volatile char index=0;
volatile char flag=0;
volatile int msCount=0;
volatile char g_timerflag=1;
volatile int counter=0;
volatile char sec=0;
unsigned int topiclength;
unsigned char topic[25];
unsigned char encodedByte;
int X;
 
const char MQTTHost[] = "io.adafruit.com";
const char MQTTPort[] = "1883";
const char MQTTClientID[] = "ABCDEF";
const char MQTTTopicRelay1[] = "saddam4201/feeds/Light1";
const char MQTTTopicRelay2[] = "saddam4201/feeds/Light2";
const char MQTTTopicRelay3[] = "saddam4201/feeds/Light3";
const char MQTTTopicRelay4[] = "saddam4201/feeds/Light4";
const char MQTTProtocolName[] = "MQTT";
const char MQTTLVL = 0x03;
const char MQTTFlags = 0xC2;
const unsigned int MQTTKeepAlive = 60;
const char MQTTUsername[] = "saddam4201";                // put your Username
const char MQTTPassword[] = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";    // Put Your Password
const char MQTTQOS = 0x00;
const char MQTTPacketID = 0x0001;
 
#define netCheckSec 60
int initFlag=1;
 
enum
{
 CMD,
 DATA, 
 SBIT_CREN=4,
 SBIT_TXEN,
 SBIT_SPEN,
};
 
int SendConnectPacket(void);
int SendSubscribePacket(char topic[], int);
 
void lcdwrite(uchar ch,uchar rw)
{
     LCDPORT= ch>>4 & 0x0F;
     RS=rw;
     EN=1;
     __delay_ms(5);
     EN=0; 
     LCDPORT= ch & 0x0F;
     EN=1;
     __delay_ms(5);
     EN=0;    
}
 
lcdprint(char *str)
{
    while(*str)
    {
        lcdwrite(*str++,DATA);
        //__delay_ms(20);
    }
}
 
lcdbegin()
{
    uchar lcdcmd[5]={0x02,0x28,0x0E,0x06,0x01};
    uint i=0;
    for(i=0;i<5;i++)
    lcdwrite(lcdcmd[i], CMD);
}
 
void serialbegin(unsigned long baudrate)
{
    TXSTAbits.BRGH = 1;                                     //Setting High Baud Rate
    SPBRG=(_XTAL_FREQ/(long)(16UL*baudrate))-1; 
    TXSTAbits.SYNC = 0;                                     //Setting Asynchronous Mode, ie UART
    RCSTAbits.SPEN = 1;                                     //Enables Serial Port
    TRISC7 = 1;                                   //As Prescribed in Datasheet
    TRISC6 = 0;                                   //As Prescribed in Datasheet
    RCSTAbits.CREN = 1;                                     //Enables Continuous Reception
    TXSTAbits.TXEN = 1;                                     //Enables Transmission
 
    //RCONbits.IPEN   = 1; // ENABLE interrupt priority
    GIE  = 1; // ENABLE interrupts
    INTCONbits.PEIE = 1; // ENable peripheral interrupts.
    PIE1bits.RCIE   = 1; // ENABLE USART receive interrupt
    PIE1bits.TXIE   = 0; // disable USART TX interrupt
 
// make sure the RX flag is clear
    PIR1bits.RCIF = 0;
  
}
 
void serialwrite(char ch)
{
    while(TXIF==0);  // Wait till the transmitter register becomes empt
    TXREG=ch;        // load the char to be transmitted into transmit reg
        TXIF=0;          // Clear transmitter flag
    __delay_ms(1);
}
 
serialprint(char *str)
{
    while(*str)
    {
        serialwrite(*str++);
    }
}
 
serialprintln(char *str)
{
    while(*str)
    {
        serialwrite(*str++);
    }
    serialwrite(0x0D);
    serialwrite(0x0A);
}
 
char UART_RxChar()
{
    while(RCIF==0);    // Wait till the data is received 
    RCIF=0;  
    uchar ch=RCREG;// Clear receiver flag
    lcdwrite(ch, DATA);
    return(ch);     // Return the received data to calling function
}
 
void serialFlush()
{
    for(int i=0;i<buflen;i++)
    {
        buf[i]=0;
    }
    index=0;
}
 
void write(char ch)
{
/* tx=0;
__delay_us(8);
for(int i=0;i<8;i++)
{
if(ch & 1)
tx=1;
else
tx=0;
__delay_us(8);
ch>>=1;
}
tx=1;
__delay_us(8); */
}
 
 
void Serialprintdebug(char *str)
{
    while(*str)
    {
write(*str);
            str++;
}
}
 
void timer()           // 10 -> 1us
{   
    OPTION_REG = (1<<2);  // Timer0 with external freq and 32 as prescalar
    TMR0=100;       // Load the time value for 1ms delay
    TMR0IE=1;       //Enable timer interrupt bit in PIE1 register
    GIE=1;          //Enable Global Interrupt
    PEIE=1;         //Enable the Peripheral Interrupt
}
 
void timerOn(uint time)
{
    msCount=time;
    TMR0=99;
    PEIE=1;
}
 
void timerOff()
{
    PEIE=0;
}
 
void delay(unsigned int t)
{
    for(int i=0;i<t;i++)
        for(int j=0;j<1000;j++);
}
 
int espInit(char *cmd, char *res, int time)
{
    retry=0;
    while(1)
    {
        if(flag == 0)
        serialFlush();
        serialprintln(cmd);
        long csec=sec;
        while(sec < csec+time)
        {
            if(strstr(buf,res))
            {
                return 0;
            }
            __delay_ms(1000);
        }
          retry++;
          if(retry>maxRetry)
          {
             return 1;
          }
    }
    return 1;
}
 
void espInitize()
{
    lcdwrite(0x01, CMD);
    lcdprint("ESP Initilizing");
    serialprintln("AT+RST");
    __delay_ms(5000);
    espInit("AT","OK",2);
    espInit("ATE1","OK",2);
    espInit("AT+CWMODE=3","OK",2); 
    espInit("AT+CWQAP","OK",2); 
    espInit("AT+CWJAP=\"wifi_name\",\"password\"","OK",3);
    serialprintln("AT+CIFSR");
serialFlush();
    __delay_ms(500);
}
 
void checkBuffer()
{
     if(strstr(buf,"Light1ON"))
            relay1=0;     
     else if(strstr(buf,"Light1OFF"))
            relay1=1;
     else if(strstr(buf,"Light2ON"))
            relay2=0;
     else if(strstr(buf,"Light2OFF"))
            relay2=1;
     else if(strstr(buf,"Light3ON"))
            relay3=0;
     else if(strstr(buf,"Light3OFF"))
            relay3=1;
     else if(strstr(buf,"Light4ON"))
            relay4=0;
     else if(strstr(buf,"Light4OFF"))
              relay4=1;           
     serialFlush();
}
 
void restartESP()
{
            espInitize();
            espInit("AT+CIPSTART=\"TCP\",\"io.adafruit.com\",1883","CONNECT",5)
            SendConnectPacket()
SendSubscribePacket(&MQTTTopicRelay1[0],strlen(MQTTTopicRelay1))
SendSubscribePacket(&MQTTTopicRelay2[0],strlen(MQTTTopicRelay2))
SendSubscribePacket(&MQTTTopicRelay3[0],strlen(MQTTTopicRelay3))
            lcdwrite(1,CMD);
            led=1;
}
 
int main()
{            
  ADCON1=0b00000110;
  relay4dir= 0;
  relay1dir= 0;
  relay2dir= 0;
  relay3dir= 0;
  leddir=0;   
  LCDPORTDIR=0x00;
  TRISE=0;
  txDir=0;
  lcdbegin();
  lcdprint("Home Automation ");
  lcdwrite(192,CMD);
  lcdprint("Using PIC16F877A");
  __delay_ms(2000);
  //Serialprintdebug("Saddam Khan");
  index=0;    
  serialbegin(115200);
  timer();
  timerOn(1000);
  lcdwrite(1,CMD);
  lcdprint("Please Wait...");
  led=0;
  restartESP();
  while(1)
  {   
      if(flag==1)
      {
          checkBuffer();
          flag=0;
      }
      
  lcdwrite(0x80,CMD);
  lcdprint("L1    L2    L3");
  lcdwrite(192,CMD);
  if(relay1)
  lcdprint("OFF");
  else
  lcdprint("ON ");  
  
    lcdwrite(198,CMD);
  if(relay2)
  lcdprint("OFF");
  else
  lcdprint("ON "); 
    
    
  lcdwrite(204,CMD);
  if(relay3)
  lcdprint("OFF");
  else
  lcdprint("ON "); 
      
  __delay_ms(1000);
  } 
  return 0;
}
 
void interrupt SerialRxPinInterrupt(void)
{
    if((PIR1bits.RCIF == 1) && (PIE1bits.RCIE == 1))
    {
        
        uchar ch=RCREG;
        if(ch != NULL)
        {
            buf[index]=ch;
            if(index>=30)
                flag=1;
           index++;
            if(index>=buflen)
             index=0;
        }
        RCIF = 0; // clear rx flag
    }  
    
   if(INTCONbits.TMR0IE && INTCONbits.TMR0IF)
   { 
    TMR0IF=0;
    TMR0=112;
    counter++;
    if(counter >= msCount)
    {
        sec++;
        if(sec >= netCheckSec)
        {
           g_timerflag=1;
           sec=0;
        }
        counter=0;
    }
    }
}
 
int SendConnectPacket(void)
{
  int txIndex=0;
  unsigned int MQTTProtocolNameLength = strlen(MQTTProtocolName);
  unsigned int MQTTClientIDLength = strlen(MQTTClientID);
  unsigned int MQTTUsernameLength = strlen(MQTTUsername);
  unsigned int MQTTPasswordLength = strlen(MQTTPassword);
  X = MQTTProtocolNameLength + 2 + 4 + MQTTClientIDLength + 2 + MQTTUsernameLength + 2 + MQTTPasswordLength + 2;
  do
  {
    encodedByte = X % 128;
    X = X / 128;
    if ( X > 0 )
    {
      encodedByte |= 128;
    }
  } while ( X > 0 );
 
  buf1[txIndex++]=0x10;
  buf1[txIndex++]=encodedByte;
  buf1[txIndex++]=MQTTProtocolNameLength<<8;
  buf1[txIndex++]=MQTTProtocolNameLength; 
  memcpy((unsigned char *)&buf1[txIndex],(unsigned char *)&MQTTProtocolName,MQTTProtocolNameLength);
  txIndex+=MQTTProtocolNameLength;
  buf1[txIndex++]=MQTTLVL;
  buf1[txIndex++]=MQTTFlags;
  buf1[txIndex++]=MQTTKeepAlive<<8;
  buf1[txIndex++]=MQTTKeepAlive;
  buf1[txIndex++]=MQTTClientIDLength<<8;
  buf1[txIndex++]=MQTTClientIDLength;
  memcpy(&buf1[txIndex],(char *)&MQTTClientID,MQTTClientIDLength);
  txIndex+=MQTTClientIDLength;
  buf1[txIndex++]=MQTTUsernameLength<<8;
  buf1[txIndex++]=MQTTUsernameLength;
  memcpy(&buf1[txIndex],(char *)&MQTTUsername,MQTTUsernameLength);
  txIndex+=MQTTUsernameLength; 
  buf1[txIndex++]=MQTTPasswordLength<<8;
  buf1[txIndex++]=MQTTPasswordLength;
  memcpy(&buf1[txIndex],(char *)&MQTTPassword,MQTTPasswordLength);
  txIndex+=  MQTTPasswordLength;
   serialFlush();
   sprintf(buf2,"AT+CIPSEND=%d",txIndex);
   serialprintln(buf2);
   __delay_ms(1000);
   serialFlush();
   for(int i=0;i<txIndex;i++)
   serialwrite(buf1[i]);
   serialwrite(0x1A);
   __delay_ms(2000);
}
 
int SendSubscribePacket(char topic[], int topiclength)
{
  X = 2 + 2 + topiclength + 1;
  do
  {
    encodedByte = X % 128;
    X = X / 128;
    if ( X > 0 )
    {
      encodedByte |= 128;
    }
    //serialwrite(encodedByte);
  } while ( X > 0 );
  
  int txIndex=0;
  buf1[txIndex++]=0x82;
  buf1[txIndex++]=encodedByte;
  buf1[txIndex++]=MQTTPacketID<<8;
  buf1[txIndex++]=MQTTPacketID;
  buf1[txIndex++]=topiclength<<8;
  buf1[txIndex++]=topiclength;
  memcpy(&buf1[txIndex],(char *)&topic[0],topiclength);
  txIndex+=topiclength;
  buf1[txIndex++]=MQTTQOS;
   serialFlush();
   sprintf(buf2,"AT+CIPSEND=%d",txIndex);
   serialprintln(buf2);
   __delay_ms(1000);
   serialFlush();
   for(int i=0;i<txIndex;i++)
   serialwrite(buf1[i]);
   serialwrite(0x1A);
   __delay_ms(2000);
}

microcontroller 5

Rotary Encoder Interfacing with PIC Microcontroller




PIC Microcontroller PIC16F877A Rotary Encoder Interfacing Tutorial



Components Required

It is the time to identify what we need to interface Rotary Encoder with PIC Microcontroller,
  1. PIC16F877A
  2. 4.7k resistor
  3. 1k resistor
  4. 10k pot
  5. 33pF ceramic disc capacitor – 2pcs
  6. 20Mhz crystal
  7. 16x2 Display
  8. Rotary Encoder
  9. 5V adapter.
  10. Bread Board
  11. Hookup wires.

Project Code


/*
 * File:   main.c
 * Author: Sourav Gupta
 *
 * Created on 18 Dec 2018, 18:57
 */
 
/*
 * Configuration Related settings. Specific for microcontroller unit.
 */
#pragma config FOSC = HS        // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = ON       // Brown-out Reset Enable bit (BOR enabled)
#pragma config LVP = OFF         // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3/PGM pin has PGM function; low-voltage programming enabled)
#pragma config CPD = OFF        // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config WRT = OFF        // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = OFF         // Flash Program Memory Code Protection bit (Code protection off)
#define _XTAL_FREQ 20000000
/*
 * System Header files inclusions
 */
 
#include <xc.h>
//#include <string.h>
#include <stdlib.h>
#include "supporting c files/lcd.h"
 
#define Encoder_SW PORTDbits.RD2
#define Encoder_DT PORTDbits.RD3
#define Encoder_CLK PORTCbits.RC4
 
/*
 * Program flow related functions
 */
int counter; // It will hold the count of rotary encoder.
int position; // It will store the rotary encoder position.
void sw_delayms(unsigned int d);
int value[7];
 
/*
 * System Init Function
 */
 
void system_init ();
 
/* Main function single Thread*/
void main(void) {
    system_init();
    lcd_puts ("Circuit Digest");
    lcd_com(0xC0);
    counter = 0;
    while(1){
        lcd_com(0xC0);
        if (Encoder_SW == 0){
            sw_delayms(20);
            if (Encoder_SW == 0){
                //lcd_com(1);
                //lcd_com(0xC0);
                lcd_puts ("switch pressed");
//                itoa(counter, value, 10);
//                lcd_puts(value);
            }
        }                       
       if (Encoder_CLK != position){
            if (Encoder_DT != position){
               // lcd_com (0x01);
                counter++;
                lcd_com (0xC0);
                lcd_puts("                ");
                lcd_com (0xC0);
                lcd_bcd(1,counter);
            }
            else{
               // lcd_com (0x01);
                lcd_com (0xC0);
                counter--;
                lcd_puts("                ");
                lcd_com (0xC0);
                lcd_bcd(1,counter);
                //lcd_puts("Left");
            }           
        }
        position = Encoder_CLK;                
 
}
 
    return;
}
 
void sw_delayms(unsigned int d){
int x, y;
for(x=0;x<d;x++)
for(y=0;y<=1275;y++);
}
 
void system_init(){
    TRISB = 0x00; // PORT B as output, This port is used for LCD    
    TRISDbits.TRISD2 = 1;
    TRISDbits.TRISD3 = 1;
    TRISCbits.TRISC4 = 1;
    lcd_init(); // This will Initialize the LCD
    position = Encoder_CLK;// Sotred the CLK position on system init, before the while loop start.
}

microcontroller 4

Heart Beat Monitoring using PIC Microcontroller and Pulse Sensor



Heart Beat Monitoring in action



Required Components

  1. PIC16F877A microcontroller
  2. 20 Mhz Crystal
  3. 33pF capacitor 2 pcs
  4. 4.7k resistor 1 pcs
  5. 16x2 Character LCD
  6. 10K pot for contrast control of the LCD
  7. SEN-11574 Pulse sensor
  8. Velcro strap
  9. 5V Power adapter
  10. Breadboard and hookup wires


Project Code



void main() {
    system_init();
    main_state = READ_ADC;      
    while (1) {
        switch (main_state) {
            case READ_ADC:
            {                
                adc_value = ADC_Read(0); // 0 is the channel number
                main_state = CALCULATE_HEART_BEAT;                
                break;
            }
            case CALCULATE_HEART_BEAT:
            {
                calculate_heart_beat(adc_value);
                main_state = SHOW_HEART_BEAT;
                break;
            }
            case SHOW_HEART_BEAT:
            {
                if (QS == true) { // A Heartbeat Was Found
                    // BPM and IBI have been Determined
                    // Quantified Self "QS" true when Arduino finds a heartbeat                    
                    QS = false; // reset the Quantified Self flag for next time

                    // 0.9 used for getting better data. actually should not be used
                    BPM = BPM * 0.9;
                    IBI = IBI / 0.9;
                    lcd_com(0x80);
                    lcd_puts("BPM:-     ");
                    lcd_print_number(BPM);
                    lcd_com(0xC0);
                    lcd_puts("I.B.I:-   ");
                    lcd_print_number(IBI);                    
                }
            }
                main_state = IDLE;
                break;
       
        case IDLE:
        {            
            break;
        }
        default:
        {

        }
    }
}
}

ส่งงาน หน้า 308

หน้า 308




code

    int Read_VR(void);
main()
{
int i,time;
 TRISB = 0x00;
 CMCON = 0x07;
 while(1)
 {
  for(i=1;i<129;i=i*2)
  {
   PORTB = i;
   time = Read_VR()*2;
   Vdelay_ms(time);
   }
 }
}
int Read_VR(void)
{
 int i;
 i =0;
 TRISA = 0xF0;
 PORTA.F0 = 1;
 Delay_ms(10);
 TRISA = 0xF1;
       while(PORTA.F0 == 1)
       {
        i++;
        }
        i = i/10;
        return i ;
}

ส่งงาน หน้า 333

 หน้า 333




code


void alarm(void);
void Vdelay_us(int time);
main()
{
 TRISB=0xFC;
 PORTB.F1=0;
 while(1)
 {
  while(PORTB.F2==0)
  {
   while(PORTB.F3==1)
   {
    alarm();
    }
   }
  }
}
void alarm(void)
{
 int i ;
 PORTB.F1=1;
for(i=100;i>50;i--)
   {
    PORTB.F0=1;
    Vdelay_us(i);
    PORTB.F0=0;
    Vdelay_us(i);
    }
 PORTB.F1=0;
 for(i=50;i<100;i++)
 {
  PORTB.F0=1;
  Vdelay_us(i);
  PORTB.F0=0;
  Vdelay_us(i);
  }
 }
 void Vdelay_us(int time)
 {
  int i ;
for(i=0;i<time;i++)
   {
  }
}

วันจันทร์ที่ 4 กุมภาพันธ์ พ.ศ. 2562

microcontroller 3

Toggle/Blink led on specific delay with pic microcontroller using timers: MPLABX and xc8 compiler



Pic microcontroller specific delay generation to toggle leds.


Project circuit diagram

Pic16f887 microcontroller is used in the project. I am going to toggle the led's connected to Port-B of pic16f887 microcontroller. Port-B is an 8-bit port. 8 led's are connected with port-b. Whole port is going to be toggled after 10 ms delay. An external 20 Mhz crystal is used as input clock source to pic16f887 microcontroller.  Timer-1 of pic16f887 is used for generating specific delay. Timer-1 is used in 16-bit mode. 

Project Code


/************************************************** 
 * Property of: www.microcontroller-project.com   *
 * Author: Usman Ali Butt                         *
 * Created on 11 April, 2017, 2:30 PM             *
 **************************************************/

#include < stdio.h>
#include < stdlib.h>
#include < pic16f887.h>          

void Timer0Delay(void);       //Delay Function

int main(int argc, char** argv) {

    TRISB=0x00;               //Port-B as Output
      
    while(1){
        PORTB= ~PORTB;       //Toggle Output
        Timer0Delay();       //Delay
    }
    return (EXIT_SUCCESS);
}

void Timer0Delay(void){     //10ms delay
    T1CON=0x01;             //Timer-1 16-bit mode Prescaler 1:4
    TMR1H=0x30;             //Count Hight Byte
    TMR1L=0xD4;             //Count Low Byte
    
    T1CONbits.TMR1ON=1;              //Run timer
    while(INTCONbits.TMR0IF==0);     //Wait for flag to over flow
    T1CONbits.TMR1ON=0;              //Switch off timer
    INTCONbits.TMR0IF=0;             //Clear Interrupt
    
}




Internet of Things (IoT)

Internet of Things หรือ IoT Internet of Things (IoT)  คือ การที่อุปกรณ์อิเล็กทรอนิกส์ต่างๆ สามารถเชื่อมโยงหรือส่งข้อมูลถึงกันได้ด้วยอิน...