HELP! diploma project - problem with my program regarding analogWrite();

Hi guys,

First of all dont blame me for my english writing skills. its not my native language. thx :slight_smile:

So... I am currently doing my diploma project.
Therefore i am writing a program for my arduino-board which should controll two motors in the end.

So far the calculations in my program and serial communication works fine.
The only problem i have is that a calculated value i want to write on a pin (analog) does not work.

But it only does not work with the calculated value (pins is always LOW) tho the value is not 0.

First i thought the problem is that the value is not declared as volatile... changed that without any better results
Now i think it has something to do with pointers.

// configuration of engine control
// via ISR using CTC - every 1 ms read/write

// ~Bachler Sebastian~

// include
#include <avr/interrupt.h>

// values
struct values{
  volatile int sensval_atm;      // sensorvalue at the moment
  volatile int sensval_old;      // sensorvalue one cyclus before
  volatile int sensvalDif_atm;   // difference between sensorvariable old and atm at the moment
  volatile int sensvalDif_old;   // difference between sensorvariable old and atm one cyclus before 
  volatile int outputval;        // digital ouput value (allready considering aceleration of potentiometer)
  
  volatile float multiplier;     // factor rising/lowering the resistance
  
  volatile int power;            // current motor power
  volatile int angle;            // current vertical angle
  volatile float velocity;       // pull velocity
  volatile float acceleration;   // pull acceleration
  volatile float frequency;      // pull-frequency in time between each pull
  
  // input pins
  const int horizontal; // horizontal potentiometer input = angle horizontal
  const int vertical;   // vertical potentiometer input = angle vertical
  
  // output pins
  const int idle;       // select the pin for the (red LED) - idling
  const int pull;       // select the pin for the (green LED) - pulling
  
  // enable pins
  const int ena;
 
  // identifier 
  const char ident;
  
  // variables too choose if printing data is necessary
  volatile int   power_old ;
  volatile float angle_old;
  volatile float horizontal_old;
  volatile float velocity_old;
  volatile float acceleration_old;
  volatile float frequency_old;
  
  // variable needed because YEAH
  boolean pulled;
};
  // initialisation
  values left   = {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, A7, A6, 2, 3, 6, 'a', 0, 0, 0, 0, 0, 0, false};  // values left
  values right  = {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, A5, A4, 4, 5, 7, 'A', 0, 0, 0, 0, 0, 0, false};  // values right

// engine control
void ec(struct values & val){ 
  
  // enable
  digitalWrite(val.ena  , HIGH); 
  
  // sensor input
  val.sensval_atm  = analogRead(val.horizontal);
  val.angle        = analogRead(val.vertical);
  val.multiplier   = val.multiplier + analogRead(A3)/1000;
  
  // calculations
  val.sensvalDif_atm = val.sensval_old - val.sensval_atm;
  val.acceleration = val.sensvalDif_atm - val.sensvalDif_old;  

  
  // motor off
  if(val.sensval_atm > val.sensval_old || val.angle > 40) {
    val.outputval = 0;
    Serial.println(val.outputval); 
    analogWrite(val.pull  , val.outputval);   
    digitalWrite(val.idle  , LOW);  
    val.frequency = millis();
    if(val.pulled == true) {
      val.frequency = millis() - val.frequency;
      val.pulled = false;
    }
  }
  
  // motor on  
  if(val.sensval_atm < val.sensval_old && val.angle < 40) {
    val.pulled = true;
    digitalWrite(val.idle, LOW);  
    // acceleration +
    if(val.sensvalDif_old < val.sensvalDif_atm) {
      val.outputval += val.acceleration*val.multiplier; 
      Serial.println(val.outputval); 
      val.outputval = 20;
      analogWrite(val.pull, val.outputval);
    }
    // acceleration -
    else {
      if(val.sensvalDif_old > val.sensvalDif_atm) {
        val.outputval += val.acceleration*val.multiplier;
        if(val.outputval < 0) val.outputval = 0;
        Serial.println(val.outputval); 
        analogWrite(val.pull, val.outputval); 
      }
      // constant movement
      else {
        Serial.println(val.outputval); 
        analogWrite(val.pull, val.outputval);
      }  
    } 
  }
  
      //---[DEBUGGING]---
      Serial.println(left.outputval);
      //---[DEBUGGING]---
      
  // set atm-values to old-values for next cyclus
  val.sensval_old    = val.sensval_atm;
  val.sensvalDif_old = val.sensvalDif_atm;
}

void echo(struct values & val){
  
  // serial output
  if(val.power != val.power_old)
  {
    char ident = val.ident;
    Serial.print(ident);       
    Serial.print(val.power);   // power (0-255)
    val.power_old = val.power;
  }
  
  if(val.frequency != val.frequency_old)
  {
    char ident = val.ident+1;
    Serial.print(ident);        
    Serial.print(val.frequency);  // frequency (time between each pull)
    val.frequency_old = val.frequency;
  }
  
  if(val.angle != val.angle_old)
  {
    char ident = val.ident+2;
    Serial.print(ident);        
    Serial.print(val.angle);  // vertical angle (0-1023)
    val.angle_old = val.angle;
  }
  
  if(val.sensval_atm != val.horizontal_old)
  {
    char ident = val.ident+3;
    Serial.print(ident);        
    Serial.print(val.sensval_atm); // horizontal angle (0-1023)
   val.horizontal_old = val.sensval_atm; 
  }
  
  if(val.sensvalDif_atm != val.velocity_old)
  {
    char ident = val.ident+4;
    Serial.print(ident);        
    Serial.print(val.sensvalDif_atm);  // horizontal speed (0-1023)
    val.velocity_old = val.sensvalDif_atm;
  }
  
  if(val.acceleration != val.acceleration_old)
  {
    char ident = val.ident+5;
    Serial.print(ident);        
    Serial.print(val.acceleration);  // horizontal acceleration (0-1023)
    val.acceleration_old = val.acceleration;
  }
}

// ISR
ISR(TIMER3_COMPA_vect) 
{ 
  // enginge control functions
  ec(left); 
  ec(right); 
  // echo
  Serial.println();
  Serial.print("T");               
  Serial.print(millis());  // runtime
  echo(&left);
  echo(&right);
}

void setup(){ 
    // turning on interrupts
    sei();
    // using timer 3 (16 bit)
    // setting zero
    TCCR3A = 0;
    // setting zero
    // setting prescaler to  1/1 
    // WGM to CTC
    TCCR3B = 0;
    TCCR3B |= _BV(CS30) | _BV(WGM32); 
    // set compare
    OCR3A = 16000;
    // on compare interrupt A running
    TIMSK3 |= _BV(OCIE3A);
    // set pins
    pinMode(left.idle , OUTPUT);
    pinMode(left.pull , OUTPUT);
    pinMode(left.ena  , OUTPUT);
    pinMode(right.idle, OUTPUT);
    pinMode(right.pull, OUTPUT);
    pinMode(right.ena  , OUTPUT);
    // turn all pins off
    digitalWrite(left.idle , LOW);  
    digitalWrite(left.pull , LOW);
    digitalWrite(right.idle, LOW);  
    digitalWrite(right.pull, LOW);
    // preset value for calculations
    left.sensval_old   = analogRead(left.horizontal);
    right.sensval_old  = analogRead(right.horizontal/);
    // begin serial communication at 9600 bits of data per second  
    Serial.begin(9600);
} 

void loop(){
}

so far the whole code

Now always when i am trying to do analogWrite(val.pull, val.outputval); the pin val.pull keeps beeing LOW tho val.outputval is not constantly 0. (changes by movement of potentiometer)

When i write analogWrite(val.pull, 255); or any other value it works perfectly... only when i want to write val.outputval it does not work :confused:

I really need to solve this problem till 02.05!

Any ideas?

greets
Sebastian

Which actual pin numbers are you calling analogWrite with? only pins 3,5,6,9,10,11 support PWM - your code doesn't make it easy to tell...

ISR(TIMER3_COMPA_vect) 
{ 
  // enginge control functions
  ec(left); 
  ec(right); 
  // echo
  Serial.println();
  Serial.print("T");               
  Serial.print(millis());  // runtime
  echo(&left);
  echo(&right);
}

Is there some part of "ISRs must be fast" that you don't understand. Serial.print() is NOT fast, and has no place in an ISR.

The ec() and echo() functions are loaded with Serial.prints(), too.

@MarkT
yes i am only using the pwm pins

@PaulS
i do understand but thats not my problem sir!

backt to topic..

any idea why val.outputval is not wirtten out to the pins?

greets
sebastian

Perhaps you could humor us, and make your ISR behave properly (FAST! FAST! FAST!) and see if your problem persists. My guess is that you are taking so long on your ISR that it is interfering with other ISRs.

@PaulS

it does not affect it. otherwise it wouldnt work at all but it just does not when i try to write val.outputval...
when i write a value between 0 and 255 instead of outputval it does work.

Your entire sketch runs as an ISR? That's extremely unconventional, contravenes best practice that ISR execution time should be as short as possible and strikes me as very dodgy. I recommend you refactor your sketch to avoid that, EVEN IF you're certain it's not the cause of your problem.

What value does val.outputval have immediately before your call to analogWrite?

i know what you mean. will change that

the value depends on the input from a potentiometer and the multiplier in the program.
but even when i set it to 128 before i call analogWrite it does not work.

shameless selfbump

any ideas? anyone?

  val.multiplier   = val.multiplier + analogRead(A3)/1000;

What sort of value are you expecting analogRead(A3)/1000 to give you?

any ideas? anyone?

Yes read and act on the advice you have already been given. You are wrong and they are right.

@dxw00d
while testing the program pin A3 is constantly LOW so val.multiplier is that value which is set at the initialisation. sry did not mention that
but anyway how should this cause my problem?

@Grumpy_Mike
You are not helping at all.
Read and acted like on the advices given and if you would just read what i wrote you would know that those things did not work!

Since many just complain about parts of the program which do not cause my problem (i tested it) just leave this thread.
Those who try to help. thx alot so far

You are not helping at all.
Read and acted like on the advices given and if you would just read what i wrote you would know that those things did not work!

Sadly you don't understand. You think the bits of code with errors in work but they don't. Only when you remove the obvious errors can you get down to tracking down your misunderstanding of problem.

So... I am currently doing my diploma project.

I hope the diploma is not in a computing based discipline. At least you diploma classification will be all your own work.

Just so you know I used to be, what they call a professor in the U.S., in an English University so I have met students like you in the past.

while testing the program pin A3 is constantly LOW so val.multiplier is that value which is set at the initialisation. sry did not mention that
but anyway how should this cause my problem?

I was just asking, as analogRead()/1000 will only ever be 0 or 1.

@Grumpy_Mike
Why so mad?

As i said i did what you guys have said... removing those errors. And as i said it did not work any better.

I doubt you even looked at my code and thought about my problem and what could be the cause of it (beside already mentioned things).

And finally you show off how a good prefessor you are and how you met students "like me" blablabla.

Maybe i totally misunderstand the problem but you obviousliy do too.

Now in fact I also have a professor working with me at this project and he probably has the same skills and knowledge then you (dunno but probably).

And why on the other side should i believe you anyways. So far you made no helpful advice to solve my problem.

Dont answer if you dont want to help!

@dxw00d

Yes of course. My bad that i did not mention.
Changed that so it also works if there is an input on A3.

. And as i said it did not work any better.

I doubt you even looked at my code

What code is that?

You said you've made alterations, but haven't posted them.

Most of us look at code with serial I/O in interrupt context and simply switch off at that point - further conversation on the matter is pointless.

@Grumpy_Mike
Why so mad?

Because I care passionately about education and I am trying to get you to not be such an arrogant nob end. Just look at the number of posts I have made if you doubt my commitment to this platform and helping people out.

What I saw was lots of people trying to help you and you just batting away the advice. How you should behave is to take it, make the changes, post the code and state what actually happens and what you expect to happen. Debugging is an iterative process, it is not a one shot fix.

And why on the other side should i believe you anyways.

Credibility is always hard to establish so look at some of my projects if you want proof I know what I am talking about.
http://www.thebox.myzen.co.uk/Hardware/

This might be a good place to thank Mike for his highly informative web site. I have just been re-reading it in the hope that some of the information in it might percolate into my brain.

@op - after reading this thread I'm just confused. Perhaps if you post your latest code and describe in what way it doesn't work. Include your debugging print output. Be specific, rather than saying:

only when i want to write val.outputval it does not work :confused:

Say:

  • what pin you are writing to
  • what value is being written
  • what does "not work" mean

The processor is a well-defined device. It is working. Perhaps it isn't doing what you expect, so you have to describe your expectations, and the observed results. You haven't done that.

guesswho:
And why on the other side should i believe you anyways. So far you made no helpful advice to solve my problem.

Dont answer if you dont want to help!

Good luck getting your diploma. With this attitude, you will need it. Given the competence you've shown so far I think you will also need lots of help - but you won't be getting any more of it from me.

I'm going to lock this thread; it seems to be going nowhere until the OP comes up with some better observations than vague hand-waving and "it's nt working".