Show Posts
Pages: [1] 2 3 ... 12
1  Forum 2005-2010 (read only) / Troubleshooting / Re: What is this interrupt code doing? on: October 11, 2009, 08:45:24 pm
Thanks groovy, sorry I know nothing about timers and interrupts, I'm trying to learn, it was pretty obvious though I guess.  So once I've adjusted the prescaler up to 1024 If I wanted to go down in ms from there I can either lower the TCNT2 value or lower the prescaler.
2  Forum 2005-2010 (read only) / Troubleshooting / Re: What is this interrupt code doing? on: October 11, 2009, 03:10:46 pm
Hmmn, his result is correct but his maths uses 107 not 106  There are 7 zeros in his comment.

Ok, well at least I know that the timing is as he thinks it should be and what the maths should be.  Still don't know how to extend the timer past 4ms segments.
3  Forum 2005-2010 (read only) / Troubleshooting / What is this interrupt code doing? on: October 10, 2009, 06:58:30 pm
Hi All, I've got a couple of LCD shields, one grpahics colour the other 16x2 LCD, both use a voltage divider to allow a set of buttons/joystick to be read on a single analog pin.  They both come with example code that uses the same technique to read the keys, I think i know whats going on roughly but I'm wondering if it's the right way to do things or not, could someone look over the intterupt code and suggest a better or alternative way to read for a button press from an analog pin?

Code:
// this is defined pre setup()
void InitPort(){
  DDRB=0x2F;
}

// then in setup:

  // Setup timer2 -- Prescaler/256
  TCCR2A &= ~((1<<WGM21) | (1<<WGM20));
  TCCR2B &= ~(1<<WGM22);
  TCCR2B = (1<<CS22)|(1<<CS21);      

  ASSR |=(0<<AS2);

  // Use normal mode  
  TCCR2A =0;    
  //Timer2 Overflow Interrupt Enable  
  TIMSK2 |= (0<<OCIE2A);
  TCNT2=0x6;  // counting starts from 6;  
  TIMSK2 = (1<<TOIE2);    



  SREG|=1<<SREG_I;

  InitPort();

// then at the end of loop and after all the other functions defined in the rest of the code the interrupt routine code:


// Timer2 interrupt routine -
// 1/(160000000/256/(256-6)) = 4ms interval
ISR(TIMER2_OVF_vect) {  
  TCNT2  = 6;
  update_adc_key();
}


The = 4ms is the maths in the example code not mine but I get 400microseconds not 4ms, is that right?
I think it basically counts 256*256*6 clk cycles, 400microseconds and then runs the update_adc_key() function, isn't that spamming the hell out of the processor?  Would I at least be better putting bounce code in here so it only reads every 20-50ms?  Or how can I increase the time so it counts longer?  I tried increasing TCNT2 value in the equation but my numbers got smaller so I'd rather be accurate than guess whats going on here....

I'm really not sure where the original coder is deriving all the numbers for his "1/(160000000/256/(256-6)) = 4ms interval" maths,  I think i understand this much, 1/160000000 = 1 clock cycle, /256 is the prescaler?  not sure where the /(256-6) comes from, CKDIV? which then leads on to the question does that 4MS/400microseconds rely on my fuse settings matching what the original coder had set for his particular chip?


Also, what exactly happens to this/any interrupt when a function uses delay()? does the delay have to finish before the interrupt can react or do counters/interrupts stop?
4  Forum 2005-2010 (read only) / Troubleshooting / Re: arduino 0017 menu (java issue??) on: September 01, 2009, 09:51:04 am
I'd resubmit the bug with the fix as it's clearly not a graphics card issue.
5  Forum 2005-2010 (read only) / Troubleshooting / Re: arduino 0017 menu (java issue??) on: August 31, 2009, 04:52:41 pm
Sorry it didn't help, it seems arduino/processing have some issues to resolve.
6  Forum 2005-2010 (read only) / Troubleshooting / Re: arduino 0017 menu (java issue??) on: August 30, 2009, 08:05:17 am
Take a look here and see if anything helps...
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1251634999

don't forget to backup your original arduino\java folder first.
7  Forum 2005-2010 (read only) / Troubleshooting / Arduino 17, vista and java issues (resolved) on: August 30, 2009, 07:23:19 am
Hi all, This is a bit of a mad post, I've just fixed the issue that I'm posting about but as I don't see the solution here I'm going to post my issue and solution for the greater good.  

I'm using arduino 17 and it seems to be having java issues like arduino 16 did (disables aero, runs like a dog, makes the PC run like a dog), I've just resolved the arduino 16 issues by renaming the arduino\java to arduino\javaold, unfortunately this method doesn't work for arduino 17, I get the splash screen and nothing else, no hung processes it just doesn't start.

My Java is completely up to date (32bit and 64bit) I'm running vista 64bit.  I'm running a core i7 920 w/6GB of ram, can someone please make it look better than a PIII 800? smiley-grin

Ok, so here's the fix:
1. make sure your Java is up to date, it would appear that arduino 17 is using 32bit Java.

2. goto your arduino install folder and rename the java folder to javaold, that way if there are any issues you can at least use it in slow mode!

3. make a new folder called java

4. for vista64 go to C:\Program Files (x86)\Java\jre6 and copy the 2 folders, lib and bin and paste them into the java folder you just made in the arduino folder

5. Run arduino 17 and your PC at full tilt, wahay  ;D

Regards,
Reggie.
8  Forum 2005-2010 (read only) / Bugs & Suggestions / Re: Stepper library with half-steps on: November 08, 2009, 05:53:56 pm
Nice addition John_NL, Works well, for anyone else trying this you need to remember when declaring the stepper object to double the original step number otherwise it will 'jump' on certain steps.  so if you usually declare:
Stepper myStepper = Stepper(20,2,3,4,5);

for half stepping it should now be:
stepper MyStepper = Stepper(40,2,3,4,5,1);
9  Forum 2005-2010 (read only) / Syntax & Programs / Re: LCD/KEY/Temperture code help on: October 09, 2009, 12:01:25 pm
You're welcome, I'm a bit of a n00b too but the millis()-previousmillis code is the first thing they teach you round here smiley you can declare as many previousmillis type variables as you like  and use them in the same manner for doing things at different times and still keeping the code responsive.  I take it
10  Forum 2005-2010 (read only) / Syntax & Programs / Re: LCD/KEY/Temperture code help on: October 09, 2009, 11:32:46 am
Hi, you could try this:

Code:
//example use of LCD4Bit_mod library

#include <LCD4Bit_mod.h>
#include <stdio.h>

#define TEMP_PIN 3
//create object to control an LCD.  
//number of lines in display=1
LCD4Bit_mod lcd = LCD4Bit_mod(2);

void getCurrentTemp(char *temp);

//Key message
int  adc_key_val[5] ={30, 150, 360, 535, 760 };
int NUM_KEYS = 5;
int adc_key_in;
int key=-1;
int oldkey=-1;
unsigned long previousmillis;
char temp_string[10];

As you can see I have added previousmillis and moved temp_string[] to your declaration section.

Now for setup:

Code:
void setup() {
 pinMode(13, OUTPUT);  //we'll use the debug LED to output a heartbeat

  // initialize DS18B20 datapin
   digitalWrite(TEMP_PIN, LOW);
   pinMode(TEMP_PIN, INPUT);      // sets the digital pin as input (logic 1)
 lcd.init();
 //optionally, now set up our application-specific display settings, overriding whatever the lcd did in lcd.init()
 //lcd.commandWrite(0x0F);//cursor on, display on, blink on.  (nasty!)
  lcd.clear();
 lcd.printIn("Temperature is");
 previousmillis = millis();
}

Again, I've just added a single line of code to setup the previousmillis variable to test for time in the main loop.

and finally your void loop:

void loop() {

  if (millis()-previousmillis>1000){
     previousmillis=millis();
     getCurrentTemp(temp_string);
     lcd.cursorTo(2, 0);  //line=2, x=0
     lcd.printIn(temp_string);
 }
}

all it does it check the time millis() against the last time the loop ran (previousmillis) and a 1000ms difference, if the condition is true it will grab the temperature.

You could have just had your getCurrentTemp and lcd.cursor/print statements and added a delay(1000); statement but using the previousmillis method means that your arduino can get on and do other things while it waits for that second toi pass.



11  Forum 2005-2010 (read only) / Syntax & Programs / Re: Print data from Serial port to LCD on: September 23, 2009, 04:45:52 am
Ribuck, are you reading the data from EQMod or from the skywatcher(celestron) firmware?  If its EQMod ask them what they use as a terminatiing character when they send out the mount position data.

Does the data always come through in that format?  123.4567891?  for instance, I believe you are reading 0-360?  would 0.1234567 come through as 000.1234567?  this would make things easier cos you just buffer the first 6chars smiley  or you could look for the .(decimal point) and buffer 2 further characters.  Trouble is, I don't see anywhere in your code that you are looking for a byte that tells you what type of data is coming, from the actual serial device is there anything that is displayed before the numbers?

Once you have the data are you just displaying it to the LCD or do you need to do some stuff to the value once its on the arduino?  I think you are taking position data and then using it to match the position on something else?  if thats the case then it would seem that you really need to buffer the data, convert it to a real float then you can do what you like with it.
12  Forum 2005-2010 (read only) / Syntax & Programs / Re: Print data from Serial port to LCD on: September 21, 2009, 07:10:39 pm
The setCursor function should be called outside the serial buffering loop, otherwise it will just display all of the characters at position 0,0 so they will all have been printed to the screen, but you only see the last one, the ? .  My bad, I should've said.
13  Forum 2005-2010 (read only) / Syntax & Programs / Re: Print data from Serial port to LCD on: September 21, 2009, 05:26:04 pm
if you want to move the cursor to 0,0 (Char1, Line 1) then use the setCursor command:

lcd.setCursor(0,0);
lcd.print (TestData);
lcd.print("      "); // just to clear any data left on screen from previous reading.



make sure that somewhere in setup after you have declared the lcd that you do a lcd.begin(16,2); or however many chars/lines your LCD is.

I'm guessing that you want to use the float value once you've displayed it to the LCD?  If so then you will really need to buffer the data to a string then convert the string to a float.
14  Forum 2005-2010 (read only) / Syntax & Programs / Re: Print data from Serial port to LCD on: September 21, 2009, 03:37:52 am
Hi Ribuck, take a look at this page:
http://itp.nyu.edu/physcomp/Labs/SerialDuplex#toc7

It does a lot of explaining about how to do what you are asking, you might want to take a look at section 7, call and response.
15  Forum 2005-2010 (read only) / Interfacing / Re: Receiving multi-character serial data on: October 26, 2009, 10:30:37 pm
Awol, We're having exactly the issue you describe in our stepper control code.

I understand why it will fail without the delay but I'm trying to understand why it needs a >20ms delay to work correctly. if its 9600bps thats (1/9600)*8 = 0.00083s <1Ms, for the time it takes a byte to arrive at the arduino? increasing the baud rate for serial comms reduces the length of the delay needed but that obviously isn't a fix, just confirms that our code sucks slighly faster at higher baud rates.

So the code in void loop() is running faster than that hence getting a -1 as it hits between bytes but why does it need more than 20ms delay to get 5 chars.  In our case 5 chars is the smallest string we send, longest string is probably a buffer full, we don't check, mainly as its not that important as our release software will be usually sending just a single command+optional data string, but random length multiple command strings are very useful while I debug and could springboard another project that they would be very useful in.

Would it be legitimate for me to use something like:

if (Serial.available() > 4)

before we start to process the serial buffer? or am I hoping that by the time its processed the command string, the data portion  of the command (if it exists) will have arrived?

Our command strings take the following form, where nnnnn = 0 to 16384
Code:
:POS:nnnnn;
:SPD:nnnnn;
:STP:nnnnn;
:LMT:nnnnn;
:IN1:n; // already padded to keep the commands to 3 bytes
:OUT:n;

IN1 and OUT don't actually need a value unless you are sending a multiple command string like this:

Code:
:spd:1000;:lmt:16000;:stp:500;:in1:0;:stp:50;:out:0;:stp:60;:out:0;

We know why in and out fail with the 0; ommited, because we still check for a value which kills the string as it reads the next command in while it hunts for a ; to finish the last command, that's fine we'll fix that in a bit by moving the call to the 'get the value for the command' function into the commands that actually require a value.

some of our code:

Code:
void loop() {
  
  
  int bCommandReady = false;

  //If There is information in the Serial buffer read it in and start the Build command subroutine
  if (usingSerial && Serial.available() > 0) {  // I expect to change this to
    // read the incoming byte:
    incomingByte = Serial.read();
    /* Build a new command. */
    bCommandReady = cliBuildCommand(incomingByte);
  }


delay(100);  // with this lower than 20ms our code goes sporadic, the lower you go it fails (as explained by awol)
  //If there is a command in the buffer then run the process command subroutine
  if (bCommandReady == true) {
    bCommandReady = false; // reset the command ready flag
    cliProcessCommand(); // run the command
  }

  if (UPDATE){
    UPDATE=false;
    FocusPrintStepsFun(); //Print the number of steps
    FocusPrintPositionFun(); //Print the Position
    SerialDATAFun();  // debug mainly, gives detailed information about the current state of the machine

  }

}

and the command/data building functions:

Code:
//Process Command. This searches the command table to see if the command exits if it does then the required subroutine is run
void cliProcessCommand(void)
{
  int bCommandFound = false;
  int idx;

  /* Convert the parameter to an integer value.
   * If the parameter is emplty, gParamValue becomes 0. */
  gParamValue = strtol(gParamBuffer, NULL, 0);

  /* Search for the command in the command table until it is found or
   * the end of the table is reached. If the command is found, break
   * out of the loop. */
  for (idx = 0; gCommandTable[idx].name != NULL; idx++) {
    if (strcmp(gCommandTable[idx].name, gCommandBuffer) == 0) {
      bCommandFound = true;
      break;
    }
  }

  /* If the command was found, call the command function. Otherwise,
   * output an error message. */
  if (bCommandFound == true) {
    (*gCommandTable[idx].function)();
  }
}


//When data is in the Serial buffer this subroutine is run and the information put into a command buffer.
// The character : is used to define the end of a Command string and the start of the parameter string
// The character ; is used to define the end of the Parameter string
int cliBuildCommand(char nextChar) {
  static uint8_t idx = 0; //index for command buffer
  static uint8_t idx2 = 0; //index for parameter buffer
  int loopchk = 0;

  nextChar = Serial.read();
  do
  {
    gCommandBuffer[idx] = TO_UPPER(nextChar);
    idx++;
    loopchk=loopchk+1;
    nextChar = Serial.read();

  }
  while ((nextChar != ':') && (loopchk < 6));

  loopchk=0;

  nextChar = Serial.read();

  do
  {

    gParamBuffer[idx2] = nextChar;
    idx2++;
    loopchk=loopchk+1;
    nextChar = Serial.read();
  }
  while ((nextChar != ';')&& (loopchk < 5));



  gCommandBuffer[idx] = '\0';
  gParamBuffer[idx2] = '\0';
  idx = 0;
  idx2 = 0;

  return true;
}
Pages: [1] 2 3 ... 12