Show Posts
Pages: 1 ... 15 16 [17]
241  Using Arduino / Programming Questions / Re: Why does this work in a .h but not in a .ino? on: January 06, 2013, 04:35:18 am
Code:
void doState1()
{//..some code  same with 2 and 3}
You've commented out the end brace here, // comments out all the text until the next newline, switch it to:
Code:
void doState1()
{
     //..some code  same with 2 and 3
}
The reason it probably works in the header is that you haven't included your header, so it doesn't try and compile it
242  Using Arduino / Programming Questions / Re: Compiling error on: January 05, 2013, 08:26:44 pm
Where did you get the Tone.h file from, I've got the same Tone.cpp, from the Arduino core library, however it doesn't match the Tone.h that you've got, they have completely different functions in them, Tone.h declares a class Tone, which you have been trying to use in your code, but the Tone.cpp files seems to contain a bunch of static functions, and doesn't even include Tone.h, as these are defined in Arduino.h.

Sorry that this doesn't really offer much of a solution, I suppose you've either got to hunt down the cpp file that goes with Tone.h, or use the functions in the arduino library: http://arduino.cc/en/Reference/Tone
243  Using Arduino / General Electronics / Re: Equivalent of a mechanical toggle switch on: January 05, 2013, 05:09:41 pm
What kind of voltages (and current) would be required, If you are just doing logic level (simple on/off) and small currents (no motors!) you could use logic gates, an and gate with your input and control line would work. If you need analogue switching you can get multiplexer/switch ICs, such as: http://uk.rs-online.com/web/p/multiplexer-switch-ics/0307200/ , again you just need to be careful with you max voltage/current.
244  Using Arduino / Programming Questions / Re: How to Print serial results from GPRS shield and GPS Shield with differnet pins? on: January 05, 2013, 02:55:31 pm
I think the problem here is that you are using the hardware serial pins to communicate with your GPRS module (pins 1&2), correct? These pins are the same pins that connect to the USB module, which you are using for your debugging information. The Arduino has one hardware uart module and this connects to both the usb and pins 1&2, you would notice, for example, that if you sent data to your arduino via the usb and looked at the Rx pin (1) on an oscilloscope, you would see the bits as they are sent, you can also put a wire connecting pin 1&2 anything you send from the pc will echo straight back to the pc, as the data comes from the Rx pin, but this is connected directly to the Tx pin, so the data gets sent there as well.
I think you'll either have to use a software serial port for the GPRS sheild or stop using the hardware serial for debugging.
245  Using Arduino / Programming Questions / Re: How can concatenate value in a variable on: January 05, 2013, 01:35:18 pm
The way c handles strings is a bit confusing for beginners. Effectively a string is stored in an array of characters, so the string "hello" is stored as ['h','e','l','l','o',0] (note that single quotes: ' are used to tell the compiler that they are a single characters, and double quotes " are for strings, whch the compiler "converts" into characters for you). When you do x="hello", x is actually the pointer to the first element in the array in the memory. The 0 at the end of the array (it's not the character '0') is called a null byte and tells the program that the string stops there.
When you look at a function like Serial.print, it takes a char* that points to the first character, and then steps through the array processing each character until it reaches a 0 (null byte).

What this means is that if you are trying to join the two strings, "hello" and "there" you need to join the two arrays: ['h','e','l','l','o',0] and ['t','h','e','r','e',0]. There are functions in the library string.h which make it easy to do these kinds of things (look at strcat http://www.cplusplus.com/reference/cstring/) but these libraries can be quite "heavy" (take up alot of the available program memory) so for microcontrollers, some programmers write these kind of simple functions themselves, to save the space of including the whole library.
246  Using Arduino / Programming Questions / Re: Read and send HEX sting by serial on: January 05, 2013, 01:11:11 pm
Have you tried connecting your rs232 shield to the rs232 on your PC. Then do a simple sketch to echo your arduino serial connection over rs232 to check that it's connected up properly. This is to make sure its all connected up properly
247  Using Arduino / Programming Questions / Re: Help if/else on: January 05, 2013, 11:36:20 am
the "goto" instruction is generally frowned upon in high level languages (anything above assembly code really) as it causes alot of problems, particularly for beginners, because of code readability, and sometimes causes unexpected errors. For this kind of code you should use a function call:
Code:
void loop()
{
  if (digitalRead(switchPin) == HIGH)
   {
       knightRider();
   }
  else
  {
    //do something else
  }
}

void knightRaider()
{
    //Stuff here
}
248  Using Arduino / Programming Questions / Re: My project isnt working, its simple.. Help plz on: January 05, 2013, 05:30:53 am
Code:
while(statebutton!=HIGH)
{
  modifyLights();
  statebutton=digitalRead(BUTTON);
  if(statebutton==HIGH)
  {
    untilhere=millis();
    while(statebutton==HIGH)
    {
       statebutton=digitalRead(BUTTON);
    }
    time=millis()-untilhere;
  }
}
There looks to be a bit of a problem here. If your outer while loop is checking that statebutton!=HIGH, then you are pretty likely to leave this loop as soon as it does go HIGH so the if statement: if(statebutton==HIGH) will probably never be reached (unless you are extremely lucky and it happens to change in the loop). Even if you do happen to get the change between entering the while loop and the if statement, your inner while loop will continue until statebutton is low again, and so you won't exit the outer while loop.
Effectively you either go through outer loop indefinitely or you leave it without ever entering the inner loop.
For what (I think) you are trying to do you would need to do:
Code:
while(statebutton!=HIGH)
{
modifyLights();
statebutton=digitalRead(BUTTON);
}

untilhere=millis();
while(statebutton==HIGH)
{
statebutton=digitalRead(BUTTON);
}
time=millis()-untilhere;

Though I'm not sure if this is actually what you want to do, one of the main problems you have with this code is the way that the flow is structured, i.e. the way you step through your code. The way you have written it is:
Code:
while waiting for user input:
    check light level
    if the lights are low: turn on LEDs, use buzzer, display message
    else turn off LEDs
when button has been pressed:
    check how long button is pressed down for
    if it's less than 1200ms turn on an LED, display message
    if it's greater than 1200ms turn off an LED, display message
But this way the user input is what causes the program to continue.
I think what you are trying to do is more along the lines of:
Code:
while light level is high: do nothing
when light level goes low:  turn on LEDs, use buzzer, display message
wait for user input
check how long button is pressed down for
if it's less than 1200ms turn on an LED, display message
if it's greater than 1200ms turn off an LED, display message
This way the routines will be triggered by the light level, and then it will wait for the user input. You can add more advanced logic, for example making that it self-clear when the light goes high again, but this just requires a bit of thought. I would also be a bit careful with the way you check for user input, at the moment if they press the button for less then 800 ms your program doesn't define a state of what should happen, you should add some extra code for this case and loop until your user input is valid.

Hope this helps,

Tobyb121
249  Using Arduino / Programming Questions / Re: Really slow program on: January 04, 2013, 05:24:23 pm
I changed all ints to byte now. is uint8_t better or same??

Yeah, byte and uint8_t are both unsigned char.
250  Using Arduino / Programming Questions / Re: TIMER0_OVF_vect compile error on: January 04, 2013, 05:17:29 pm
I believe the problem is that TIMER0 is used by the Arduino library for the delay, micros and millis functions, if you know you are not going to be using these you may be able to change this by playing around with wiring.c, but this may have unexpected results, particularly if you are planning on using any other libraries.
It is generally better to use one of the other timer/counter modules, they all do slightly different things but from a very quick look at your code I think you've got the right idea. Have a look at the ATMEL ATmega328 datasheet as this goes in to loads of detail on what each timer does.
251  Using Arduino / Programming Questions / Re: How do I give an I2C device an address? on: January 04, 2013, 04:58:09 am
The easiest thing to do is look at the datasheet, this ought to tell you everything you need to know. Some modules have fixed addresses, some have software controlled addresses, some have hardware controlled addresses (where you have a set of pins that determine the address). Datasheets can be very cryptic and it can be a bit of a pain finding what you want, but a search for "address" should help you find what you want.

Tobyb121
252  Using Arduino / Programming Questions / Re: Software serial implementation on: January 03, 2013, 05:27:07 pm
Thanks, for the thoughts and comments, I've actually just got it working, the key was to clear the timer and external interrupt flags in the necesary places.

@PeterH
I've looked through the Software Serial source and it uses interrupts for detecting the start of a byte, but then blocks while it reads each bit, when you have one byte after another it effectively doesn't top blocking.

@Nick Gammon
Now that I've got my software serial working I'm thinking to do this, the reason I had gone for the hardware connection with the PC was that there is quite alot of data going from the arduino to the PC, what I'm thinking to do is use the Tx from the HW UART for sending data to the PC, the HW Rx to the GPS and then use the Software UART for receiving data from the PC. It will probably make the code a bit less readable.

Thanks for your help,

Tobyb121
253  Using Arduino / Programming Questions / Re: Software serial implementation on: January 03, 2013, 10:33:31 am
Thanks for the quick reply, I have looked at reducing the NMEA sentances that are sent, unfortunatly the data sheet is rubbish so I havn't got this to work yet, however I will still need at least the GGA and RMC sentances, which is likely to be around 200 characters, and so will block for about 0.2s, and is still a bit long for me. I think that reducing the sentances will help, but I'm still going to have a problem.
254  Using Arduino / Programming Questions / Software serial implementation on: January 03, 2013, 10:15:41 am
Hi there,

I'm working on a little project then needs to have two serial devices connected to it, it basically reads analog voltages from A0-5, and a gps module connected via a serial port at 9600 baud, does a little bit of processing and sends this data over a second serial port.
The second serial port needs be full duplex, as it is used to also receive control commands from a pc, so I have naturally used the hardware serial port for this. The GPS module therefore needs to be connected using some sort of software UART.
I looked at first at the Software Serial library, but the problem with that is that it from what I can tell from the code, it blocks the processor during receive. The module is fixed at 9600 b/s, a full set of NMEA messages could easily be 4-500 bytes and so this will block the processor for nearly half a second, time that needs to be spent measuring A0-5, which I want to be happening about 10 times a second.

I therefore decided to build my own software serial implementation using an external interrupt on pin 2, and timer1, I know this is a very resource heavy way to do it, but I don't need these functions for anything else so that doesn't concern me.

I've written the code below to test my iplementation, using an uno, with pin 0 (HW UART Rx) connected directly to pin 2. I then just send it characters from realterm and it should echo them back to me. The problem is that it seems to miss the first bit every time, so for example 'a' (B01100001) gets returned as 0xC2,0xFF (B11000010 B11111111) i.e. it reads the start bit as the LSB of 'a' reads bits 0-6 as 1-7 then the last bit, a 0, is recognised as a new byte, then it gets all 1's (no transmission).

I cannot understand at all from my code why it reads the start bit as bit 0, but I've been trying to get it to work for ages now.

Would someone more experienced than myself mind having a look at my code and seeing if they can work out the problem.
I have made this to work with an uno, though I think should work with any 16MHz processor.

Thanks,

Tobyb121

EDIT: One other thing I should mention, in debugging this I added an array that would store value of micros() at each timer interrupt and the initial falling edge, this showed that the first timer interrupt happens about very quickly (<20us I think) after the falling edge, implying that it tirggers immediately after exiting the ext interrupt routine

Code:
#define BUFFER_SIZE 128 //Number of bytes to store in a buffer

byte _i;                //current bit
char _b;                //shift byte to store current byte
char buf[BUFFER_SIZE];  //buffer to store received bytes
byte _ptrRead;          //position in buffer to read from          
byte _ptrWrite;         //position in buffer to write to

int _baud;              //period of each bit in instruction cycles

void initialiseSerial(int baud){
        _ptrRead=0;
        _ptrWrite=0;
  
pinMode(PIN2,INPUT);

_baud=2000000/baud;    //Calculate baud (based on 16MHz processor)
        
SREG|=B10000000;       //Global interrupt enable

        // Setup timer1 to interrupt on overflow, internal clock, 1:8 prescaler
TCCR1A=0;
TCCR1B=B00000010;
TIMSK1=B00000000;

        //External Interrupt enable on pin2 falling edge
EICRA=B00000010;
EIMSK=B00000001;
}

void Timer1InterruptRoutine(){
        // reset timer to trigger in next bit
TCNT1=0xFFFF-_baud;
        
        //if less than eight bytes have been written
if(_i<8){
_b|=digitalRead(PIN2)<<_i;  //read the pin and add it to the temp byte
_i++;
}
else{  //when all bytes have been received
buf[_ptrWrite++]=_b;       //Add the temp byte to the buffer  
TIMSK1=B00000000;          //Switch off the timer
EIMSK=B00000001;           //Re-enable the falling edge interrupt
}

}


ISR(TIMER1_OVF_vect){
Timer1InterruptRoutine();
}

//Fired when falling edge detected on pin 2
void Int0InterruptRoutine(){
        //reset temporary storage variables
_b=0;
_i=0;

        //Disable external interrupt for now
EIMSK=B00000000;

        //Enable timer and set it to overflow in 1.5*baud ticks, in middle of bit0
TCNT1=0xFFFF-3*_baud/2;
TIMSK1=B00000001;
}

ISR(INT0_vect){
Int0InterruptRoutine();
}

// Read a byte from the buffer and increment the pointer
char readByte(){
char b;
b=buf[_ptrRead++];
_ptrRead%=BUFFER_SIZE;
return b;
}

// Check if there are bytes available to read
byte bytesAvailable(){
if(_ptrWrite<_ptrRead)
return _ptrWrite+BUFFER_SIZE-_ptrRead;
else
return _ptrWrite-_ptrRead;
}


void setup()
{
        pinMode(PIN3,OUTPUT);
        pinMode(PIN2,INPUT);
Serial.begin(9600);
initialiseSerial(9600);
}

void loop()
{
if(bytesAvailable())
 Serial.print((char)readByte());  //Continuously check the buffer and write any received bytes to the hardware serial
}
Pages: 1 ... 15 16 [17]