NerdKits - electronics education for a digital generation

You are not logged in. [log in]

NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.

Microcontroller Programming » How do I read what the bit is set to and the write it to the screen?

November 10, 2010
by KyleH
KyleH's Avatar

I thought I would take the challenge put forth the NK sample projects and make the LCD print when the screen is on or off. I didn't know what a microcontroller was three weeks ago and know nothing of C so its been a fun learning curve.

The Atmega168 Datasheet provides this sample code for reading the pin value so I tried to include it in my code shown below. I tried calling my variable I both portc and pinc to no avail. Am I on the right track here?

C Code Example

unsigned char i;
...
/* Define pull-ups and set outputs high */
/* Define directions for port pins */
PORTB = (1<<PB7)|(1<<PB6)|(1<<PB1)|(1<<PB0);
DDRB = (1<<DDB3)|(1<<DDB2)|(1<<DDB1)|(1<<DDB0);
/* Insert nop for synchronization*/
__no_operation();
/* Read port pins */
i = PINB;

My code attempt:

// led_blink.c
// for NerdKits with ATmega168
// hevans@nerdkits.edu

#define F_CPU 14745600
#include <stdio.h>
#include <avr/io.h>
#include <inttypes.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>

#include "../libnerdkits/delay.h"
#include "../libnerdkits/lcd.h"

// PIN DEFINITIONS:
//
// PC4 -- LED anode

int main() {

//Add Variable i
unsigned char i;

  // LED as output
  DDRC |= (1<<PC4);

    // fire up the LCD
  lcd_init();
  FILE lcd_stream = FDEV_SETUP_STREAM(lcd_putchar, 0, _FDEV_SETUP_WRITE);
  lcd_home();

  // loop keeps looking forever
  while(1) {
    // turn on LED
    PORTC |= (1<<PC4);

    //delay for 500 milliseconds to let the light stay on
    delay_ms(500);

    // turn off LED
    PORTC &= ~(1<<PC4);

    //delay for 500 milliseconds to let the light stay off
    delay_ms(500);

    //Define I to be the pin

    i = PORTC;

  // print message to screen
  //             20 columns wide:
  //                     01234567890123456789
  lcd_line_one();
  fprintf_P(&lcd_stream, PSTR("Status:"));
  lcd_write_data(i);
  fprintf_P(&lcd_stream, PSTR("Value"));
  lcd_line_two();
  lcd_write_string(PSTR("2nd Line"));
  lcd_line_three();
  lcd_write_string(PSTR("3rd Line"));
  lcd_line_four();
  lcd_write_string(PSTR("4th Line"));

  }

  return 0;
}
November 10, 2010
by KyleH
KyleH's Avatar

Heh I just figured out that I could simply write on when I turn it on and off when I turn it off.

Still I think it would be useful to know how to store whatever I am telling it to do and then recall it as a variable and say if its on, print on, if it is off print off. COuld you provide some help on how to do that in this case?

Working code in the loop looked like this:

    // turn on LED
    PORTC |= (1<<PC4);
    lcd_line_one();
    lcd_write_string(PSTR("Status: On "));

    //delay for 500 milliseconds to let the light stay on
    delay_ms(500);

    // turn off LED
    PORTC &= ~(1<<PC4);
    lcd_line_one();
    lcd_write_string(PSTR("Status: Off"));

    //delay for 500 milliseconds to let the light stay off
    delay_ms(500);
November 11, 2010
by bretm
bretm's Avatar

You want

i = PINC & (1<<PC4);

This will be either 0 or 16 depending on the state. If you want 0 or 1 you can do

i = (PINC >> PC4) & 1;

In your previous example it would always be zero (if you used PINC instead of PORTC) because you always checked right after you turned it off.

Post a Reply

Please log in to post a reply.

Did you know that reading a double floating point variable with scanf requires "%lf" for "long float"? Learn more...