Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Need Help: Integrating lamps dimmer with blinds (using stepper motor)

Status
Not open for further replies.
Hooooohhh,

Alright,,,

So now can we go to the both problems in post #29? With this last code I still got them.
 

Hi I see something strange with the motor power supply (separated with the uC power supply)

pwr.png

Do you know what is causing it?
 

Not really but on the other hand you are showing a simulation model, do you get 0.9v in the output of the real 7805?
 

In the hardware, Voltage is 4.7 - 4.9V but the problem is with my 16x2 LCD. It is like lack of power. I cannot see the characters clearly. At the beginning it is very clear but after a while it's dimming. The lamps blink like mad and do not follow my code.
 

What about my code? Am I doing something wrong in each of this:

Code:
        if((ldr1 <= 300) && (motor_flagA == 0))    [COLOR="#FF0000"]// It gives error only when I add this part and the last part[/COLOR]
        {
            turn_A(ARIGHT,23);
            motor_flagA++;
        }
        
        #asm("cli")   
        if((PORTB.0 == 1) && (ldr1 <= 300) && (motor_flagA == 1))
        {
            if(x > 1)
            {  
                x = x - 1;
            }
        }
        
        // If light intensity greater than the setpoint, increase the firing delay, and close blinds        
        if((PORTB.0 == 1) && (ldr1 >= 350))
        {
            if(x < 280)
            { 
                x = x + 1;
            }
        }
        
        #asm("sei")
        
        if((ldr1 >= 350) && (x == 280) && (motor_flagA == 1))    [COLOR="#FF0000"]// This one[/COLOR]
        {
            turn_A(ALEFT,23);
            motor_flagA = 0;   
        }
 

Hi, I did an experiment.

First, I modify the void change_intensity() so that it contain only 1 lamp and one motor. It is like this:


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
void change_intensity()
 {
 
        static unsigned int motor_flagA = 0;
        static unsigned int motor_flagB = 0;
        static unsigned int motor_flagC = 0;
        
        // If light intensity below the setpoint, open blinds, and shorten the firing delay
        if((ldr1 <= 300) && (motor_flagA == 0))
        {
            turn_A(ARIGHT,23);
            motor_flagA++;
        }
        
        #asm("cli")   
        if((PORTB.0 == 1) && (ldr1 <= 300) && (motor_flagA == 1))
        {
            if(x > 1)
            {  
                x = x - 1;
            }
        }
        
        // If light intensity greater than the setpoint, increase the firing delay, and close blinds        
        if((PORTB.0 == 1) && (ldr1 >= 350))
        {
            if(x < 280)
            { 
                x = x + 1;
            }
        }
        
        #asm("sei")
        
        if((ldr1 >= 350) && (x == 280) && (motor_flagA == 1))
        {
            turn_A(ALEFT,23);
            motor_flagA = 0;   
        }
}



When I download it into my hardware, off course only one lamp and one motor work. Both of them work as what I want and they are very very smooth. My LCD does not dim also, everything seems fine.

The next, I tried to add one lamp and one motor so it become like this:

Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
void change_intensity()
 {
 
        static unsigned int motor_flagA = 0;
        static unsigned int motor_flagB = 0;
        static unsigned int motor_flagC = 0;
        
        // If light intensity below the setpoint, open blinds, and shorten the firing delay
        if((ldr1 <= 300) && (motor_flagA == 0))
        {
            turn_A(ARIGHT,23);
            motor_flagA++;
        }
        
        #asm("cli")   
        if((PORTB.0 == 1) && (ldr1 <= 300) && (motor_flagA == 1))
        {
            if(x > 1)
            {  
                x = x - 1;
            }
        }
        
        // If light intensity greater than the setpoint, increase the firing delay, and close blinds        
        if((PORTB.0 == 1) && (ldr1 >= 350))
        {
            if(x < 280)
            { 
                x = x + 1;
            }
        }
        
        #asm("sei")
        
        if((ldr1 >= 350) && (x == 280) && (motor_flagA == 1))
        {
            turn_A(ALEFT,23);
            motor_flagA = 0;   
        }
        
        
                // If light intensity below the setpoint, open blinds, and shorten the firing delay
        if((ldr3 <= 300) && (motor_flagC == 0))
        {
            turn_C(CRIGHT,23);
            motor_flagC++;
        }
        
        #asm("cli")   
        if((PORTB.2 == 1) && (ldr3 <= 300) && (motor_flagC == 1))
        {
            if(z > 1)
            {  
                z = z - 1;
            }
        }
        
        // If light intensity greater than the setpoint, increase the firing delay, and close blinds        
        if((PORTB.2 == 1) && (ldr3 >= 350))
        {
            if(z < 280)
            { 
                z = z + 1;
            }
        }
        
        #asm("sei")
        
        if((ldr3 >= 350) && (z == 280) && (motor_flagC == 1))
        {
            turn_C(CLEFT,23);
            motor_flagC = 0;   
        }
 }



Here the problem start. Both lamps and motors are still work smoothly but LCD start dimming, and the characters disappear.

Well, I want to ask, what will be the effect of using #asm("cli") and #asm("sei") too many times?

- - - Updated - - -

Next, I add the third lamp and the third motor, so it become like this:


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
void change_intensity()
 {
 
        static unsigned int motor_flagA = 0;
        static unsigned int motor_flagB = 0;
        static unsigned int motor_flagC = 0;
        
        // If light intensity below the setpoint, open blinds, and shorten the firing delay
        if((ldr1 <= 300) && (motor_flagA == 0))
        {
            turn_A(ARIGHT,23);
            motor_flagA++;
        }
        
        #asm("cli")   
        if((PORTB.0 == 1) && (ldr1 <= 300) && (motor_flagA == 1))
        {
            if(x > 1)
            {  
                x = x - 1;
            }
        }
        
        // If light intensity greater than the setpoint, increase the firing delay, and close blinds        
        if((PORTB.0 == 1) && (ldr1 >= 350))
        {
            if(x < 280)
            { 
                x = x + 1;
            }
        }
        
        #asm("sei")
        
        if((ldr1 >= 350) && (x == 280) && (motor_flagA == 1))
        {
            turn_A(ALEFT,23);
            motor_flagA = 0;   
        }
        
        
                // If light intensity below the setpoint, open blinds, and shorten the firing delay
        if((ldr2 <= 300) && (motor_flagB == 0))
        {
            turn_B(BRIGHT,23);
            motor_flagB++;
        }
        
        #asm("cli")   
        if((PORTB.1 == 1) && (ldr2 <= 300) && (motor_flagB == 1))
        {
            if(y > 1)
            {  
                y = y - 1;
            }
        }
        
        // If light intensity greater than the setpoint, increase the firing delay, and close blinds        
        if((PORTB.1 == 1) && (ldr2 >= 350))
        {
            if(y < 280)
            { 
                y = y + 1;
            }
        }
        
        #asm("sei")
        
        if((ldr2 >= 350) && (y == 280) && (motor_flagB == 1))
        {
            turn_B(BLEFT,23);
            motor_flagB = 0;   
        }
        
                // If light intensity below the setpoint, open blinds, and shorten the firing delay
        if((ldr3 <= 300) && (motor_flagC == 0))
        {
            turn_C(CRIGHT,23);
            motor_flagC++;
        }
        
        #asm("cli")   
        if((PORTB.2 == 1) && (ldr3 <= 300) && (motor_flagC == 1))
        {
            if(z > 1)
            {  
                z = z - 1;
            }
        }
        
        // If light intensity greater than the setpoint, increase the firing delay, and close blinds        
        if((PORTB.2 == 1) && (ldr3 >= 350))
        {
            if(z < 280)
            { 
                z = z + 1;
            }
        }
        
        #asm("sei")
        
        if((ldr3 >= 350) && (z == 280) && (motor_flagC == 1))
        {
            turn_C(CLEFT,23);
            motor_flagC = 0;   
        }
 }



And everything mess up :(
 

what will be the effect of using #asm("cli") and #asm("sei") too many times?

The interrupt is disabled after cli() so the interrupts have to wait until sei() is used again, if the duration is long it can lead to problems
 

Code:
#asm("cli")   
        if((PORTB.0 == 1) && (ldr1 <= 300) && (motor_flagA == 1))
        {
            if(x > 1)
            {  
                x = x - 1;
            }
        }
        
        // If light intensity greater than the setpoint, increase the firing delay, and close blinds        
        if((PORTB.0 == 1) && (ldr1 >= 350))
        {
            if(x < 280)
            { 
                x = x + 1;
            }
        }
#asm("sei")

It is not so long (only 17us), but there will be three as shown in the previous last code, so can they lead to problem?
 

Well so that is not the cause.
But why using only one lamp and one motor is OK, and using more than one is not. Do you have any suggestion related to post #49
 

Not really, I have spend enough time trying to debug the version of the previous thread , I can't do that over again
 

Hello...

I'm back and already able to control two lamps and two motors. I think the problem is in this part:

Code:
void turn_B(unsigned char directionB, int stepB)
 {
    static unsigned char k = 0;
    unsigned int l = 0;

    while(l <= stepB)
    {
        l++;

        if(directionB)
        {
            k++;
        }
        else
            {
                k--;
            }

        if(k == 255)
        {
            k = 3;
        }
        else
            if(k == 4)
            {
                k = 0;
            }

        PORTD = (PORTD & 0b10000111) | (motor_stepB[k] & 0b01111000);   // [B][COLOR="#FF0000"]Here[/COLOR][/B]
        delay_ms(50);
    }
 }


I think this disturb the external interrupt pin (PIND.2) so that when motorB turn, all lamps blinking very bad. Is there any special way to put two motors in PORTB only?
I mean, motorA (PINB.0 1 2 3) and motorB (PINB. 4 5 6 7).
 

Your steps are currently
Code:
unsigned int motor_stepA[4] = {0b00101000, 0b00110000, 0b01010000, 0b01001000};
unsigned int motor_stepA[4] = {0b00101000, 0b00110000, 0b01010000, 0b01001000};
Which by the way are 16 bit int with no reason so use

so if you change them to
Code:
unsigned char motor_stepA[4] = {0b0000[COLOR="#FF0000"]0101[/COLOR], 0b0000[COLOR="#FF0000"]0110[/COLOR], 0b0000[COLOR="#FF0000"]1010[/COLOR], 0b0000[COLOR="#FF0000"]1001[/COLOR]};
unsigned char motor_stepB[4] = {0b[COLOR="#FF0000"]0101[/COLOR]0000, 0b[COLOR="#FF0000"]0110[/COLOR]0000, 0b[COLOR="#FF0000"]1010[/COLOR]0000, 0b[COLOR="#FF0000"][COLOR="#FF0000"]1001[/COLOR][/COLOR]0000};

then you can use
Code:
PORTB= motor_stepA[step1] | motor_stepB[step2];
 

So you mean put PORTB= motor_stepA[step1] | motor_stepB[step2];
in each of
void turn_A(unsigned char directionA, int stepA) and
void turn_B(unsigned char directionB, int stepB)


If like that, I should assign new global variable then ?
 

I just showed you how to write the two nibbles (one for each motor) to the same port simultaneously.

If you don't want to do it simultaneously then you can write them one at a time using a mask as I showed you before
 

If I use:

Code:
PORTB= motor_stepA[i] | motor_stepB[k]

then I should make i and k as global variable?

If you don't want to do it simultaneously then you can write them one at a time using a mask as I showed you before

I use this but they do not work well.

Code:
PORTB = (PINB & 0b11110000) | (motor_stepA[i] & 0b00001111); 

PORTB = (PINB & 0b00001111) | (motor_stepB[k] & 0b11110000);
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top