Author Topic: Arduino Port Manipulation  (Read 3623 times)

0 Members and 1 Guest are viewing this topic.

Offline DTM22Topic starter

  • Jr. Member
  • **
  • Posts: 32
  • Helpful? 0
Arduino Port Manipulation
« on: November 18, 2011, 02:37:03 PM »
Hi, I'm attempting to use port manipulation for a project I'm working on where the timing is very crucial.  Ive read several tutorials about it online but I am still unclear on how to read whether the appropriate INPUT pins read HIGH or LOW.  In my case I'm using the digital pins 6 and 7.  I was already told by someone to use the following code to check whether the state of either of the pins changes to HIGH and if so, to perform a particular function.  Here's the code I was given by joe61:
Quote
Code:

int main()
{
    DDRD &= ~ ((1 << PD6) | (1 << PD7));
   
    for ( ;; )
    {
        if (PIND & (1 <<PD6))
            handlePD6 ();
        if (PIND & (1 <<PD7))
            handlePD7 ();

        _delay_ms (100);
    }
}


Where handlePD[67] are functions you write to do what you want.

This was very helpful but when I add it to my code, I get the error message saying PD6 and PD7 were not declared in this scope, how do I got about declaring them properly?

Offline joe61

  • Supreme Robot
  • *****
  • Posts: 417
  • Helpful? 16
Re: Arduino Port Manipulation
« Reply #1 on: November 18, 2011, 04:37:24 PM »
That was just a fragment, you have to #include <avr/io.h> as well. If you're using the Arduino environment I thought it did that for you, but I don't use it so maybe not. If not using the Arduino IDE, just add this to the top of the file

Code: [Select]
#include <avr/io.h>
Then your makefile (if you're doing it that way) needs to define the processor you're using. Here's an example:

Code: [Select]
DEVICE  = atmega328p
AVRDUDE_DEVICE = m328p

SRCS = main.c
OBJS = $(SRCS:.c=.o)

CFLAGS=-g -Wall -mcall-prologues -mmcu=$(DEVICE) -Os
CC=avr-gcc
OBJ2HEX=avr-objcopy
LDFLAGS=-Wl,-gc-sections -Wl,-relax

PROG = -c usbtiny -P usb
#PROG = -c avrisp2 -P /dev/ttyACM0

AVRDUDE=avrdude
TARGET=main
OBJECT_FILES=$(OBJS)

all: $(TARGET).hex

clean:
rm -f *.o *.hex *.obj *.hex

%.hex: %.obj
$(OBJ2HEX) -R .eeprom -O ihex $< $@

sensors.o: sensors.c

%.obj: $(OBJECT_FILES)
$(CC) $(CFLAGS) $(OBJECT_FILES) $(LDFLAGS) -o $@

program: $(TARGET).hex
$(AVRDUDE) -p $(AVRDUDE_DEVICE) $(PROG) -U flash:w:$(TARGET).hex


I switch back and forth between a Pololu and Adafruit programmer, so that's what the PROG macros are for, substitute a definition that suits your programmer.

Joe

P.S. Lots of people use something like webbotLib to keep from having to mess with makefiles. You might find it very helpful: http://webbot.org.uk/iPoint/30.page

Offline DTM22Topic starter

  • Jr. Member
  • **
  • Posts: 32
  • Helpful? 0
Re: Arduino Port Manipulation
« Reply #2 on: November 19, 2011, 01:34:22 PM »
Hi, sorry to bother you again about this but I'm using the Arduino IDE and it does not recognize that library.  I'm still getting the same error message, any other ideas as to what may be causing the problem?

Offline joe61

  • Supreme Robot
  • *****
  • Posts: 417
  • Helpful? 16
Re: Arduino Port Manipulation
« Reply #3 on: November 19, 2011, 01:40:56 PM »
Post the code you're using and I'll take a look. Can't say without seeing that.

Joe

Edit: Are you copying the code I posted into the Arduino environment? That won't work, because it has its own main() routine. Rather than use main() as I did, you need to use the setup() and loop() functions.

Put the 'DDRD &= ~ ((1 << PD6) | (1 << PD7)); ' part in the setup() function, and the code in the for (;;) loop in the loop() function.
« Last Edit: November 19, 2011, 01:48:24 PM by joe61 »

Offline DTM22Topic starter

  • Jr. Member
  • **
  • Posts: 32
  • Helpful? 0
Re: Arduino Port Manipulation
« Reply #4 on: November 19, 2011, 02:00:25 PM »
Hey, thanks for your help, here's what I have so far.
Right now I'm just attempting to have a value sent to the LCD screen when the sensor is tripped(Goes HIGH)
Code:

#include <LiquidCrystal.h> //Liquid Crystal Library
#define pin6 (1 << PD6)
#define pin7 (1 << PD7)       
       
        int BPS;                 
        int FPS;               
        long Inches;           
        long Time;           
        unsigned long StartTime;
        unsigned long StopTime; 
        unsigned long Duration;
     
        LiquidCrystal lcd(8, 9, 10, 11, 12, 13);
        //Initialises the library with the appropriate interface pins
   
        void setup()
        {
         lcd.begin(16, 2);                                // Sets up the LCD's number of columns and rows(16x2):
         DDRD &= ~ ((1 << PD6) | (1 << PD7));  //Sets Pins 6 and 7 as INPUTS
        }

        void loop()
        {   
            if (PIND & (1 <<PD6))
            {
              StartTime=micros();
              lcd.print(StartTime, DEC);
              delay(3000);
              lcd.clear();
            }   
        }
       

Offline joe61

  • Supreme Robot
  • *****
  • Posts: 417
  • Helpful? 16
Re: Arduino Port Manipulation
« Reply #5 on: November 19, 2011, 02:41:51 PM »
I set up an LCD on a breadboard and loaded your code. I think it's doing what the code says to. What are you seeing that is different than what you expect? Can you copy and paste the error messages?

Incidentally. I didn't realize you're using the Arduino environment. You don't need any of the bit-fiddling we've been doing there. You don't have to set pin 6 & 7 as input because that's what they are by default. To read the value of pin 6 you can just say

Code: [Select]
unsigned char val = digitalRead (6)
Joe

Offline DTM22Topic starter

  • Jr. Member
  • **
  • Posts: 32
  • Helpful? 0
Re: Arduino Port Manipulation
« Reply #6 on: November 19, 2011, 02:45:39 PM »
Here are the error messages Im getting:
Sensor_Programming_with_LCD_PortMan__.cpp: In function 'void setup()':
Sensor_Programming_with_LCD_PortMan__:36: error: 'PD6' was not declared in this scope
Sensor_Programming_with_LCD_PortMan__:36: error: 'PD7' was not declared in this scope
Sensor_Programming_with_LCD_PortMan__.cpp: In function 'void loop()':
Sensor_Programming_with_LCD_PortMan__:62: error: 'PD6' was not declared in this scope
Sensor_Programming_with_LCD_PortMan__:69: error: 'PD7' was not declared in this scope

And as for using digitalread, I read it is too slow for the time sensitive calculation I will be doing and could cause errors in my end result which is why I was looking into port manipulation to take much faster readings.

Offline joe61

  • Supreme Robot
  • *****
  • Posts: 417
  • Helpful? 16
Re: Arduino Port Manipulation
« Reply #7 on: November 19, 2011, 02:51:27 PM »
Weird, it compiles fine for me with PD6 & PD7. Maybe your avr-gcc got messed up somehow. Try removing and reinstalling the Arduino environment. What version are you using? (Help -> About Arduino)

Joe

Offline DTM22Topic starter

  • Jr. Member
  • **
  • Posts: 32
  • Helpful? 0
Re: Arduino Port Manipulation
« Reply #8 on: November 19, 2011, 03:10:04 PM »
I just removed and reinstalled the Arduino Environment, I was running version 022 and I now have version 023 and Im still getting the same error message

Offline joe61

  • Supreme Robot
  • *****
  • Posts: 417
  • Helpful? 16
Re: Arduino Port Manipulation
« Reply #9 on: November 19, 2011, 03:27:50 PM »
There's a thread on the Arduino forums about this ( http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1287285012 ), it says to use PORTD6 rather than PD6, because of the way things are declared for the 328. So I checked the header file for the 328p and sure enough they are declared like that.

So now I have to figure out why it compiles on my machine, I don't think I've every used PORTDn.

Joe

Offline DTM22Topic starter

  • Jr. Member
  • **
  • Posts: 32
  • Helpful? 0
Re: Arduino Port Manipulation
« Reply #10 on: November 19, 2011, 03:38:41 PM »
So by rewriting the code and changing PD6 to PORTD6 and PD7 to PORTD7 is should work?

Offline DTM22Topic starter

  • Jr. Member
  • **
  • Posts: 32
  • Helpful? 0
Re: Arduino Port Manipulation
« Reply #11 on: November 19, 2011, 03:58:34 PM »
I did it and it works!  Thanks so much, you were a big help!