Sunday 19 November 2017

MSP430 with Bluetooth Low Energy RN4020 (BLE)

In this post, we'll see how to use a Bluetooth Low Energy (BLE) module, microchip's RN4020 with the MSP430 launchpad. I have used the MSP430G2553 microcontroller for this purpose. There is a lot of documentation available about BLE on the official website (Bluetooth.com) and just typing the term in google will lead you to several other sources. I may cover certain topics related to BLE in a separate post!

You'll need to know how UART works for this tutorial, I would suggest having a look at this URL:UART
Before connecting the BLE module to the micro-controller, we need to configure RN4020 as a peripheral and also create a private service and its characteristics. The steps required to do the same are as follows:

Connect RN4020 to an FTDI adapter (USB to TTL converter) like the one below:


Connect 3.3 V Vcc to RN4020 WAKE and Vcc respectively, GND to grounds and RX, TX to TX, and RX respectively.

Open Tera term and select the serial port, enable Local echo and select CR+Linefeed for Transmit and Receive from setup, and also set the correct baud rate under Serial Port option, i.e. 115200.

Now type the following commands, after the execution of each command, an ACK or acknowledgment signal will be received on the terminal.

SF,1 //factory default
SB, 4 // baud rate set as 115200
SS, C0000001 //set device information and battery service
PZ //clears all settings of the private service and characteristics
PS, 11223344556677889900AABBCCDDEEFF //define private service with UUID
PC,010203040506070809000A0B0C0D0E0F, 08, 02 //the specified characteristic with write property is added, size is 2 bytes
SR, 20000000 //auto advertise
R, 1 //reboot

Check the list of services by typing LS, the UUID of Device Information, Battery and our private service and its characteristics with their UUIDs and handles will be displayed.

The characteristic that we created will be used to turn the LED ON/OFF via an android application. On typing 00, the LED will turn OFF, if it was ON and on typing 01, the LED will turn ON (if it was OFF). You may create additional characteristics as per your requirement, refer the RN4020 user-guide to know more about different AT commands used to configure the module.

Now download BLE Scanner Application from the Android store: BLE Scanner App

Connect with the RN4020 module from the list of devices and enter 00 or 01 as the value of the private characteristic, do select byte array and not Text to enter the value successfully. After entering the same, you can observe that tera terminal shows a command WC, handle, value. Here the value is either 00 or 01.

If on connecting the MSP430 micro-controller, you are able to read the value, you would then be able to make a decision. Have a look at the code which is loaded on MSP430G2553 which causes an interrupt to be generated whenever any value is transmitted by the BLE module. The code is self-explanatory.


#include <msp430.h>

#include<stdio.h>

char buffer[20]; //buffer to receive

volatile unsigned int receive = 0;

//configure UART

void Configure_UART()

{

P1SEL = BIT1 + BIT2;

P1SEL2 = BIT1 + BIT2;

UCA0CTL1 |= UCSSEL_2;

UCA0BR0 = 0X08;

UCA0BR1 = 0X00;

UCA0MCTL = UCBRS2 + UCBRS0;

UCA0CTL1 &= ~UCSWRST;

}
//configure pins

void Configure_Pins()

{

P1DIR |= BIT0; //Pin 0, LED connection

P1OUT &= ~BIT0;

&nbsp;

}
//main loop

void main(void)

{

WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer

BCSCTL1 = CALBC1_1MHZ; // Set range

DCOCTL = CALDCO_1MHZ;

Configure_UART();

Configure_Pins();

UC0IE |= UCA0RXIE;

__bis_SR_register(CPUOFF + GIE); //set cpuoff and enable interrupts
}

//cpu is turned on whenever interrupt occurs and in main routine its off(stack restored)
#pragma vector = USCIAB0RX_VECTOR

__interrupt void USCI0RX_ISR(void)

{

P1OUT &=~BIT6;

buffer[receive++] = UCA0RXBUF;

if(UCA0RXBUF == '\n')

{
receive = 0;

__bic_SR_register(GIE); //disable interrupt as we want to make a decision now

char conn = buffer[0];

if(conn != 'C')

{

char c = buffer[9]; //decide number to be accessed

switch(c)

{

case '1': P1OUT |= BIT0;

break;

case '0': P1OUT &= ~BIT0;

break;

}

}

__bis_SR_register(GIE); //okay to talk again

}

}

Finally, the demo can be found on Youtube: Demo Video

Saturday 18 November 2017

MSP430G2553 with a Light Dependent Resistor

In this tutorial, we will connect a Light Dependent Resistor to an MSP430 and turn ON the LED connected to Port 1, pin 0 if the light is below a threshold value else we will turn it OFF.

The LDR is connected to Port 1, pin 7 (configured to act as input channel for the ADC). The SAR ADC on MSP430 converts the analog values supplied by the LDR to digital values.

As displayed in the video (link given below), the LDR is connected in a voltage divider circuit with a 10K Ohms resistor. The detailed theory about the operation of the voltage divider circuit and the formula for calculating the voltage due to variation in resistance of the LDR can be found on: http://robotics.hobbizine.com/ldrlaunch.html

Youtube video link: Demo Video

#include <msp430.h>

unsigned int value = 0;

void ConfigureADC(void)

{
ADC10CTL1 = INCH_7 + ADC10DIV_0;
ADC10CTL0 = SREF_0 + ADC10SHT_2 + ADC10ON + ADC10IE;
ADC10AE0 |= BIT7;
}

void ConfigurePins(void)
{
P1OUT = 0;
P1DIR |= BIT0;
}

void main(void) {

WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer

BCSCTL1 = CALBC1_1MHZ;

DCOCTL = CALDCO_1MHZ;

ConfigurePins();

ConfigureADC();

while(1)

{

ADC10CTL0 |= ENC + ADC10SC;

__bis_SR_register(CPUOFF + GIE);

value = ADC10MEM;

if(value <= 511)

{

P1OUT |= BIT0; //turn ON the Light

}

else

{

P1OUT &= ~BIT0; //turn if OFF

}

}

}

#pragma vector = ADC10_VECTOR

__interrupt void ADC10_ISR(void)

{

__bic_SR_register_on_exit(CPUOFF);

}

You may use this circuit with a bulb and power the circuit with a solar panel during day time and use the saved power to turn ON the bulb after evening. Another interesting project along similar lines is: Solar Powered Project using MSP430
Kindly comment if you want to know anything specific about the H/W or S/W part!
Next post will be on an MSP430 + Bluetooth low energy module!

MSP430G2553 - Toggle LED with a switch

In this post, we'll learn to use a switch to toggle an LED using MSP430G2553 μcontroller.

The LED and switch are connected to Port 1, pin 0 and pin 3 respectively. Clicking the switch generates an interrupt. Initially, the LED is in OFF state, if the switch is pressed, the LED starts blinking till next interrupt occurrence/switch press.

If pull mode is enabled by setting PxREN register then either the pull up or pull down option can be selected by setting or clearing the corresponding bit in PxOUT register. One can either select high to low or low to high transition as the trigger for interrupt by setting/clearing the corresponding bit in PxIES register. Detailed information regarding the port settings can be found in the datasheet.
The state of the switch is tracked by a variable named "blink".

Do check the demonstration video: MSP430 with a switch and an LED

#include<msp430.h>

unsigned int blink = 0;

void main(void)

{

 WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer

 P1DIR |= BIT0; // Set P1.0 to output direction

 P1OUT &= ~BIT0; //clear pin

 P1REN |= BIT3; //enable pull mode 

 P1OUT |= BIT3; //pull up

 P1IES |= BIT3; //triggers when button pressed, high to low 

 P1IE |= BIT3; //enable interrupt 

__enable_interrupt(); //global/general interrupts enabled
for(;;) 

 { 

if (blink > 0)
{
P1OUT ^= BIT0; //toggle LED
__delay_cycles(100000); //delay of 10000 cycles at 1MHz
  }

 }
}
//Port 1 Interrupt Service Routine

#pragma vector = PORT1_VECTOR

__interrupt void Port_1(void)
{
blink ^= 0x01;
P1IFG &= ~BIT3; // P1.3 interrupt flag cleared
P1OUT &= ~BIT0; // clear LED to start in off state
}

MSP430G2553 – LED/Blinky

Blinking LED is similar to "Hello World" for an embedded engineer. I started using launchpad as a part of my MSc. project and have been experimenting with it since then. As there are many blogs and websites that assist a beginner or a pro alike, I'll mention all that I referred (wherever relevant).

The best blog to get started with MSP430 would be : MSPSCI Blog

This blog covers all the basics required to get started with the development process. I have used MSP430G2553 microcontroller on a launchpad board for this project.

Hardware: Although, there is an on-board LED, I have used an external one and have connected everything on a breadboard. (Picture will be added soon).

Code: There is a default project called Blink.c (CCS), you may use that or the below mentioned code.
 
#include<msp430.h>

void main(void)

{

WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer

P1DIR |= BIT0; // Set P1.0 to output direction

for(;;)

{

volatile unsigned int i; // volatile to prevent optimization

P1OUT ^= BIT0; // Toggle P1.0 using exclusive-OR

__delay_cycles(100000); //delay of 10000 cycles at 1MHz

}

}

General Points regarding C programming language

  1. The three important aspects of any language are:
    1. The way in which it stores the data
    2. The operators it uses to transform and combine data
    3. How it accomplishes I/P & O/P
  2. C was developed at AT & T's Bell Labs, USA in 1972 by Dennis Ritchie.
  3. The major advantages that promoted its use were its reliability, ease of use and simplicity.
  4. Languages can be classified as:
    1. High Level/Problem Oriented Languages: Ensure faster development or better programming efficiency. Examples: FORTRAN, PASCAL, Java, etc.
    2. Low Level/Machine Oriented Languages: Ensure faster execution or better program execution. Example: Assembly language
    3. C fits in between the two categories, hence, it is often termed as Middle level language. C not only allows bit-oriented operations, Direct Memory Access and usage of pointers but also provides high level constructs. Hence, both code readability and performance are ensured.
  5. Exponentiation operations allowed in higher level languages (2**3, 2^3) aren't considered valid in C.
  6. Types of Instructions are:
    1. Sequence Control,
    2. Decision Control,
    3. Loop Control &
    4. Case Control Instruction
  7. The usage of nested if-else's (Decision control) can be minimised by using logical operators (&&, ||). Nested if-else increases the complexity and lines of code.
  8. Conditional operators - Expression1 ? Expression2 : Expression3. As only one statement is allowed after ? or :, hence, usage in serious programming is limited.
  1. Other points will be added soon...

Programs on C - Convert int number to string and display

Without using any library functions (except scanf and printf), convert integer number as provided by user to a character string and display the string.

#include <stdio.h>

void tostring(char [], int);

int main()

{

char str[10]; //len is 10 considering max storage size of int

int num,result;

printf("Enter a number: ");

scanf("%d",&num);

tostring(str,num); //convert to string

printf("Number converted to string: %s\n",str);

return 0;

}

//function to convert to string

void tostring(char str[], int num)

{

int i, rem, len =0, n;

n=num;

while(n!=0)

{

len++; //get length for string/digits in int

n=n/10;

}

for(i=0;i<len;i++) //convert and store in string

{

rem=num%10; //last digit fetched first

num=num/10; //continue fetching rest of the digits

str[len-(i+1)]=rem + '0'; //start storing string with max-1 index first

}

str[len]='\0'; //null to end the string[max]

}

Programs on C - All three digit prime numbers

A prime number is a number which is either divisible by 1 or itself, hence, we need to check if the number is divisible by any number but itself and 1. If the remainder is zero on checking this condition then the number is not a prime number.

#include <stdio.h>

int main()

{

int i, j;

int IsPrime;

printf("The three digit prime numbers are:\n");

for(i=100;i<1000;i++)

{

IsPrime = 1;

for(j=2;j<i;j++) //check divisibility with all but 1 and itself

{



if(i%j==0) //if divisible then it's not a prime number

{

IsPrime = 0; //not a prime number

break; //no need to check divisibilty further as it's divisible by some no.

}

}

if(IsPrime==1)

{

printf("%d \n", i); //print only if the no. is not divisible by any other no. except itself or 1, i.e. it's prime no.

}

}

return 0;

}


Programs on C - Reverse of a number


#include <stdio.h>
int main()
{
int x; //input number
int rev; //reverse will be stored in this variable
printf("Type a number to get reverse of the number: ");
scanf("%d", &x);
printf("The number is: %d \n", x);
while(x>0)
{
rev = rev*10 + x%10;
x= x/10;
}
printf("Reverse of the number is: %d \n", rev);
return 0;
}
The same can be accomplished by using a function specifically for reversing the number. Also, recursive function can be used to achieve the same.