Show Posts
Pages: 1 2 [3] 4 5
31  Forum 2005-2010 (read only) / Interfacing / Re: interrupt-driven USART reception: I'm stumped. on: March 09, 2009, 05:02:11 pm
Thanks for the info, I love the hexadecimal reward system.  
32  Forum 2005-2010 (read only) / Interfacing / Re: interrupt-driven USART reception: I'm stumped. on: March 08, 2009, 04:06:33 pm
I take your point that there are some trade-offs between ease of use and configurability.  But in this case I don't see the upside of automatically including the serial receive ISR in the uploaded code when there's no serial definitions in the code.

I'll look into that circular buffer algorithm if I can track down that book, it sounds interesting.

Cutting and pasting the ISR definition into the code is definitely an easier work-around than mine, thanks for the tip.
33  Forum 2005-2010 (read only) / Interfacing / Re: interrupt-driven USART reception: I'm stumped. on: March 07, 2009, 04:49:31 pm
The following code configures the USART manually without use of the Arduino serial functions.  The reason for this is that to get it to compile you have to comment out some of the wiring_serial.c file, and thus we can't use the Arduino serial commands.

Functionally, every time the receive interrupt is called it increments an index and then prints it to the serial buffer (again, manually).  

If you run the code, and you have Putty or hyperterminal or whatever properly configured, you'll just get the ASCII chart over and over as the index overflows.

Here it is:
Code:
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif
/* Definitions for setting and clearing register bits
*  See http://www.sigterm.de/projects/sens-o-nuts/Dokumentation/atmel/libc/group__avr__sfr.html */

int receiveroutputenable = 3;  
/* receiver output enable (pin2) on the max485.  
*  will be left low to set the max485 to receive data. */

int driveroutputenable = 4;    
/* driver output enable (pin3) on the max485.  
*  will left low to disable driver output. */

int rxpin = 0;                  // serial receive pin, which takes the incoming data from the MAX485.

unsigned long baud = 250000;    // The baud rate for DMX is 250000bps, since each bit = 4 microseconds.
unsigned long clockspeed = F_CPU;
/* F_CPU is a predefined constant equal to the clock speed of the microcontroller.
*  for the Arduino duomilanove it is 16000000.
*  I'm going to dump it into clockspeed because I'm worried about it being a signed long,
*  which could screw up the bitwise math I'm going to do on baudprescale, maybe. */

unsigned long baudprescale;    
/* The baud prescale that will be loaded into the
*  UBRR0H and UBRR0L registers to set the USART baud rate */


volatile int i = 0;           //dummy variable for for() loops, etc.
volatile byte ReceivedByte = 0; //holds the incoming byte from the receive buffer.

void setup() {
  pinMode(receiveroutputenable, OUTPUT);
  pinMode(driveroutputenable, OUTPUT);
  digitalWrite(receiveroutputenable, LOW);
  digitalWrite(driveroutputenable, LOW);    //sets pins 3 and 4 to low to enable reciever mode on the MAX485.

  pinMode(rxpin, INPUT);  //sets serial pin to receive data

  baudprescale = (((clockspeed / (baud * 16UL))) - 1); //

  cli();  //disable interrupts while initializing the USART

  sbi(UCSR0A, TXC0);
  cbi(UCSR0A, FE0);
  cbi(UCSR0A, DOR0);
  cbi(UCSR0A, UPE0);
  cbi(UCSR0A, U2X0); //
  cbi(UCSR0A, MPCM0);
  /* set transfer complete flag (TXC0 = 1).
  *  clear Frame Error flag (FE0 = 0).  
  *  clear Data overrun flag (DOR0 = 0).
  *  clear Parity overrun flag (UPE0 = 0).
  *  disable doubling of USART transmission speed (U2X0 = 0).  
  *  Disable Multi-Processor Communication Mode-- whatever that is. (MCPM0 = 0)  */
  
  sbi(UCSR0B, RXCIE0);
  cbi(UCSR0B, TXCIE0);
  cbi(UCSR0B, UDRIE0);
  sbi(UCSR0B, RXEN0);
  sbi(UCSR0B, TXEN0);
  cbi(UCSR0B, UCSZ02);
  /* Enable Receive Interrupt (RXCIE0 = 1).
  *  Disable Tranmission Interrupt (TXCIE = 0).
  *  Disable Data Register Empty interrupt (UDRIE0 = 0).
  *  Enable reception (RXEN0 = 1).
  *  Enable transmission (TXEN0 = 1).
  *  Set 8-bit character mode (UCSZ00, UCSZ01, and UCSZ02 together control this,
  *  But UCSZ00, UCSZ01 are in Register UCSR0C). */
  
  cbi(UCSR0C, UMSEL00);
  cbi(UCSR0C, UMSEL01);
  cbi(UCSR0C, UPM00);
  cbi(UCSR0C, UPM01);
  sbi(UCSR0C, USBS0);
  sbi(UCSR0C, UCSZ00);
  sbi(UCSR0C, UCSZ01);
  cbi(UCSR0C, UCPOL0);
  /* USART Mode select -- UMSEL00 = 0 and UMSEL01 = 0 for asynchronous mode.
  *  disable parity mode -- UPM00 = 0 and UPM01 = 0.
  *  Set USBS = 1 to configure to 2 stop bits per DMX standard.  The USART receiver ignores this
  *  setting anyway, and will only set a frame error flag if the first stop bit is 0.  
  *  But, we have to set it to something.
  *  Finish configuring for 8 data bits by setting UCSZ00 and UCSZ01 to 1.  
  *  Set clock parity to 0 for asynchronous mode (UCPOL0 = 0). */
  
  UBRR0L = baudprescale; // Load lower 8-bits of the baud rate value into the low byte of the UBRR register
  UBRR0H = (baudprescale >> 8); // Load upper 8-bits of the baud rate value into the high byte of the UBRR register
  // ***note to self: at some point add a command to write UBRR0H high bits to 0 per datasheet for "future compatibility"

  sei(); // Enable the Global Interrupt Enable flag so that interrupts can be processed
}  //end setup()

ISR(USART_RX_vect){
  ReceivedByte = UDR0;  
  /* The receive buffer (UDR0) must be read during the reception ISR, or the ISR will just
  *  execute immediately upon exiting. */
  i++;
  UDR0 = i;
} // end ISR

void loop()  {
 
} // end loop()

34  Forum 2005-2010 (read only) / Interfacing / Re: interrupt-driven USART reception: I'm stumped. on: March 07, 2009, 04:39:30 pm
Okay, I have some answers:

First of all, the serial receive interrupt is USART_RX_vect, not USART_RXC_vect as I had in my first post.  Defining USART_RXC_vect is like defining NOTHINGWILLHAPPEN_vect, it's a valid name for an interrupt vector, but it will never execute, because the CPU will never call it.

When you define USART_RX_vect, however, the compiler throws you an error, because the arduino software defines that interrupt vector and includes it in your code, whether you reference Arduino serial functions or not.  So you have to comment out some parts of wiring_serial.c

IMHO, and I'm new at this so please correct me if I'm wrong about this, including the serial functions even if they're not referenced is a bug, not a feature.  It increases the uploaded sketch size, and reduces the flexibility of the programmer, with no upside.  Anyway, in the next post is my workaround:
35  Forum 2005-2010 (read only) / Interfacing / Re: interrupt-driven USART reception: I'm stumped. on: March 05, 2009, 06:33:57 pm
Thank you for your post, it was illuminating to me on a number of levels.

So it sounds like if I want to access the UART_RXC ISR, I'll need to configure/access the USART manually by setting the bits in the control register and reading the buffer register, rather than using the Arduino serial library.  I can probably figure out how to do that.

I think that the problems receiving data I was having are due to buffer overrun, not noise.  I'm using good twisted pair shielded cable that I've properly terminated, etc. per EI485 best practices.  I'll check for slew rate on my o-scope, but I've used this controller with no problems before, so I'm sure it's fine.

I was assuming that ALL the interrupts were enabled by default.  

As a first step, I was attempting to read and post to the serial port all 512 levels as they came in.  But I'm actually only interested in a small subset of those values, so perhaps if I write that code first, the resulting routine will be fast enough that it won't overflow the buffer.

I'll post my results, thanks for your help so far.
36  Forum 2005-2010 (read only) / Interfacing / interrupt-driven USART reception: I'm stumped. on: March 04, 2009, 10:22:43 pm
Hi all,
    I'm trying to program the arduino to receive DMX-512, which runs at a 250Kbit baud rate.  I can receive the channel information, but I get intermittent bad values, which I think is because of other interrupts running and disrupting the serial reception.

However, there is an interrupt on the Atmega168 that indicates a new byte has been received by the USART, USART_RXC_vect.  So I thought, if I did the time-critical work of reading the incoming values inside the serial receive ISR, it would prevent that work from being screwed up by other interrupts, and also allow me to do other things besides poll the serial receive all the time.

I'm having trouble getting the ISR to work.  Here's my test code:

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

int receiveroutputenable = 3;  // receiver output enable (pin2) on the max485.  will be left low to set the max485 to receive data.
int driveroutputenable = 4;    // driver output enable (pin3) on the max485.  will left low to disable driver output.
int rxpin = 0;                // serial receive pin on the Arduino, which takes the incoming data from the MAX485.

volatile int index = 0;  //a variable incremented in the ISR and printed in the main routine.


void setup() {
  pinMode(receiveroutputenable, OUTPUT);
  pinMode(driveroutputenable, OUTPUT);
  digitalWrite(receiveroutputenable, LOW);
  digitalWrite(driveroutputenable, LOW);    //sets pins 3 and 4 to low to enable reciever mode on the MAX485.

  pinMode(rxpin, INPUT);  //sets serial pin to receive data

  Serial.begin(250000);  //the baud rate for DMX is 250000bps (since each bit is 4 microseconds).

  UCSR0B |= (1 << RXCIE0);  //sets RXCIE0 in register UCSR0B to 1, to enable USART reception interrupt.

  sei();  //Enable global interrupts
  
}  //end setup()

ISR(USART_RXC_vect){  //the USART receive Interrupt Service Routine
  index++;  //increment index
}

void loop()  {
  Serial.println(index);  //print index.  If the ISR is running, this should increment (although not in lockstep with the ISR).
}

If the ISR(USART_RXC_vect) is firing, it should increment "index" every time.  Then at some point the main code should print out the new value.  However, the serial code just prints out 0's, so I conclude the ISR isn't firing (I'm using Putty to read the incoming values at 250000bps).

Can anyone help me get the ISR up and running?  I'm new to assembly/reading the Atmega168 data sheet, so it's probably something pretty simple.

Thanks for the help!
37  Forum 2005-2010 (read only) / Interfacing / Re: Volume control for HTPC on: June 06, 2009, 05:39:14 pm
btw, welcome to the forums!
38  Forum 2005-2010 (read only) / Interfacing / Re: Volume control for HTPC on: June 06, 2009, 05:38:13 pm
HTPC is home theater pc?

Well, interfacing a potentiometer to the arduino and converting it to a numeric range is easy:

http://www.arduino.cc/en/Tutorial/Potentiometer

You can capture the analog value and either output it on the serial port or using the Ethernet shield, I guess.  The tricky thing will be getting your PC to take that value and control the volume, for that you'll have to write code that runs on your computer, not the arduino.

There has to be an inexpensive commercial solution that will do this for you, if you just want it to work why not do that?
39  Forum 2005-2010 (read only) / Interfacing / Re: Arduino and HM91710A - Generate DTMF! on: June 09, 2009, 02:54:06 am
Ah, I took another look at the datasheet and you're right.  I revise my answer to ^^^  smiley
40  Forum 2005-2010 (read only) / Interfacing / Re: Arduino and HM91710A - Generate DTMF! on: June 08, 2009, 04:50:36 am
I don't think this is the ideal IC for your purpose, because it's set up to receive inputs from a 12-key numeric pad.  To get it to work, you'll have to get the arduino to mimic the electrical behavior caused by the capacitance change that happens when you press one of those buttons.  

I think what you want is an IC that takes something the arduino can talk to easily, like serial, i2c, etc. and converts that to DTMF.

OR... cut out the middleman, and get the arduino to output DTMF directly... I know I've seen threads from other people trying to interface Arduino to DTMF, maybe there's a solution out there that you could adapt.
41  Forum 2005-2010 (read only) / Interfacing / Re: What should I do with all this stuff? Ideas wanted on: May 26, 2009, 11:13:00 pm
I also have old cell phones, and it seems like there ought to be a good way to interface them to the Arduino.  I think you should develop a digital picture frame/greeting card thingy where you could load a picture on the arduino, display it on the screen, and give them to your friends.
42  Forum 2005-2010 (read only) / Interfacing / Re: Non-contact proximity sensor on: June 08, 2009, 04:09:36 am
Just out of idle curiosity, what's this for?
43  Forum 2005-2010 (read only) / Interfacing / Re: Non-contact proximity sensor on: June 06, 2009, 05:40:59 pm
Or capacitive sensing?
http://www.arduino.cc/playground/Main/CapSense
44  Forum 2005-2010 (read only) / Interfacing / Re: Drawdio with arduino? on: June 08, 2009, 04:37:34 am
I would say that it could be done with minimal parts...a few 1Mohm resistors, a speaker of course, and possibly some shielded cable?

What I would do is set up the arduino to receive input on a pin using the capsense library.  You'll get differing levels of capacitance depending on what the pin touches, or how much lead is drawn.  

With that, you'll take the numeric range of returned by the capsense function and output it to frequency, using any of the audio output methods that have been posted, or just banging a pin on and off with the delay between oscillations set by your input.

It will take some fussing to get a good sensitivity range, but could be a really fun project.
45  Forum 2005-2010 (read only) / Interfacing / Re: Annoying sine high pitched sound through speaker on: June 08, 2009, 04:57:57 am
It seems like that should be pretty easily solved by a big old capacitor (>1200uF) across ground and your 12V supply, which would give a ready supply of electrons when the screen switches on and temporarily overwhelms the power supply.  But then from your post I gather you tried that?

Could you post up a schematic?
Pages: 1 2 [3] 4 5