Show Posts
Pages: [1]
1  Forum 2005-2010 (read only) / Development / Re: interrupts other than INT0 INT1  and TIME on: June 04, 2007, 07:17:28 pm
very interesting. I was also using a delayMicroseconds call and getting some strange data, so I switched to delay() and there was no problem. I'm gonna go look at both of them in detail now.
2  Forum 2005-2010 (read only) / Development / Re: interrupts other than INT0 INT1  and TIME on: June 04, 2007, 06:00:13 pm
Hi Jim

Between now and then, I've gotten it working by using PCMSK0 very carefully, ie masking everything but the pin I'm 'listening' to. I suspect that before, indeed some digitalWrites were triggering undesired interrupts.

I've found that I need to do this, since cli() and sei() don't seem to work as expected* so I've avoided using them at all, and only using the PCICR and PCMSK0 to disable/enable interrupts. In any case, this little vacation in 'interrupt hell' has opened my eyes to some things to be very careful of in the future.

Also, my advice to any other interrupt newbies: do not even attempt to debug without a scope  smiley-wink

*I suspect that other wiring functions (eg Serial.print) are disabling/enabling interrupts and were the cause of some of my problems.
3  Forum 2005-2010 (read only) / Development / interrupts other than INT0 INT1  and TIMER on: June 04, 2007, 04:28:29 pm
HI

In the arduino0007 documentation, it only mentions those interrupts. I'm assuming that's because they provide functions in WInterrupts.c to deal with them.

I'm trying to use pin change interrupts (PCINT0) and I'm having trouble due to the interrupts being triggered all the time. In my ISR, the first thing I do is set another pin high so that I can scope out when I'm entering the ISR. My other scope probe is on the pin itself, and I'm getting interrupts even when the pin value isn't chaning. I'm using a 100 Mhz scope and looking at the finest possible time resolution, so I don't think it's a glitch, but who knows.

Anyone dealt with pin change interrupts on the arduino? am I missing something really obvious?








ISR (PCINT0_vect) {
  
   char cSREG;
   cSREG = SREG;
  
   //Serial.println(PORTB, BIN);
   digitalWrite(9, HIGH);
    
   PCICR &= ~0x01;
  
   qt_data = get_bytes(10);
  
   PCICR |= 0x01;
    
   digitalWrite(9, LOW);
  
   SREG = cSREG;
  
  
  
}
4  Forum 2005-2010 (read only) / Troubleshooting / Re: PORTx vs. digitalRead() on: July 18, 2007, 12:14:10 pm
ahh thanks, I'll give that a try.
5  Forum 2005-2010 (read only) / Troubleshooting / Re: PORTx vs. digitalRead() on: July 07, 2007, 10:22:00 pm
Yeah it is strange...here is the code:

Code:
#include <avr/portpins.h>
#include <avr/interrupt.h>

/*
Interupt-based QT300 1-WIRE driver
*/

#define TBR 200  //baud period in microseconds (110-200 allowed)
#define TWU 40  //wake up time
#define TSCK 40 //half period of clock (min 30)
#define TDS 80 //data spacing duration  (min 75)
#define TSAMP 15

#define CHAN 1 // number of channels to be sampled (not used yet)

//Connectors and corresponding arudino pins
#define       J1      2
#define       J2      3
#define       J3      4
#define       J4      5
#define       J5      6
#define       J6      7
#define       J7      8
#define       J8      9
#define       J9      10
#define       J10      11
#define       J11      12
#define       J12      13


//macros to disable pin change interrupts and mask/unmask them
#define DISABLE_INT  PCICR &= !(0x05)
#define ENABLE_INT PCICR |= 0x05
#define MASK0 PCMSK0 |= 0x3F
#define MASK2 PCMSK2 |= 0xFC
#define UNMASK0 PCMSK0 &= !(0x3F)
#define UNMASK2 PCMSK2 &= !(0xFC)

//states
#define DEFAULT 0
#define PRINT 1
#define SEND 2

//which PIN to send/recieve from:
int req = J4;
 
volatile uint16_t qt_data = 0;

volatile uint8_t state;
volatile byte portreading = 0;


int ch = 0;
int i = 0;
int bl = 0;                 // used to count the time of the acquisition burst

int dec_reading = 0;

void setup() {

  
  //disable PCinterrupts
  DISABLE_INT;
  UNMASK0;
  UNMASK2;

  //set PORTB to outputs
  DDRB = 0xFF;
  PORTB = 0xFF;
  
  DDRD = 0xFF;
  PORTD = 0xFF;
  
  
  Serial.begin(115200);      
  delay(500);                

  
   ENABLE_INT;
   MASK0;
   MASK2;

   state = SEND;
 

}//setup()

void loop(){
    
    switch (state) {
      
    case SEND:
  
    
     //send acquisition request
     send_req(req);
     state = DEFAULT;
     break;
      
    
     case PRINT:

     Serial.print(qt_data);
     Serial.println("");
     Serial.print(portreading,BIN);
     Serial.println("");
  
     state = SEND;
    
     break;
    
    
    default:
    
    
    break;
  
    }
 
}//loop()


uint16_t get_bytes(int pin) {
    
 
    static uint8_t qtMSB;
    static uint8_t qtLSB;
    
    qtMSB = 0;
    qtLSB = 0;
    
    //this delay needs to be determined by how long it takes to go through ISR
    delayMicroseconds(TBR);  //TBD
    delayMicroseconds(TBR/2);
    
    //first byte
    
    for (i = 0; i < 8; i++) {
    
    
      qtMSB |= (digitalRead(pin) << i);
      //qtMSB |= (PORTB1 << i);
      delayMicroseconds(TBR);
      
 
     }
  
    delayMicroseconds(85);
    
  
    while (digitalRead(pin)  != HIGH);
    while (digitalRead(pin) != LOW);
  
  
    delayMicroseconds(TBR);
    delayMicroseconds(TBR/2);
    
    //second byte
    for (i = 0; i < 8; i++) {
      
      qtLSB |= (digitalRead(pin) << i);
      //qtLSB |= PORTB1 << i;
      delayMicroseconds(TBR);
  
    }
  
  
  
  
   return qtLSB + (qtMSB << 8);

  
}

//send acquisition request to qt300 on selected pin
void send_req(int pin) {
  

    DISABLE_INT;
    UNMASK0;
    UNMASK2;
    
  
    DDRB |= 0xFF;
    DDRD |= 0xFF;
    
    //send wake up pulse
    digitalWrite(pin, LOW);
    delayMicroseconds(TWU);
    
    //send baud rate pulse
    digitalWrite(pin, HIGH);
    delayMicroseconds(TBR);
    digitalWrite(pin, LOW);
    
    
    delayMicroseconds(TWU); //twu
    digitalWrite(pin, HIGH);
  
    DDRB &= 0x00;
    DDRD &= 0x00;
    delayMicroseconds(TBR);
    
    ENABLE_INT;
    MASK0;
    MASK2;    
    
  
}

ISR(__vector_default)
{
    Serial.println("DEFAULT");
    state = PRINT;
}



ISR (PCINT0_vect) {
  
   DISABLE_INT;
   UNMASK0;
   UNMASK2;
  
   //portreadin = PORTB; //doesn't work, always gives all HIGH
   portreading = _SFR_IO8(port_to_input[2]);
 
   qt_data = get_bytes(req);  
  
   state = PRINT;

   ENABLE_INT;
   MASK0;
   MASK2;
  
}//ISR(PCINT0_vect);


ISR (PCINT2_vect) {

   DISABLE_INT;
   UNMASK0;
   UNMASK2;
 
   //portreading = PORTD;
   portreading = _SFR_IO8(port_to_input[4]);
  
   qt_data = get_bytes(req);  
  
   state = PRINT;

   ENABLE_INT;
   MASK0;
   MASK2;  
  
}//ISR(PCINT2_vect);
6  Forum 2005-2010 (read only) / Troubleshooting / PORTx vs. digitalRead() on: July 07, 2007, 08:05:31 pm
I have something that's mystifying me and I'm hoping someone can explain.

Background:
I'm using PORTB in this case.
I have DDRB = 0xFF; and PORTB = 0xFF;

I have an external chip that pulls down one of 6 pins on PORTB. Each one triggers a pin change interrupt. First thing I do in the ISR is check which was pulled low. Now when I just read in PORTB, they all appear high. When I use a for loop and use digitalRead(), it correctly tells me which one was low.

I could use the for loop method, but I'm wondering why just reading PORTB doesn't work.

I've looked at digitalRead, which after doing some checks returns this:

return (_SFR_IO8(port_to_input[digitalPinToPort(pin)]) >> digitalPinToBit(pin)) & 0x01;

Which I've managed to turn into this:

_SFR_IO8(port_to_input[2]); //PB is defined as 2 in pins_arduino.c

which successfully works as well.

SOO my question is can anyone explain why this SFR_IO8 trick works but simply reading PORTB does not?




7  Forum 2005-2010 (read only) / Troubleshooting / Watchdog Timer on: June 29, 2007, 06:04:25 pm
Hi folks

So I want to use the watchdog timer, and so I referred to the atmega168 datasheet to learn how to do so.

I've managed to get it working, and I've gotten different prescaling values to work so that it resets after different timeouts, and tested that these are indeed working (ie after .5 sec or 1 sec)

The problem:

it stops execution, but doesn't seem to reset. In fact, pressing the reset button does absolutely nothing, and I need to unplug the arduino and re-plug it to reset/program it again.

I suppose that I'm missing something about the bootloader, and that somewhere I need to specify an address where it should go upon resetting. Has anyone here used the WDT with the arduino? what am I missing?
8  Forum 2005-2010 (read only) / Interfacing / Re: Long(ish) Distance Communication on: August 22, 2007, 05:44:36 pm
Quote
Quote
Do I need to do anything special in firmware, or will the standard Serial.print commands work as needed?
No.  All the MAX232 (or any other rs232 transceiver/level converter) does is to convert TTL 0V and 5V signal levels to RS232 10V and -10V signal levels, and vice versa.

The Arduino mini and FTDI chip (on the mini adapter) wouldn't care if you took those signals and converted them to rs232 levels, or rs422 (like 232, but with differential signalling for more distance), or even lasers and fiber optic cable, so long as it gets converted back to 0/5V TTL at the other end.  smiley

-j

Yeah I understand that much. Another question that just popped up, can I just use 1 max232 and interface with the FTDI chip? or does the extra max232 on that end accomplish something that the FTDI doesn't?

9  Forum 2005-2010 (read only) / Interfacing / Re: Long(ish) Distance Communication on: August 08, 2007, 11:36:07 pm
Quote
RS485 may help you. It is a serial protocol like the RS232 but with better distance support.
As mentionned in this thread, take a look to MAxim's MAX489 RS485 drivers.

thanks. I looked into that as well, but I think it may be overkill for now.
10  Forum 2005-2010 (read only) / Interfacing / Re: Long(ish) Distance Communication on: August 08, 2007, 11:35:37 pm
Quote
Yes.  There's a device commonly called a "USB active extension" that is nothing more than a one port bus powered USB hub on the end of a 5m (the maximum allowed by spec) cable.  We have used two or three of these to get from a ceiling mounted projector back to a computer sitting in a corner.

Another long-haul USB option is a pair of devices that convert the signals from USB to something else and exchanges them over cat 5 cable.  A bit more pricey, but a bit longer haul, too (100m or better, IIRC).

Hmm. If I could do with 1 repeater it could work, but I don't like the idea of having to use 4 or 5, both cost wise and elegance wise...


Quote
Lots of folks, as this is the way the majority of computer communications used to be done.  There are specs on the cable for rs232 (EIA232 might be a more correct designation for the spec), but for 60' you can get 9600 baud on just about any old wire, using appropriate line drivers/receivers like the MAX232 family.

Quote
could I put one in between the tx/rx lines between an arduino mini and the mini-USB adapter?
You'll need one at each end.

I've built a few Arduino-based boards of my own design, and I use the MAX232 when I need true rs232 connectivity.  Works great.


This sounds more like what I'd need. I've looked at the datasheet, and it seems that on each end, I just hook up the R1in/T1out as needed. seems simple enough. Do I need to do anything special in firmware, or will the standard Serial.print commands work as needed?

anyway, thanks a lot for your help.
11  Forum 2005-2010 (read only) / Interfacing / Long(ish) Distance Communication on: August 07, 2007, 12:46:51 pm
I've done some brief research, but I'm looking for a way to reliably get data in/out to a computer around 20m (~60ft) away.  This is far beyond the USB spec, but I was wondering if using one or more USB hubs/repeaters would do the trick.

I have to say, I don't like that idea too much, so I was wondering if anyone had experience with serial line drivers? could I put one in between the tx/rx lines between an arduino mini and the mini-USB adapter?

So anyone with idea/experience with this or other ideas let me know.
12  Forum 2005-2010 (read only) / Interfacing / Re: supply current: has arduino fryed my qprox sen on: April 17, 2007, 07:34:47 pm
Well I've managed to do it. BTW Jon, I noticed in your code that your bytes are flipped around, ie you're reading in the MSB first and then shifting the less significant bits to the left. Is there a reason for that?
13  Forum 2005-2010 (read only) / Interfacing / Re: supply current: has arduino fryed my qprox sen on: April 16, 2007, 06:36:58 pm
Hi Jon

thanks very much for everything you've posted, you have no idea how much trouble you have saved me!

I have my qt300 sending SPI to my arduino, but now I want to use the 1-wire UART mode of the qt300, since it will greatly reduce the wiring complexity of my system ( I am using multiple qt300s). I already have code to do the 1-wire comm, but I first need to change modes of the qt300.

According to this thread on the quantum forum:

http://www.qprox.com/forum/read.php?1,1370

You can program the chips to change modes with only a microcontroller, rather than buying the programmer.

 I am about to do this, but I wanted to check if anyone here has done this, and can give some pointers.
14  Forum 2005-2010 (read only) / Exhibition / Re: Not my projet, but very impressive! on: April 24, 2007, 12:23:41 pm
hmm, "better"? yes it looks cooler, but the first one *sounds* MUCH better!
15  Forum 2005-2010 (read only) / Frequently-Asked Questions / Re: Turning an Arduino into a programmer on: May 25, 2007, 02:21:17 pm
Hey jims

I was thinking about this just earlier today and stumbled on this post. Sounds like a great idea. I thought I'd voice my interest in the following 'possible' features (in order):


# Restore bootloader (and appropriate fuses)

# Turn virgin chip into an Arduino chip.

# Write eeprom


Pages: [1]