Sunday, March 20, 2016

HC-SR04 with Raspberry Pi - Distance

HC-SR04 (Ultrasonic Module) interfacing with Raspberry Pi for distance calculation.




Will provide the schematics soon.

/*
 * HC-SR04 <> RPi
 * To calculate the distance
 * Using the libbcm2835 library
 * Author : Ahamed EN (ahamed.en@gmail.com)
 * 20-March-2016
 */
#include <bcm2835.h>
#include <stdio.h>
#include <sys/time.h>

/* We will be using
 * Pin#16 (GPIO23) as Trigger
 * Pin#18 (GPIO24) for Echo
 */
#define TRIGGER RPI_GPIO_P1_16
#define ECHO    RPI_GPIO_P1_18

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

    if (!bcm2835_init())
        return 1;

    struct timeval start, end;
    float duration;

    bcm2835_gpio_fsel(TRIGGER, BCM2835_GPIO_FSEL_OUTP);
    bcm2835_gpio_fsel(ECHO, BCM2835_GPIO_FSEL_INPT);

    bcm2835_gpio_write(TRIGGER, LOW);
    bcm2835_gpio_write(ECHO, LOW);
    bcm2835_delay(2);

    bcm2835_gpio_write(TRIGGER, HIGH);
    usleep(10); /* As per the HC-SR04 manual */
    bcm2835_gpio_write(TRIGGER, LOW);

    /* Wait until we get a HIGH */
    while(!bcm2835_gpio_lev(ECHO));
    gettimeofday(&start, NULL);

    /* Wait until we get a LOW */
    while(bcm2835_gpio_lev(ECHO));
    gettimeofday(&end, NULL);

    /*
     * speed = distance/time
     * speed = 340m/s = 34300cm/s (speed of sound)
     *
     * 34300 = distance/time
     *
     * distance = time/2 * 34300 (time/2 because what we got is the time
     *                              for to and fro)
     */

    duration = (end.tv_sec - start.tv_sec) * 1000.0;
    duration += (end.tv_usec - start.tv_usec) / 1000.0;
    duration = duration/1000; /* to seconds */

    float distance = duration/2 * 34300;

    printf("Disatnce : %f cm\n", distance);

    bcm2835_delay(500);
    bcm2835_close();
    return 0;
}

Interfacing SIM800 module with Raspberry Pi via Serial Interface C program

Interfacing SIM800 module with R-Pi via Serial Interface using C program. Following program sends an SMS to the specified mobile number.

This program uses the normal C routines

R-Pi                 SIM800
                  
Pin#06(GND)  --------  GND
Pin#08(TXD0) --------  Rx
Pin#10(RXD0) --------  Tx



root@raspberrypi:~/sim# gcc send.c -o send_sms

root@raspberrypi:~/sim# ./send_sms
Writing to Port : AT
Read from port  : ATOK
Writing to Port : AT+CMGF=1
Read from port  : AT+CMGF=1OK
Writing to Port : AT+CNMI=2,1,0,0,0
Read from port  : AT+CNMI=2,1,0,0,0OK
Writing to Port : AT+CMGS="9535213788"
Read from port  : AT+CMGS="9535213788">
Writing to Port : PI_SIM800_TESTING




The received SMS


/*
 * SIM800 <> Raspberry Pi - Serial Interface
 * To send a SMS using SIM800 module via RPi
 * Author : Ahamed EN (ahamed.en@gmail.com)
 * Date : 20 March 2016
 */

#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <termios.h>

/* This is R-Pi default serial port */
#define DEFAULT_PI_SERIAL_PORT "/dev/ttyAMA0"

typedef enum _mode_t{
    RW,
    WO,
    RO
}sim_mode_t;

static inline void error(char *err)
{
    printf("Error : %s\n", err);
}

#define ERROR(err) { printf("[%s %d] ", __func__, __LINE__); error(err); }

int open_serial_dev(char *serial_dev)
{

    if(!serial_dev){
        ERROR("serial_dev in NULL");
        return -1;
    }

    int fd;

    fd = open(serial_dev, O_RDWR | O_NOCTTY | O_NDELAY);
    if(fd < 0){
        ERROR("Could not open the serial device");
        return -1;
    }
    return fd;

}

/* To initialize the serial port via termios */
int serial_init(int fd)
{

    struct termios termios;
    int ret = 0;

    ret = tcgetattr (fd, &termios);
    if(ret < 0){
        ERROR("tcgetattr failed");
        return -1;
    }

    cfsetispeed(&termios, B9600);
    cfsetospeed(&termios, B9600);

    termios.c_iflag &= ~(IXANY | IXON | IXOFF);
    termios.c_lflag &= ~(ICANON | ECHO);
    termios.c_cflag |= (CLOCAL | CREAD);

    termios.c_cc[VMIN]  = 1;
    termios.c_cc[VTIME] = 10;

    ret = tcsetattr (fd, TCSANOW, &termios);
    if(ret < 0){
        ERROR("tcsetattr failed");
        return -1;
    }


    return 0;
}

void set_cmd(char *cmd, char *cmd_str)
{
    memset(cmd, 0, sizeof(cmd));
    strcpy(cmd, cmd_str);
}

int read_port(int fd, int ret)
{
    int rv = 0;
    int i = 0;
    char buf[64];
    if(ret){
        rv = read(fd, &buf, sizeof(buf));
        printf("Read from port\t: ");
        for(i=0; i<rv; i++){
            if(buf[i] == '\n' || buf[i] == '\r') continue;
            printf("%c", buf[i]);
        }
        printf("\n");
    }
    return rv;
}

int write_port(int fd, char *cmd, int len)
{
    if(fd < 0){
        ERROR("Invalid fd");
        return -1;
    }

    printf("Writing to Port\t: %s", cmd);

    int ret = 0;
    ret = write(fd, cmd, len);
    if(ret <= 0){
        ERROR("write failed");
    }
    return ret;

}

/* Function to write and read from the port */
void set_get_cmd(int fd, sim_mode_t mode, char *cmd_str)
{
    int ret;
    char cmd[64];
    set_cmd(cmd, cmd_str);
    ret = write_port(fd, cmd, strlen(cmd));
    usleep (100000);
    if(mode == WO){
        return;
    }
    read_port(fd, ret);
    return;

}

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

    char *serial_dev = DEFAULT_PI_SERIAL_PORT;
    int ret = 0;
    int fd;


    if(argv[1]){
        serial_dev = argv[1];
    }

    fd = open_serial_dev(serial_dev);
    if(fd < 0){
        ERROR("Exiting");
        return -1;
    }

    ret = serial_init(fd);
    if(ret < 0){
        ERROR("Exiting");
        return -1;
    }

    /* Check the SIM800 Data sheet for the commands */

    set_get_cmd(fd, RW, "AT\r\n");
    set_get_cmd(fd, RW, "AT+CMGF=1\r\n");
    set_get_cmd(fd, RW, "AT+CNMI=2,1,0,0,0\r\n");

    /* Specify the 10 digit mobile # here */
    set_get_cmd(fd, RW, "AT+CMGS=\"9535213788\"\r\n");

    /* Following is your text message */
    set_get_cmd(fd, WO, "PI_SIM800_TESTING\r\n");

    set_get_cmd(fd, WO, "\x1A");

    printf("\n");

    return 0;

}