Go Down

Topic: How to program ATmega328P Microcontroller for 2 Axis Control (Read 1 time) previous topic - next topic

kenwood120s

Quote
// Try searching maximum pages, now page 40, then 1 at a time - I know of no other way. //
If that was at me, here's how to link to a thread. Open the thread you want to be able to link to, then select and ctrl-C its URL. Then in the post you want to link from, select the text in your post you want to use as the clickable link, and hit the "chain" icon. Ctrl-V your previously ctrl-C'd url in where it says "Enter URL", and hit OK there and on the next panel.



So for example you can now click here to go to one of your other threads, which may or may not be the one you were talking about because I cba to track that one down.

[gumby]I've got my head stuck in the cupboard[/gumby]

JackOWalden1Sr

/* The below code is in the public domain. With the controller board powered up,
with 5 volts, will allow for the uploading of code to the board via computer.
The below 'serial' code will now be in memory, and will light the internal led?
 // kenwood120s, I'm sorry for not mentioning your name, and I know not how to
 re-open a closed thread
 // Keep in mind the pull-up means the pushbutton's logic is inverted. It goes
 // HIGH when it's open, and LOW when it's pressed. Turn on pin 13 when the
 // button's pressed, and off when it's not:
The additional code is what I want to do:  
 // When digitalWrite(5, LOW); is low,- means 'system is not 'on control'
 // System must be manually aimed at the sun, digitalRead(A5, LOW); must be 'HIGH'
 // When digitalWrite(6, HIGH); is high, motor is energized- means 'off control'  
 // When digitalWrite(6, LOW); is low, motor is deenergized- means 'on control'  
 // etc.. please indicate, yes or no, if I'm on the right path. It compiles?
 // Why sensorVal seems to work, when digitalRead don't?
 // Why error "exit status 1   expected '}' at end of input */

void setup() {
 //start serial connection
 Serial.begin(9600);
 //configure pin 2 as an input and enable the internal pull-up resistor
 pinMode(2, INPUT_PULLUP);
 pinMode(13, OUTPUT);
}

void loop() {
 //read the pushbutton value into a variable
 int sensorVal = digitalRead(2);
 //print out the value of the pushbutton
 Serial.println(sensorVal);
 //print out the value of the input sensor
 int digitalRead(A0);

 if (sensorVal == HIGH) {
   digitalWrite(13, LOW);
 } else {
   digitalWrite(13, HIGH);

 if (sensorVal, A0 == HIGH) {
   digitalWrite(5, LOW);
 } else {
   digitalWrite(5, LOW);
   
 if (sensorVal, A1 == HIGH) {
   digitalWrite(6, HIGH);
 } else {
   digitalWrite(6, LOW);
}

BJHenry

Quote
// Why sensorVal seems to work, when digitalRead don't?
Because this:
Quote
Code: [Select]

 int sensorVal = digitalRead(2);

 if (sensorVal == HIGH) {
   digitalWrite(13, LOW);
 } else {
   digitalWrite(13, HIGH);
is different to this:
Quote
Code: [Select]

 if (sensorVal, A0 == HIGH) {
   digitalWrite(5, LOW);
 } else {
   digitalWrite(5, LOW);
 
Quote
Why error "exit status 1   expected '}' at end of input */
Because you're missing several closing braces.

kenwood120s

I know not how to re-open a closed thread
Threads typically don't get closed, but what's closed threads got to do with this? I merely suggested a way to link to an existing thread from a post, in a way that's better than saying it's on page X of a forum, since it won't be on that page for long.

PLEASE us code tags: you have used them before so you know how, but just check you don't include your post inside the tags.

//Posting as comments like this is crazy.

(And in any case the //s are redundant since you use the /*...*/ approach ;) )
[gumby]I've got my head stuck in the cupboard[/gumby]

JackOWalden1Sr

Thanks BJHenry, now I'm getting the hang of opening and closing braces; and how to do it automatically, with a quick 'enter'.  Also, thanks kenwood120s, for your good input.  :)

JackOWalden1Sr

What I have is a dual axis control system that can be more accurate than NASA's solar control. It will keep the dual axis platform aimed directly at the sun for maximum output of the solar cells. The control system can be as accurate as desired, and will even keep it out of the shade of adjacent platforms.
The earth is not round, it is slightly bulging at the equator; it is also tilted, and it wobbles somewhat. This is what causes the annual summer and winter solstices and equinoxes. Nothing 'solar' is exact, only close.
The control system can track the sun by time alone; but, if not exactly by time, then by sensor input. This will take into consideration the solstices and equinoxes year round.
The timing can be based on the longest day at the installed location worldwide.  The altitude is controlled 'UP' in the a.m. and 'DOWN' in the p.m. hours. This is based on pre-and-post Solar Noon, not 12:00 o'clock noon, as the days are longer or shorter at varying locations. The following URL is for the Global Positioning System (GPS}. https://www.esrl.noaa.gov/gmd/grad/solcalc/ It is ideal for determining the sunrise and sunset times, but, if the programming code could be embedded in the Microcontroller's memory it would be much better. Even without that feature, GPS is still worthwhile for locating the systems anywhere on earth. It is not considered at this time to rotate the platform continuously, but, park it in the east at the very end of day.
I have a new code ready for posting, if you are ready to consider it. This code is based on melding two codes together, and removing the superfluous code. The code has a myriad of timed outputs, in lieu of just one.  Any and all inputs as to the cause will be greatly appreciated. Thanks, and have a nice day. 

BJHenry

Feel free to post your new code, but if you still haven't gone back and gotten the basic down then you'll just get told again to do so.

JackOWalden1Sr

Code: [Select]

const int switchPin = 13;
unsigned long previousTime = 0;
int switchState = 0;
int prevSwitchState = 0;
int led = 2;
long interval = 110000;

unsigned long currentTime = millis();

unsigned long time;

void setup() {
  //start serial connection
  Serial.begin(9600);
  //configure pin 2 as an input and enable the internal pull-up resistor
  pinMode(2, INPUT_PULLUP);
  pinMode(13, OUTPUT);

  if (currentTime - previousTime > interval)
    previousTime = currentTime;
  digitalWrite(led, HIGH);
  led++;
  if (led == 12) {
  } // put your main code here, to run repeatedly


  if (switchState != prevSwitchState) {
    for (int x = 12; x < 13; x++) {
      digitalWrite(x, LOW);
    }
    led = 12;
    previousTime = currentTime;
  }
  prevSwitchState = switchState;
}

void loop() {
  Serial.print(0);
  time = millis();
  //prints time since program started

  //read the pushbutton value into a variable
  int sensorVal = digitalRead(2);
  //print out the value of the pushbutton
  Serial.println(sensorVal);
  //print out the value of the input sensor
  int digitalRead(A0);

  if (sensorVal == HIGH) {
    digitalWrite(13, LOW);
  }    else {
    digitalWrite(13, HIGH);
  }
  if (sensorVal, A0 == HIGH) {
    digitalWrite(5, LOW);
  }     else {
    digitalWrite(5, LOW);
  }
  if (sensorVal, A1 == HIGH) {
    digitalWrite(6, HIGH);
  } else {
    digitalWrite(6, LOW);
  }
  if (sensorVal, A2 == HIGH) {
    digitalWrite(7, HIGH);
  } else {
    digitalWrite(7, LOW);
  }
  if (sensorVal, A3 == HIGH) {
    digitalWrite(8, HIGH);
  } else {
    digitalWrite(8, LOW);
  }
  if (sensorVal, A4 == HIGH) {
    digitalWrite(9, HIGH);
  } else {
    digitalWrite(9, LOW);
  }
  if (sensorVal, A1 == HIGH) {
    digitalWrite(10, HIGH);
  } else {
    digitalWrite(10, LOW);
  }
  if (sensorVal, A2 == HIGH) {
    digitalWrite(6, HIGH);
  } else
    digitalWrite(6, LOW);
  if (currentTime - previousTime > interval) {
  }
  previousTime = currentTime;
  digitalWrite(led, HIGH);
  led++; {
    if (led == 12) {
    } // put your main code here, to run repeatedly
  }

  if (switchState != prevSwitchState) {
    for (int x = 12; x < 13; x++)
      digitalWrite(x, LOW);
    prevSwitchState = switchState;
    led = 12;
    previousTime = currentTime;
  }
}
 
// Interested only on duration of timed outputs, and if, GPS is doable.

BJHenry

First off, this is better than what you've posted previously. Still has plenty of issue but it is a step forward.

Interested only on duration of timed outputs, and if, GPS is doable.
Which timed outputs? I can see that you're trying to read the inputs and turn the onboard LED on or off based on the input, but there is no timing method involved at all.
GPS is always doable but talking about that at the moment is definitely putting the cart before the horse.

JackOWalden1Sr

The timed output dilemma is solved. My first thought was to use Pulse Width Modulation (PWM) to control the speed of the DC motors. Because the duration of the timing is so small, and the delay is so short, my second thought is that the PWM is more than adequate for timing; therefore, a fraction of a second out of 24 hours delay is tolerable. 

BJHenry

The timed output dilemma is solved. My first thought was to use Pulse Width Modulation (PWM) to control the speed of the DC motors. Because the duration of the timing is so small, and the delay is so short, my second thought is that the PWM is more than adequate for timing; therefore, a fraction of a second out of 24 hours delay is tolerable. 
Sure, but there is no timed outputs of any kind in the code that you've posted.

JackOWalden1Sr

How about this code for motor control?
Code: [Select]
unsigned long previousTime = 9;
int switchState = 9;
int prevSwitchState = 1;
long interval = 0; 
int pwm = 12; // assigns pin 12 to variable pwm
int pot = A0; // assigns analog input A0 to variable pot
int t1 = 0;   // declares variable t1
int t2 = 0;   // declares variable t2
void setup()  // setup loop
{
  pinMode(pwm, OUTPUT); // declares pin 12 as output
  pinMode(pot, INPUT);  // declares pin A0 as input
}
void loop()
{
    unsigned long currentTime = millis()/1000; 
  if(currentTime - previousTime > interval);
    previousTime = currentTime;
    digitalWrite(10, HIGH);
  t2= analogRead(pot); // reads the voltage at A0 and saves in t2
  t1= 1000-t2;         // subtracts t2 from 1000 ans saves the result in t1
  digitalWrite(pwm, HIGH); // sets pin 12 HIGH
  delayMicroseconds(t1);   // waits for t1 uS (high time)
  digitalWrite(pwm, LOW);  // sets pin 12 LOW
  delayMicroseconds(t2);   // waits for t2 uS (low time)
      digitalWrite(11, HIGH);
  t2= analogRead(pot); // reads the voltage at A0 and saves in t2
  t1= 1000-t2;         // subtracts t2 from 1000 ans saves the result in t1
  digitalWrite(pwm, HIGH); // sets pin 12 HIGH
  delayMicroseconds(t1);   // waits for t1 uS (high time)
  digitalWrite(pwm, LOW);  // sets pin 12 LOW
  delayMicroseconds(t2);   // waits for t2 uS (low time) // [3,5,6,9]
  if (digitalRead(A1) == LOW) // This indicates no light on sensor, and is on control.
    analogWrite(5, 30); // Ditto- on control.
  delay(225); // Indicates motor runs to bring back on control.
  if (digitalRead(A2) == LOW)
    delay(240);
  analogWrite(6, 30);
  delay(225);
  if (digitalRead(A3) == LOW) //This indicates on control.
    analogWrite(9, 15); // This indicates on control.
  delay(240);
  if (digitalRead(A4) == LOW) // This indicates on control.
    analogWrite(10, 15);
  delay(240);
}   

BJHenry

You've obviously done away and done some researching, that's great. Having said that, there's a few things to get out of the way first:
Code: [Select]
int pwm = 12; // assigns pin 12 to variable pwm
Pin 12 doesn't support PWM, at least on the Uno.


Code: [Select]
void setup()  // setup loop
{
  pinMode(pwm, OUTPUT); // declares pin 12 as output
  pinMode(pot, INPUT);  // declares pin A0 as input
}
Best bet to set your other outputs here too.


Code: [Select]
if(currentTime - previousTime > interval);
IF statements don't have semi-colons after them. You also need some brackets to make sure it is tested correctly- you want something like this:
Code: [Select]
  if((currentTime - previousTime) > interval);
IF statements also need braces.


The logic of the rest of your code doesn't make too much sense. You need to give us some more information on the motors that you are planning to use.

JackOWalden1Sr

Thank you BJHenry,
The motors are of the type presented by: http://www.kinematicsmfg.com/
They are 24VDC bidirectional motors, driving gear boxes, with up to 156,000:1 gear box reduction ratios. The sizes range from LARGE to HUMONGOUS. The ATmega 328P Microcontroller will do a fine job controlling them.
All of the PMW circuits will be utilized, plus some others. Outputs 10 and 11 will be for West and Up directions, respectively. Circuits 3, 5, 6, and 9 are for North, East, South and West respectively. These will be active, only by the inputs of circuits A1, A2, A3, and A4. (The different numbers are because of the differing circuit characteristics), and can be further adjusted. This will drive the motors for less than one platform revolution per day. See the attachment for a representation. The outputs will encompass diodes to prevent voltage back-feed from the manual push-buttons. One additional circuit will park the motor in the east, at full speed, when day ends.One additional circuit will override the 'down' circuit to keep the unit in sunshine.  The LEDS are for troubleshooting purposes.

JackOWalden1Sr

Please tell me what is wrong with this code. It was cut and pasted from:
https://www.arduino.cc/en/Tutorial/CurieTimer1PWM?action=sourceblock&num=1
Code: [Select]
#include "CurieTimerOne.h"

void setup() {
  // Setup a PWM signal on pin 13, onboard LED, with a 25% duty cycle
  // of a 1 second period (1000000 usec), as follow (please note the
  // decimal point to indicate double):

  CurieTimerOne.pwmStart(13, 25.0, 1000000);

  // Or, use discrete number range, 0-1023, to define the duty period,
  // 255 is 24.9%, as follow:

  // CurieTimerOne.pwmStart(13, 255, 1000000);
}

void loop() {
  // put your main code here, to run repeatedly:

  delay( 10000 );
}

Go Up