Problem with My Engineering Project

Okay. I'm new to circuits and coding. I'm an EE major. I have a project idea that I came up with for school. And I'm so close to the finish line I can taste it but at the same time I'm totally stuck on where to go or what to do from here. Here's some context.
For my project, my idea was to use an Arduino Uno to automate blinds (the kind on your house windows). So here's the synopsis. An ambient light sensor takes a reading of the light in the room. The Arduino reads this. If the light is too dim, it will initiate the blinds to open by turning a DC motor in the appropriate direction for a short period of time. If the light is too bright, it will turn the motor in the opposite direction to close the blinds. I should mention that I have everything attached to an H-bridge to easily reverse the polarity of the current. Pretty simple, right? Well.. I can't see to get my circuit to do what I want it to do, which points to a problem in my code, obviously. What ends up happening is the Arduino takes in the light sensor value and if the light is dim, then it turns the motor continuously until the light is too bright, at which point it spins continuously in the opposite direction. Thats no good. The motor would just rip the blinds off the walls. I'm kind of at my wits end here. Can anyone guide me in the right direction? I'm so close to achieving this on my own and that's a very euphoric feeling, but I guess I need a little help after all.

sketch_engineeringProject.ino (1.16 KB)

Have a read of how to post in the forum in the guidelines - people won’t look at attached code , use code tags.
A proper circuit diagram helps too

How do I make a circuit diagram? I guess I'll just make it by hand, on paper?

Can You please post the code according to the advice in the first topic like "How to use this Forum", #7?
Please post a wiring diagram showing names of pins etc. Fritzings are paintings. Your Fritzing doesn't even allow to be magnified.

To the issue. What do You want

previousLight

to do?

This way looks strange to me because I can't read the painting You posted.

   analogWrite(enablePin, motorSpeed);
    analogWrite(controlPin1, motorSpeed);

You send PWM to a pin named "enablePin". Sounds really odd to me.

What is that 16 pin blob being used?

engamir27:
How do I make a circuit diagram? I guess I'll just make it by hand, on paper?

Yes. Usually works fine. We don't ask for CAD....

A hand drawing on paper is preferred over Fritzing pictures.

And a 9V battery will probably not last long.

engamir27:
How do I make a circuit diagram? I guess I'll just make it by hand, on paper?

I would suggest you to create a simulation on Proteus. Advantages:

  1. You will get the circuit diagram.
  2. You will get the simulation to test your code.

Sounds like you need some limit switches so the Arduino knows when you reach the end of the travel limits and can stop driving in that direction; perhaps back off a little and stop, until a change in light conditions is then reached.
Examples:
https://www.digikey.com/en/products/filter/snap-action-limit-switches/198?s=N4IgjCBcoLQdIDGUBmBDANgZwKYBoQB7KAbRAGYBOEAXQIAcAXKEEAXzYICZSQsA7NPQAEaRIwCWhfsKwB3CY0QALWmyA

Wire it up to connect a pin to Gnd when closed.
Turn on the pullup resistor for that pin, and look for a Low to tell when the switch is closed and the limit reached.

But instead of a limit switch, couldn't I just code the Arduino to initiate the motor for a period of time I determine? Say I need the motor to turn at half speed for half a second when the light reaches changes a threshold of light. Could I not tell the Arduino to do so through some particular code? I'm working on a diagram as I write this. I may repost my question again with the diagram and the code for clarification as this post seems to confuse people more than help explain my problem.

Maybe You could. You need to give the motor time enough to make its move and, maybe, also give the light sensor time to settle. Some light sensors are quite a bit slow.

Give us links to the hardware You use. "A light sensor" is not exactly precise engineering....
Motor, driver......

Below is a wiring diagram.. I know it may be a little difficult to read but I think its somewhat legible.
Here is the code I am currently using.
And, if it helps clarify, it's just a run of the mill phototransistor. I don't know its model or make.

const int controlPin1 = 5;
const int controlPin2 = 3;
const int enablePin = 9;
const int lightPin = A0;
int motorSpeed = 0;
int light = 0;

void setup() {
  Serial.begin(9600);
  pinMode(lightPin, INPUT);
  pinMode(controlPin1, OUTPUT);
  pinMode(controlPin2, OUTPUT);
  pinMode(enablePin, OUTPUT);
  digitalWrite(enablePin, LOW);// put your setup code here, to run once:

}

void loop() {
 light = analogRead(lightPin);
  delay(1);
  motorSpeed = (1023)/8;
  Serial.println(light);
  if (light >= 0 && light <= 700){
    analogWrite(enablePin, motorSpeed);
    analogWrite(controlPin1, motorSpeed);
    digitalWrite(controlPin2, LOW);
    delay(1000);
    digitalWrite(enablePin, LOW);
    digitalWrite(controlPin1, LOW);
    digitalWrite(controlPin2, LOW);
  }
  if (light > 700 && light <= 1023){
    analogWrite(enablePin, motorSpeed);
    digitalWrite(controlPin1, LOW);
    analogWrite(controlPin2, motorSpeed);
    delay(1000);
    digitalWrite(enablePin, LOW);
    digitalWrite(controlPin1, LOW);
    digitalWrite(controlPin2, LOW);
  }
}

What kind of battery is that 9 volt battery? The rectangular one used in fire alarms? That will not do well. Maybe an old phone charger? That could be okey.

To be sure, I ask how the controller is powered.

I did Google on the L213D and landed in angled connectors. Do You have a link to it? I miss the pin names of the circuit in Your drawing. Your PWM-ing the enable puzzles me.

Railroader:
Can You please post the code according to the advice in the first topic like "How to use this Forum", #7?
Please post a wiring diagram showing names of pins etc. Fritzings are paintings. Your Fritzing doesn't even allow to be magnified.

To the issue. What do You want

previousLight

to do?

This way looks strange to me because I can't read the painting You posted.

   analogWrite(enablePin, motorSpeed);

analogWrite(controlPin1, motorSpeed);




You send PWM to a pin named "enablePin". Sounds really odd to me.

What is that 16 pin blob being used?

Ignore previousLight. It has no function currently. I meant to delete that line of useless code. As for the PWM to enablePin, yes. The enablePin is the pin that powers the motor. The reason it is being PWM is because I want the motor to turn at a speed I determine. Remember, the motor will be opening and closing blinds. If it runs at full speed it will move too quickly and have too much power, angular momentum, force, etc. It'll basically break the blinds. I'll need to regulate the power being sent to the motor in order to have it operate a functional velocity.
The 16 pin blob is an H-bridge, L293D. I need it to reverse the polarity of the motor, so the motor can open and close the blinds. I hope this helps explain.
Back to my original point, the problem is that when I initiate the program it ends up running the motor at a constant rate. The motor never stops. This is a problem. This will either break the motor or rip the blinds off. Either way, that's no bueno. This is the crux of the problem. I need to add a function in my code that specifies a timeframe to operate the motor within. As in power the motor for 1 second, or 2 seconds, or a quarter of a second, whatever that time is. But the motor cannot run constantly otherwise this project is a dud. Does this help explain my problem?

No. Your reply does not tell anything new.

Provide us with a link to that L293D. I did use time but didn't find the circuit data sheet.
Sending PWM to a true enable pin is mostly not good. The power should be controlled by that second pin. If the motor runs too fast, lower the PWM to that control pin. Lower the value in motorSpeed = (1023) / 8;.

Your double PWM outputs might be the reason for "full speed".

I understand what you mean by PWM-ing only the control pins and not the enable. I can change that. But the problem persists. Here is a link to the L239D Datasheet:

I think the first thing to do is sense when the voltage from the LDR has reached some arbitrary level (that could be rising or falling), not that it's at some level. This is termed 'state change detection'. State change detection normally involves doing something for just one scan of the program. This might be calling a function or setting some value, etc.

So, the change from, say, below a certain level to at or above that level constitutes a state change. Use the state change to set a flag to run your timer for whatever duration is needed. When the timer is done it resets the flag which shuts off the motor.

If there are several levels of light to be sensed you need a state change, and accompanying flag, detect for each one - in both directions.

Further reading: IDE -> file/examples/digital/statechangedetection

timer counter state change toggle FSM tutorial

Yes! The thought just occurred to me before you posted this reply. Why am I telling the controller to continuously scan for the current level of light? It should be looking for a threshold being crossed. A state being changed, as you indicated. So, in essence, this is what I'm trying to program into my Arduino:

thresHoldLight = 700 (just picking an arbitrary number from 1 to 1023);

When the lightValue crosses thresHoldLight, then:

When lightValue > thresHoldLight {
initiate motor in positive direction for 2 seconds }
When lightValue < thresHoldLight {
initiate motor in negative direction for 2 seconds}
}
and that's it really. That's all I'm trying to tell the Arduino to do. So now I'm just trying to write a program that does exactly that. I will take a look at your link. Thank you.

Thanks.

On the L293D output pins 3 and 6 on the L293D goes to the motor. Fine.
To go in one direction You give pin 3 a low level for one direction and PWM at pin 6. To go the other direction You give pin 6 a low level and PWM to pin 3. PWM == 0 makes stop, PWM 255 gives full speed.
The enable should be active all the time. I think that high level is the active level.

It's getting terrible late here, 02.47 AM, so I might be affected by that in some detail.
That way I run similar H-bridge.
The speed is set by the value of the analog.write.

Can You try this, with the motor mechanically disconnected from the blinds? Use a significantly lower PWM than 1023/8. Let's say 1023/100. That ought to slow down the motor.

Hello. I posted about this yesterday, if any of you are reading this again. But although I fixed my previous problem I have a new one haha. Ok, here it is.

So my final project for my engineering class is an Arduino-based automated blinds system. By "blinds" I'm referring to the blinds on house windows. The general idea is that a phototransistor takes continuous readings of the ambient light in a room. When the light level gets too bright, the Arduino sends a signal to a DC motor to turn the blinds closed, thus reducing the light in the room. And vice versa when the light is too dim (blinds open to allow light in). In order to accomplish this, I needed an H-bridge (L239D) to reverse polarity on the motor to allow the motor to spin in both directions when needed. And that's essentially it. It's a very simple circuit, nothing complicated, as I'm a beginner with Arduinos and coding. One phototransistor, one H-bridge, one DC motor, one Arduino . I've attached a sketch of the wiring diagram below.

Now here is the new problem I'm having.

So, to be clear, the concept that enables the system to operate properly is that there is a threshold level of light that when exceeded initiates the motor to close the blinds (because the light is now too bright). And when the light is below the threshold, the motor is initiated to open the blinds. So, the concept hinges upon the threshold. Here is the problem, though. Instead of initiating the motor when the light crosses the threshold, instead it is initiating the motor every time the light level changes value. So, when the light level changes from, for example, 600 to 601, the motor initiates. If the light level changes from 601 to 602, it initiates again. And so on. The motor is at least turning in the appropriate direction (when the light is low it the motor turns so it closes the blinds). But again, it keeps doing this over and over every time the value changes at all. I set my threshold at 700 in the code below. So, if the light changes from 600 to 599, it turns the motor to close the blinds. And again when it goes down to 598.. etc. And if the light is above 700, then it will open the blinds. But then again when it is 701, and again at 702.. etc. Obviously, this is a problem because the motor will constantly be moving and, remember, the motor will be attached to the blinds, so the blinds will basically be torn off its hinges. Can someone help guide me in the right direction and help save my final project? What am I missing?

Also, before anyone says anything about the PWM-ing -- I am PWMing the motor so it turns at an appropriate speed (not too fast, not too slow). And I added a delay operation so the motor only turns for appropriate amount of time (if the motor turns for too long, again the blinds will be torn off the walls). But all of that is irrelevant to my problem. What is my code missing?

And here is the code:

const int controlPin1 = 5;
const int controlPin2 = 3;
const int enablePin = 9;
const int lightPin = A0;
const int thresHold = 700;
int motorSpeed = 0;
int lightState = 0;
int lastLS = 0;

void setup() {
  Serial.begin(9600);
  pinMode(lightPin, INPUT);
  pinMode(controlPin1, OUTPUT);
  pinMode(controlPin2, OUTPUT);
  pinMode(enablePin, OUTPUT);
  digitalWrite(enablePin, LOW);// put your setup code here, to run once:

}

void loop() {
 lightState = analogRead(lightPin);
  delay(1);
  motorSpeed = (1023)/100;
  Serial.println(lightState);
  if (lightState != lastLS){
    if(lightState > thresHold){
    digitalWrite(enablePin, HIGH);
    analogWrite(controlPin1, motorSpeed);
    digitalWrite(controlPin2, LOW);
    delay(1000);
    digitalWrite(enablePin, LOW);
    digitalWrite(controlPin1, LOW);
    digitalWrite(controlPin2, LOW);
  }
  if (lightState < thresHold){
    digitalWrite(enablePin, HIGH);
    digitalWrite(controlPin1, LOW);
    analogWrite(controlPin2, motorSpeed);
    delay(1000);
    digitalWrite(enablePin, LOW);
    digitalWrite(controlPin1, LOW);
    digitalWrite(controlPin2, LOW);
  }
    delay(50);
  }
  lastLS = lightState;
}

First, if you haven't done so look up the term "hysteresis."

The idea is to have two thresholds; one for the light getting brighter and the second for it getting darker.

Suppose the blinds are closed and the room is getting dark now. If the light level falls below, say, "450" then you open the blinds.

With the blinds now open you wouldn't want to close the blinds until the light level rose to "650".

Also, this means you need to remember the state of the blinds (open or closed) and look for the appropriate level based on that state.