Blackfin:
Here's something that compiles but isn't tested. It attempts to maintain a target brightness using states and hysteresis. I've chosen a smaller value for the motor speed and an arbitrary value for the brightness. You'll need to play with those.
You might consider adding a serial interface feature to allow you to select a brightness level.
The code assumes (maybe incorrectly) you have limit switches. These would be important, for example, at night time: no matter how much you keep opening the blinds you'll never reach the desired brightness. But you don't really want to run the motor indefinitely trying. So a limit switch tells the Arduino the blinds are as open as they'll get and to just stop trying (and possibly damaging the motor or blind mechanism in the process.)
If you don't have limit switches you can comment out or remove those checks. I strongly recommend some form of limiting though...
//pins
const uint8_t controlPin1 = 5;
const uint8_t controlPin2 = 3;
const uint8_t enablePin = 9;
const uint8_t lightPin = A0;
const uint8_t limitswitchOpen = 6;
const uint8_t limitswitchClose = 7;
//constants
const uint8_t motorSpeed = 40; //slow speed for accurate brightness control
uint16_t lightState = 0;
#define K_TARGET_BRIGHTNESS 550
#define K_HYST_LOW 25
#define K_HYST_HIGH 25
#define K_MOVE_TIME 1000ul
#define K_SENSOR_READ_TIME 50ul
#define K_LIMSW_ACTIVE_LVL LOW
#define K_LIMSW_INACTIVE_LVL HIGH
enum statesBlinds
{
ST_BLINDS_IDLE=0,
ST_BLINDS_CLOSING,
ST_BLINDS_OPENING
};
void setup( void )
{
Serial.begin(9600);
pinMode( lightPin, INPUT );
pinMode( controlPin1, OUTPUT );
pinMode( controlPin2, OUTPUT );
pinMode( enablePin, OUTPUT );
digitalWrite( enablePin, LOW );
pinMode( limitswitchOpen, INPUT_PULLUP );
pinMode( limitswitchClose, INPUT_PULLUP );
}//setup
void loop( void )
{
static uint8_t
stateBlinds = ST_BLINDS_IDLE,
nextState;
static uint32_t
timeSensor,
timeBlinds;
uint32_t timeNow = millis();
//read the sensor every K_SENSOR_READ_TIME milliseconds
if( (timeNow - timeSensor) >= K_SENSOR_READ_TIME )
{
timeSensor = timeNow;
lightState = analogRead(lightPin);
Serial.println(lightState);
}//if
switch( stateBlinds )
{
case ST_BLINDS_IDLE:
if( lightState >= (K_TARGET_BRIGHTNESS + K_HYST_HIGH) )
{
//Q: is brightness level too high?
//yes; start blinds moving in the closing direction
if( digitalRead( limitswitchClose ) == K_LIMSW_INACTIVE_LVL ) //move only if limit-switch allows it
{
digitalWrite( enablePin, HIGH );
analogWrite( controlPin1, motorSpeed );
digitalWrite( controlPin2, LOW );
stateBlinds = ST_BLINDS_CLOSING;
}//if
}//if
else if( lightState <= (K_TARGET_BRIGHTNESS - K_HYST_LOW) )
{
//Q: is brightness level too low?
//yes; start blinds moving in the opening direction
if( digitalRead( limitswitchOpen ) == K_LIMSW_INACTIVE_LVL ) //move only if limit-switch allows it
{
digitalWrite( enablePin, HIGH );
analogWrite( controlPin1, LOW );
digitalWrite( controlPin2, motorSpeed );
stateBlinds = ST_BLINDS_OPENING;
}//if
}//else
break;
case ST_BLINDS_CLOSING:
//if limit switch closes or we reach the target brightness...
if( (digitalRead( limitswitchClose ) == K_LIMSW_ACTIVE_LVL ) || (lightState <= K_TARGET_BRIGHTNESS) )
{
//stop motor and...
digitalWrite( enablePin, LOW );
digitalWrite( controlPin1, LOW );
digitalWrite( controlPin2, LOW );
//return to idle state
stateBlinds = ST_BLINDS_IDLE;
}//if
break;
case ST_BLINDS_OPENING:
//similar logic to closing direction
if( (digitalRead( limitswitchOpen ) == K_LIMSW_ACTIVE_LVL ) || (lightState >= K_TARGET_BRIGHTNESS) )
{
digitalWrite( enablePin, LOW );
digitalWrite( controlPin1, LOW );
digitalWrite( controlPin2, LOW );
stateBlinds = ST_BLINDS_IDLE;
}//if
break;
}//switch
}//loop
I want to say thank you for taking the time to write all that out for me and prove me with an example of the code you think is best for my circuit.
No I did not incorporate limit switches. My reasoning is this: instead of using a limit switch to prevent turning I wanted to calibrate the time the motor turns precisely by using some math to convert the rotations of the motor into distance of string being moved in the open/close direction. Does that make sense? If, in order to open the blinds, the motor needs to move x inches, well... I've calibrated the motor to turn at a speed I determine, right? And if I can also determine the amount of time it is functioning, well then its just a simple formula of velocity x time = distance. So I just need to tell the motor to turn for x seconds. That would be something I would fine-tune later. And my intent was to use the delay function to time the motor.
Like so:
digitalWrite(enablePin, HIGH);
delay(500); (500 being an arbitrary number)
And it shouldn't matter too much if I'm delaying all other operations because while the blinds are opening/closing I don't really need to worry about what the light sensor reading is or anything else for that matter. After the blinds open/close is a different story. But while the motor is functioning, that's all I need my device to do.
At least that was my reasoning. Again, I'm new to all of this. Perhaps I'm being naive or unaware. But I was trying to make the simplest possible circuit for my very first engineering class. But again, thank you very much for writing all that out, although I don't have limit switches in my circuit. Bear in mind that at this particular moment, I'm not trying to develop an actual device that will really go on a set of blinds and start working. At this point I'm just trying to develop a prototype so to speak, something I will fine-tune later in this process. A working foundation. I wish I had more time to learn more about the concepts of coding, but time is limited.