Show Posts
Pages: [1] 2
1  Using Arduino / Programming Questions / Re: Serial Write/Read- How to avoid missing a read without sacrificing the loop on: November 22, 2012, 08:47:14 pm
Quote
How does this look for what I am trying to accomplish?
Lousy. Why are you using a String?
I don't know. That is what the code I took from originally had. What would be better? Unsigned long? Will that allow data which is separated by colons?
Quote
Code:
  while (Serial.available()){
    char incomingByte = (char)Serial.read();
   
     command += incomingByte;
      return;
    }
As long as there is serial data to read, read one character and return. Why?
I realize now that the previous gentleman was using it to find his ! and @ which indicated start and end.

would it be better if I did this?

Code:
void serialEvent(){
  while (Serial.available()){
    int incomingByte = Serial.read();
 
    }
  }

Quote
Code:
  int data[2]; // up to three integers of data
How do you intend to fit three integers into a two element array?
does it not start at 0? 0,1,2 is three?
Should I change it to int data[3]

Quote
You shouldn't be calling handleCommand() until you know you have a command to handle.

So are you suggesting that I write a command that says "when handleCommand is finished, send a "true" value"  which is then used to compare data[0] and data[1]?

2  Using Arduino / Programming Questions / Re: Serial Write/Read- How to avoid missing a read without sacrificing the loop on: November 22, 2012, 08:31:37 pm
I found some reference to the strtok command and after some searching I found a previous thread which I took some code from.

How does this look for what I am trying to accomplish?

Code:

String command; // hold the incoming command

void setup(){
  Serial.begin(115200);
}

void loop(){
 
  Serial.print ("?V");
  handleCommand();
 
  if (data[0] > data [1]){
    dosomething;
  }
 
}

void serialEvent(){
  while (Serial.available()){
    char incomingByte = (char)Serial.read();
   
     command += incomingByte;
      return;
    }
  }


void handleCommand() {
 
  // variables to hold the command id and the command data
  int id;
  int data[2]; // up to three integers of data
 
  char cmd[command.length()+1];
  command.toCharArray(cmd, command.length()+1);
  char *token = strtok(cmd, ":");
 
  // id
  if (token) {
    id = atoi(token);
    token = strtok(NULL, ":");
  }
 
  // data 
  for (int i = 0; i < 3; i++) {
   
    if (token) {
      data[i] = atoi(token);
      token = strtok(NULL, ":");
    }
   
  }
 
}
3  Using Arduino / Programming Questions / Re: Serial Write/Read- How to avoid missing a read without sacrificing the loop on: November 22, 2012, 06:02:08 pm
Quote
The question would be how the controller treats the voltage if it goes below 10v... I.E. 4.2 volts as (042 or 42)

Have you tried connecting it to a battery that outputs less than 10v to see the result? The controller may have a limited voltage span for various reasons.

I don't have the controller yet. I am trying to write as much of the code before I receive it.

The battery supply is limited to 10V, but obviously the motor voltage could be as low as 0.

4  Using Arduino / Programming Questions / Re: Serial Write/Read- How to avoid missing a read without sacrificing the loop on: November 22, 2012, 05:52:56 pm
Quote
inside of voltagedrv is the voltage level of the motor. when I send the controller the command ?V 1, the controller reports the current value.
No. voltagedrv contains the number of characters you just wrote to the serial port. I fail to see how that information is useful.

Paul,
I appreciate you taking your time to help with my issue, but its obvious that I am not very knowledgeable with programming. I think it would be more beneficial for both of us if there was more explanation, rather than telling me that the my information is not useful. I know that a lot of people come onto this forum wanting others to program their projects for them, but in my case I honestly want to learn. Have a happy thanksgiving. Thanks
5  Using Arduino / Programming Questions / Re: Serial Write/Read- How to avoid missing a read without sacrificing the loop on: November 22, 2012, 05:45:28 pm
You need to know a bit more about the data coming back. Is it a string separated by : ? If so do you know how long that string is? That is how many bytes long. If so then you need to wait untill they are all in, tat is the serial avaliable shows that there are at least that many bytes in the buffer. You can then read them back either into each byte if the string or assemble them into the two or three variables that the reply contains.
Do some tests and find out if this is not documented.

It probably would have been smarter to just show you the entire example. This is from the documentation.

Where:
vdr= internal voltage in Volts *10
vmot= main battery voltage in Volts *10
v5out = 5V output on DSub connector in millivolts
Examples:
Q: ?V
R:V=135:246:4730
Q: ?V 3
R:V=4730

The question would be how the controller treats the voltage if it goes below 10v... I.E. 4.2 volts as (042 or 42)

Thanks for the input so far Mike
6  Using Arduino / Programming Questions / Re: Serial Write/Read- How to avoid missing a read without sacrificing the loop on: November 22, 2012, 03:37:59 pm
Unless the responder can tag the data some way the only way to do it is to send a request and then enter a loop that constantly checks if there is data avaliable then read that data. The repeat for the next data you want.

This is the command.

Syntax: ?V [cc]
Reply: V=vdr:vmot:v5out

Instead of sending one for each the motor(dr) and the battery(mot), is there a way to tell the arduino which one (1:2:3)?   I assume its something along the lines of the array function?
7  Using Arduino / Programming Questions / Re: Serial Write/Read- How to avoid missing a read without sacrificing the loop on: November 22, 2012, 03:23:40 pm

You are wrong. You will never miss a read, it sits in the buffer until you collect it. You must use serial Avaliable to check it has arrived before trying to read it.


I was actually just reading this as you posted. That is helpful thanks.

If the serial response is a different value each time, is there a way to mark it so that I know which value belong to which request?

I.e. if I'm asking it for two different voltages, how do I know which is which in the buffer?
8  Using Arduino / Programming Questions / Re: Serial Write/Read- How to avoid missing a read without sacrificing the loop on: November 22, 2012, 02:52:54 pm
Can you look at my attempt and advise on how to do this properly?

Decide how often you want to read the values.

In loop(), use the technique demonstrated in the 'blink without delay' example sketch to send a request for a value at regular intervals. Use a flag to record which variable you requested last time, so you can alternate them. In loop(), test whether a response is available; when it is, read the response and store it. The flag tells you which value the response contains.

If you want to do anything else within loop() other than read these values, then add code to do it. Make sure that none of the code you add does anything that stops (blocks) the execution of loop() - it should be designed as above to detect when something needs to be done and do it, rather than stop and wait with a delay().



Thanks Peter. This sounds like something I am looking for. I will look into it and report back.
9  Using Arduino / Programming Questions / Re: Serial Write/Read- How to avoid missing a read without sacrificing the loop on: November 22, 2012, 02:52:05 pm

Strange set of priorities. If reading serial data is higher priority, then it should be able to interrupt loop. If not interrupting loop() is more important, then reading serial data is NOT first priority.

So, which is it?

The wording might not have been clear, but since I am using a bank of ultracapacitors, overvoltage is not an option, therefore I need the arduino to accurately read what the voltage is at the beginning of each loop.

Quote
Why not? Haven't you looked at the documentation/measure it?

The controller runs the serial connection at 115200 bit/s. I do not know exactly how it relates to my situation

Quote
Here's a hint. It's nowhere near that fast.

99.9% of the time, voltagedrvread will be -1. Not likely what you want.

What do you think is in voltagedrv? Why is that important?

inside of voltagedrv is the voltage level of the motor. when I send the controller the command ?V 1, the controller reports the current value.

Quote
Why would you have a delay to read serial data?

Its my only understanding on how to capture the controllers response without missing it.
10  Using Arduino / Programming Questions / Serial Write/Read- How to avoid missing a read without sacrificing the loop on: November 22, 2012, 01:38:43 pm
I am using the arduino to talk to a robot controller.
It's critical for me to know at all times what the voltage of both the motor and battery is so that I can initiate certain commands.
The robot controller can send and receive serial commands, hence me using the arduino to probe it.

My question pertains to how I can know these values at all times at 1st priority, but not interrupt what else is happening in the loop. I don't know how quick the robot controller can send back values and do not want to use a delay to slow down the other processes in the loop.

Can you look at my attempt and advise on how to do this properly?

Code:
void loop () {
  int voltagedrv = Serial.write(?V 1); // ask robot controller for motor voltage
     int voltagedrvread = Serial.read();  // read response
  int voltagebat = Serial.write(?V 2); // ask robot controller for battery voltage
     int voltagebatread = Serial.read();  // read response
 
  if( voltagedrvread < voltagebatread ){   // if battery voltage is greater than motor voltage do something
    doSomething;
  }
  else if ( voltagedrvread => voltagebatread){  // if motor voltage is equal or greater than battery voltage do something else
    doSomethingelse;
  }
}





Thanks!
11  Using Arduino / Programming Questions / Re: Using a mapped value which is then ramped analog output on: November 20, 2012, 07:56:43 pm
Thanks! I'm happy to have solved it mostly myself.

Can you explain the purpose of byte and unsigned long?

They're other types of integers. in an arduino (it changes), an int is two bytes; a byte is one byte; and a long is four bytes. `unsigned' means it will never be negative, so instead of representing (for a 1 byte number for example) -128 to 127, an unsigned byte can represent 0 to 255.

unsigned long is the type returned by millis() so it should be used for variables storing the time.
byte is the shortest possible value so I used it to save memory because it can only be HIGH or LOW anyway

Your description makes sense. Thanks.

Now, I was trying to understand how to simplify my "if else if" statements into an array as previously advised. I will have multiple switches with plenty of options for each, and for the sake of code speed, I will need to minimize what happens in each loop.

Can you help me make sense of how to apply the array to an output with multiple possibilities? Also, the idea of having the arduino check if the switch has moved and if it hasn't avoiding that part of the loop in entirety.

I have tried to search beyond the basic description of array, but I can't find the proper wording.
12  Using Arduino / Programming Questions / Re: Using a mapped value which is then ramped analog output on: November 20, 2012, 05:47:39 pm

That's about what I guessed. Try implementing what I described in the last two paragraphs of my post and come back with questions about how to do so

This is my first attempt at the code.
How does it look?
That looks really good! Just a few tips and it should work great. I modified it a little
Code:
void loop () {
  static unsigned long startButtonPressTime;
  static byte lastButtonState = LOW;
  int pwr;
  byte buttonState = digitalRead(button);

  if (buttonState == HIGH) {
    if (lastButtonState = LOW) {
      startButtonPressTime = millis();
    }
    else {
      pwr = map(millis() - startButtonPressTime, 0, 1000, 0, 255);  // after 1 second give full pwm output
    }
  }
  analogWrite(3, pwr);

  lastButtonState = buttonState;
}

Thanks! I'm happy to have solved it mostly myself.

Can you explain the purpose of byte and unsigned long?
13  Using Arduino / Programming Questions / Re: Using a mapped value which is then ramped analog output on: November 20, 2012, 12:12:37 pm

?
14  Using Arduino / Programming Questions / Re: Using a mapped value which is then ramped analog output on: November 20, 2012, 08:20:13 am

That's about what I guessed. Try implementing what I described in the last two paragraphs of my post and come back with questions about how to do so

This is my first attempt at the code.
How does it look?

Code:
void loop () {

if (button == HIGH && time <= millis() ){

int time = millis();

}

else if (button == HIGH && time > millis() ){

int buttontime = millis()-time;

ramp = map(buttontime, time, 1000, 0, 255);  // after 1 second give full pwm output

}

else if (button == LOW) {

time = 0;

}
15  Using Arduino / Programming Questions / Re: Using a mapped value which is then ramped analog output on: November 20, 2012, 06:47:53 am
You're using a lot of words like "inject" and "ramp" which don't make a lot of sense, so let's try to be clear: the map function takes several arguments, does some math, and returns a value.

Second, you're saying you want to make a button output a voltage, which doesn't make sense either -- buttons are inputs.

So what I think you mean:
You want to make a project that reads a button and outputs a voltage if the button is pressed (if it's not pressed, output 0 volts). The voltage depends on how long the button has been pressed; increasing as it has been held longer.

If that's so, you'll want to make it so that when the button was not pressed last time but was pressed this time, it resets a clock (or sets a variable to now). Then you want to map the elapsed time (now - the stored time) into a voltage that you feed to analogWrite.

now can be figured out using the millis() command. You can use a variable declared as static to keep a variable (such as the time when the button was first pressed) between iterations of a loop. The rest I think you know how to do.

Sorry, it's hard to type as it makes sense in my head  smiley-lol
Ultimately I am sending signals to a robot controller and using a on/off switch to control a motor. I am using the adjustable map values to vary my maximum power and the "ramp" to have a smooth motor application. I know it sounds like a complicated effort, but its all for good reason.

so to sum up,
I want to make a project which reads a button digitally, and outputs a "progressive" voltage.
In order to output to analog we have to map it, so a button LOW = 0 HIGH = 255 (or whatever number I choose)
But instead of it being just 0 or 255, I would like it to climb from 0 to 255 over a set period of time or loops. You could call it ramp, fade, etc.

Is this any clearer? Sorry for the confusion.

That's about what I guessed. Try implementing what I described in the last two paragraphs of my post and come back with questions about how to do so

Yes your right. I realize now this morning that your approach is applicable. Is it more efficient to do it with a for loop count since we are talking about a 0.1 to 1 second "ramp" , or is still best to do as you suggest and use the internal clock? 
Pages: [1] 2