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.

74hc595 16f877a interfacing problems

Status
Not open for further replies.
My previous post is updated. What does the solenoids do ?
 

solenoids just raise to from the albhabets
 

Why 24 solenoids ? How many alphabets at once ? big brailly for visually impaired ?

If 24 ascii characters are sent ('1' and '0' s) then you have to do 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
unsigned long value2hc595 = 0;
char counter = 0, i = 0;
char buffer[24];
 
//MSB sent first
 
void interrupt() {
 
    if(RCIF_bit) {
        if(counter < 24) {
            buffer[counter++] = UART1_Read();
            ++counter;
        }
 
        RCIF_bit = 0;
    }
}
 
 
while(1) {
 
    if(counter == 23) {
 
        for(i = 0; i < 24; i++) {
 
            value2hc595 <<= 1;
 
            if(vuffer[i] == '1') {
                value2hc595 |= 1;
            }
        }
    }
]



Then send 3 bytes to HC595
 
  • Like
Reactions: varunme

    varunme

    Points: 2
    Helpful Answer Positive Rating
My current application need only to send letters. not the words.
the words are stored in push button switches in the pic, for demo purpose, I want to do this only

24 solenoids, for showing the words stored in the pushbutton switches, which are not sent by uart.

yes braily type
 

Draw the exact circuit and post it as image here. Tell how the system has to work. Provide an example of what exact data you send through UART and what solenoids have to turn ON for that data. Don't make changes every now and then. Without knowing the exact functioning code cannot be written.
 

it incorporates voice also so altogather 15bits for a single alphabet, ok i will send
 

You said 24 bits and now you say 15 bits. See this ic code to send 24 bits to HC595.


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void SPI_Send(unsigned long s) {
 
     unsigned long mask = 0x80000000;
     char i = 0;
     
     for(i = 0; i < 24; i++, mask >>= 1) {
           if(s & mask) 
               DS = 1;          
           else 
               DS = 0;
               
           SH_CP = 1;
           Delay_ms(10);
           SH_CP = 0;
     }
     
     ST_CP = 1;
     Delay_ms(10);
     ST_CP = 0;
}

 

sorry about that, that time I was about make a code to check if its working, you are so helpfull, thank you
Actually that time i was out of focus that time, now with your support things are almost clear, i will try with this code
 

Sorry the code was wrong. Here is the corrected code.


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void SPI_Send(unsigned long s) {
 
     unsigned long mask = 0x800000;
     char i = 0;
     
     for(i = 0; i < 24; i++, mask >>= 1) {
           if(s & mask) 
               DS = 1;          
           else 
               DS = 0;
               
           SH_CP = 1;
           Delay_ms(10);
           SH_CP = 0;
     }
     
     ST_CP = 1;
     Delay_ms(10);
     ST_CP = 0;
}

 

so the whole code is as follows, the 595 outputs are not steady, its fluctuating


Code:
sbit SH_CP at RD0_bit;
sbit SH_CP_Direction at TRISD0_bit;

sbit ST_CP at RD2_bit;
sbit ST_CP_Direction at TRISD2_bit;

sbit DS at RD1_bit;
sbit DS_Direction at TRISD1_bit;

char uart_rd = 0, i = 0, j = 0;
char sequence[12] = {0b11000011, 0b11011011, 0b11100011,
                     0b11000011, 0b11111011, 0b11100011,
                     0b11000011, 0b11011011, 0b11100011,
                     0b11010011, 0b11011011, 0b11110011};

void interrupt() {
     if(RCIF_bit) {
           if(OERR_bit) {
                CREN_bit = 0;
                CREN_bit = 1;

                OERR_bit = 0;
           }

           uart_rd = UART1_Read();

           RCIF_bit = 0;
     }
}

void SPI_Send(unsigned long s) {

     unsigned long mask = 0x800000;
     char i = 0;

     for(i = 0; i < 24; i++, mask >>= 1) {
           if(s & mask)
               DS = 1;
           else
               DS = 0;

           SH_CP = 1;
           Delay_ms(10);
           SH_CP = 0;
     }

     ST_CP = 1;
     Delay_ms(10);
     ST_CP = 0;
}

void main() {

     CMCON = 0x07;
     ADCON1 = 0x87;

     TRISA = 0xC0;
     TRISB = 0x00;
     TRISC = 0x80;
     TRISD = 0x00;

     PORTA = 0x00;
     PORTB = 0x00;
     PORTC = 0x00;
     PORTD = 0x00;

     SH_CP_Direction = 0;
     SH_CP = 0;

     ST_CP_Direction = 0;
     ST_CP = 0;

     DS_Direction = 0;
     DS = 0;

     UART1_Init(9615);
     Delay_ms(200);
     UART1_Write_Text("Send 0, 1, 2 or 3\r\n");
     UART1_Write_Text("-----------------\r\n\r\n");

     RCIE_bit = 1;
     PEIE_bit = 1;;
     GIE_bit = 1;

     while(1) {

           switch(uart_rd) {

                case '0':
                       i = 0;
                       break;
                case '1':
                       i = 3;
                       break;
                case '2':
                       i = 6;
                       break;
                case '3':
                       i = 9;
                       break;
           };

           if(uart_rd) {
               for(j = i; j < (i + 3); j++) {
                     SPI_Send(sequence[j]);
                     Delay_ms(2000);
               }

               uart_rd = 0;
           }

       }}
 

You have to send 24 bytes like 100100011110101000100101 (ascii characters) from UART.


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
sbit SH_CP at RD0_bit;
sbit SH_CP_Direction at TRISD0_bit;
 
sbit ST_CP at RD2_bit;
sbit ST_CP_Direction at TRISD2_bit;
 
sbit DS at RD1_bit;
sbit DS_Direction at TRISD1_bit;
 
char i = 0;
char buffer[24];
char index = 0;
unsigned long value2hc595 = 0;
 
void interrupt() {
 
     if(RCIF_bit) {
           if(OERR_bit) {
                 CREN_bit = 0;
                 CREN_bit = 1;
                 
                 OERR_bit = 0;
           }
           
           if(index < 24) {
                 buffer[index++] = UART1_Read();                 
           }
           
           RCIF_bit = 0;
     }
}
 
void SPI_Send(unsigned long s) {
 
     unsigned long mask = 0x800000;
     char i = 0;
     
     for(i = 0; i < 24; i++, mask >>= 1) {
           if(s & mask) 
               DS = 1;          
           else 
               DS = 0;
               
           SH_CP = 1;
           Delay_ms(10);
           SH_CP = 0;
     }
     
     ST_CP = 1;
     Delay_ms(10);
     ST_CP = 0;
}
 
void main() {
 
     CMCON = 0x07;
     ADCON1 = 0x87;
     
     TRISA = 0xC0;
     TRISB = 0x00;
     TRISC = 0x80;
     TRISD = 0x00;
     
     PORTA = 0x00;
     PORTB = 0x00;
     PORTC = 0x00;
     PORTD = 0x00;
     
     SH_CP_Direction = 0;    
     SH_CP = 0;     
 
     ST_CP_Direction = 0;    
     ST_CP = 0;
     
     DS_Direction = 0;
     DS = 0;
     
     UART1_Init(9615);
     Delay_ms(200);
     
     RCIF_bit = 0;
     RCIE_bit = 1;
     PEIE_bit = 1;
     GIE_bit = 1;
     
     while(1) {
 
              if(index == 23) {
                    for(i = 0; i < 24; i++) {
                           value2hc595 <<= 1;
 
                           if(buffer[i] == '1') {
                                  value2hc595 |= 1;
                           }
                    }
                    
                    SPI_Send(value2hc595);
                    
                    index = 0;
              }
     }
}







Edit. Try attached file. Send 111100000101010100001111 from PC to PIC.


I think it is better to make a matrix of solenoids like 10 X 10 = 100 micro solenoids. Then based on the character the required solenoids are turned ON.
 

Attachments

  • PIC16F877A +74HC595 + Solenoids + UART 20 MHz.rar
    85.9 KB · Views: 49
  • solenoids.png
    solenoids.png
    61 KB · Views: 67
Last edited:

I thought it is easy to make array than matrixing, so i gone with array

- - - Updated - - -

will try to make a software for pc and will update you
 

No need for software. just send ascii characters 1's and 0's. Isn't matrix and array ? Make 8 X8 matrix = 64 tiny solenoids. 8 HC595's are needed.


Make a matrix like shown in attached image. It is 5X8 matrix. There are 8 rows and 5 columns. Each column can be driven by one 74HC595 and you need 5 HC595s. Ascii character has to be converted to matrix data and send to the 5 cascaded HC595s.

You can also make 8 X 8 matrix. It will be better. 8 HC595 will be cascaded. Each HC595 will hold the data of one column or row.
 

Attachments

  • matrix.png
    matrix.png
    3.6 KB · Views: 55
Last edited:
  • Like
Reactions: varunme

    varunme

    Points: 2
    Helpful Answer Positive Rating
New code. Saves some RAM. Not tested.


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
sbit SH_CP at RD0_bit;
sbit SH_CP_Direction at TRISD0_bit;
 
sbit ST_CP at RD2_bit;
sbit ST_CP_Direction at TRISD2_bit;
 
sbit DS at RD1_bit;
sbit DS_Direction at TRISD1_bit;
 
char i = 0;
char buffer[2];
char index = 0, count = 0;
unsigned long value2hc595 = 0;
 
void interrupt() {
 
     if(RCIF_bit) {
           if(OERR_bit) {
                 CREN_bit = 0;
                 CREN_bit = 1;
                 
                 OERR_bit = 0;
           }
           
           buffer[index++] = UART1_Read();                 
                      
           RCIF_bit = 0;
     }
}
 
void SPI_Send(unsigned long s) {
 
     unsigned long mask = 0x800000;
     char i = 0;
     
     for(i = 0; i < 24; i++, mask >>= 1) {
           if(s & mask) 
               DS = 1;          
           else 
               DS = 0;
               
           SH_CP = 1;
           Delay_ms(10);
           SH_CP = 0;
     }
     
     ST_CP = 1;
     Delay_ms(10);
     ST_CP = 0;
}
 
void main() {
 
     CMCON = 0x07;
     ADCON1 = 0x87;
     
     TRISA = 0xC0;
     TRISB = 0x00;
     TRISC = 0x80;
     TRISD = 0x00;
     
     PORTA = 0x00;
     PORTB = 0x00;
     PORTC = 0x00;
     PORTD = 0x00;
     
     SH_CP_Direction = 0;    
     SH_CP = 0;     
 
     ST_CP_Direction = 0;    
     ST_CP = 0;
     
     DS_Direction = 0;
     DS = 0;
     
     UART1_Init(9615);
     Delay_ms(200);
     
     RCIF_bit = 0;
     RCIE_bit = 1;
     PEIE_bit = 1;
     GIE_bit = 1;
     
     while(1) {
 
              if(index) {
                    value2hc595 <<= 1;
                    if(buffer[0] == '1')
                          value2hc595 |= 1;
            
            index = 0;
            ++count;                           
              }
        
          if(count == 24) {                
                    SPI_Send(value2hc595);
            count = 0;
          }            
     }
}

 
  • Like
Reactions: varunme

    varunme

    Points: 2
    Helpful Answer Positive Rating
its not shifting
 

Which code you used ? Code in post #54 ? If yes, you need to send 24 x 1's or 0's and then the shifting happens.
 
  • Like
Reactions: varunme

    varunme

    Points: 2
    Helpful Answer Positive Rating
yes #54 , ok
yes working
 

You didn't give exact circuit. Make it a 8x5 or 8x8 solenoids. I will write code for you. How do you send characters ? Through UART ? No, need for array. switch statement is enough. Create as many cases as you have characters and each case based on the received character assigns a 24 bit value to a unsigned long variable and this variable is passed to SPI_Send() function which sends data to 74HC595.

Here is another version of code which receives '0' or '1' from UART and displays it on 74HC595 after 24 characters are received. It saves a few more bytes.

mikroC code. Not tested.


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
sbit SH_CP at RD0_bit;
sbit SH_CP_Direction at TRISD0_bit;
 
sbit ST_CP at RD2_bit;
sbit ST_CP_Direction at TRISD2_bit;
 
sbit DS at RD1_bit;
sbit DS_Direction at TRISD1_bit;
 
char uart_rd, count = 0;
unsigned long value2hc595 = 0;
 
void interrupt() {
 
     if(RCIF_bit) {
           if(OERR_bit) {
                 CREN_bit = 0;
                 CREN_bit = 1;
                 
                 OERR_bit = 0;
           }
           
           uart_rd = UART1_Read();                 
           ++count;
           
           RCIF_bit = 0;
     }
}
 
void SPI_Send(unsigned long s) {
 
     unsigned long mask = 0x800000;
     char i = 0;
     
     for(i = 0; i < 24; i++, mask >>= 1) {
           if(s & mask) 
               DS = 1;          
           else 
               DS = 0;
               
           SH_CP = 1;
           Delay_ms(2);
           SH_CP = 0;
     }
     
     ST_CP = 1;
     Delay_ms(2);
     ST_CP = 0;
}
 
void main() {
 
     CMCON = 0x07;
     ADCON1 = 0x87;
     
     TRISA = 0xC0;
     TRISB = 0x00;
     TRISC = 0x80;
     TRISD = 0x00;
     
     PORTA = 0x00;
     PORTB = 0x00;
     PORTC = 0x00;
     PORTD = 0x00;
     
     SH_CP_Direction = 0;    
     SH_CP = 0;     
 
     ST_CP_Direction = 0;    
     ST_CP = 0;
     
     DS_Direction = 0;
     DS = 0;
     
     UART1_Init(9615);
     Delay_ms(200);
     
     RCIF_bit = 0;
     RCIE_bit = 1;
     PEIE_bit = 1;
     GIE_bit = 1;
     
     while(1) {
 
              if(uart_rd) {
                    value2hc595 <<= 1;
                    if(uart_rd == '1')
                          value2hc595 |= 1;          
                                       
              }
 
          if(count == 24) {
            SPI_Send(value2hc595);
                    count = 0; 
          }         
     }
}

 
Last edited:
  • Like
Reactions: varunme

    varunme

    Points: 2
    Helpful Answer Positive Rating
ok, i will send the circuit as well as the binary to send
yes through uart

By the way each character in solenoid is 2x3 matrix, 7 characters, thus 42 solenoids
 
Last edited:

each character in solenoid is 2x3 matrix, 7 characters, thus 42 solenoids

Below is the table of case and binary to shift


Code:
Sl No	Case	Binary to shift
1	a	10000010000000
2	b	10100001000000
3	c	11000000100000
4	d	11010000010000
5	e	10010000001000
6	f	11100000000100
7	g	11110000000010
8	h	10110000000001
9	i	01100011000000
10	j	01100001100000
11	k	10001000110000
12	l	10101000011000
13	m	11001000001100
14	n	11011000000110
15	o	10011000000011
16	p	11101010000001
17	q	11111011100000
18	r	10111001110000
19	s	01101000111000
20	t	01111000011100
21	u	10001100001110
22	v	10101100000111
23	w	01110110000011
24	x	11001111000001
25	y	11011111110000
26	z	10111001111000
27	0	01110000111100
28	1	10000000011110
29	2	10100000001111
30	3	11000010000111
31	4	11010011000011
32	5	10010011100001


Schematic for the pic 595 and solenoid

 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top