News:

;) This forum is the property of Proton software developers

Main Menu

how to use shift register in 1 pin to control 8 LEDs

Started by Abdullah, Aug 27, 2025, 02:11 PM

Previous topic - Next topic

Abdullah

Hello everyone i need a program for shift register IC 74hc595 to turn On Off  8 LEDs using 1 pin pic 16f887

Frizie

Abdullah, see the Positron help file, look at the Shout instruction.
You can find the help in your Positron compiler self:
ALT+H  >  Documents  >  0-Positron8 Manual
Ohm sweet Ohm | www.picbasic.nl

Pepe

demo proteus for 7 leds

;-------------------------------------------------------------------------------
;**** Added by Fuse Configurator ****
; Use the Fuse Configurator plug-in to change these settings

Device = 16F887

Config1 FOSC_HS, WDTE_OFF, PWRTE_OFF, MCLRE_OFF, CP_OFF, CPD_OFF, BOREN_OFF, IESO_OFF, FCMEN_OFF, LVP_OFF, DEBUG_OFF
Config2 BOR4V_BOR40V, WRT_OFF

;**** End of Fuse Configurator Settings ****
;-------------------------------------------------------------------------------

 
Declare Xtal = 20
Declare Optimiser_Level = 3
Declare Bootloader off
Declare Create_Coff On
Declare Reminders off
Declare Watchdog off

Symbol Led_Pin PORTB.0   
Dim count As Byte = 0


TRISB.0 = 0
PinSet Led_Pin

Do
For count=0 To 127 
  write(count)
  DelayMS 400
Next 
Loop

Proc write (dato As Byte)
Dim ld As Byte

 Rol dato   
 
 For ld = 6 To 0 Step -1                  ' Create a loop for the 7-bits to shift
  Rol dato                                ' Shift the bits left
  If STATUSbits_C <>0 Then                ' Is the Carry Flag set?
                           PinClear Led_Pin
                           DelayUS 1                 ' Delay 1 µs
                           PinSet Led_Pin
                       Else
                           PinClear Led_Pin
                           DelayUS 10                ' Delay 10 µs
                           PinSet Led_Pin
  EndIf
 Next
                 
 ' Alter the Latch pin
 '
 PinClear Led_Pin
 DelayUS 40                               ' Delay 40 µs for Latch
 PinSet Led_Pin
 DelayUS 5                                ' Delay 5 µs
EndProc

Abdullah

hello sir how to add  an input button to change LEDs using one button on first pulse 1st led should bright up and on 2nd pulse 2nd led should bright up
 

Abdullah

Sir this code add with irx remote control program 16c72A

Pepe

;---------------------------------------------------------------
Device = 16F887
Config1 FOSC_HS, WDTE_OFF, PWRTE_OFF, MCLRE_OFF, CP_OFF, CPD_OFF, BOREN_OFF, IESO_OFF, FCMEN_OFF, LVP_OFF, DEBUG_OFF
Config2 BOR4V_BOR40V, WRT_OFF

Declare Xtal = 20
Declare Optimiser_Level = 3
Declare Bootloader Off
Declare Create_Coff On
Declare Reminders Off
Declare Watchdog Off

'--- Pin único para 74HC595 (dato + clock + latch) ---
Symbol OneWire = PORTB.0
TRISB.0 = 0
PinSet OneWire             ' Línea inicia en alto (capacitor cargado)
DelayMS 10

'--- Tiempos (µs) ---
Symbol T0      = 30       ' ancho pulso de descarga para "0"
Symbol T1      = 5        ' ancho pulso de descarga para "1"
Symbol TSETTLE = 80       ' tiempo de asentamiento nodo RC
Symbol TLATCH  = 300      ' pulso de latch
Symbol TSPACE  = 10       ' espacio entre bits
Symbol sw PORTA.0
Dim n As Byte
Dim pattern As Byte  = 1
Dim flg As Bit
Do
If sw = 0 And flg = 0 Then
                            flg = 1
                            ShiftOut_OneWire(pattern)
                            Latch595()
                            pattern = pattern << 1
                            If pattern = 0 Then pattern = 1
                       Else         
                            If sw = 1 Then flg = 0
EndIf                           
 
Loop

'--------------------------------
' Procedimiento: genera pulso de descarga en la línea OneWire
Proc PulseWidth(anchous As Word)
    PinClear OneWire
    DelayUS anchous
    PinSet OneWire
EndProc

' Envía un bit LSB primero con asentamiento
Proc SendBit(b As Bit)
    If b = 0 Then
        PulseWidth(T0)
    Else
        PulseWidth(T1)
    EndIf
    DelayUS TSETTLE
EndProc

' Envía 8 bits LSB primero
Proc ShiftOut_OneWire(dato As Byte)
    Dim bi As Byte
    For bi = 0 To 7
        SendBit(dato.7)
        dato = dato << 1
    Next
EndProc

' Pulso final para actualizar el latch del 74HC595
Proc Latch595()
    PulseWidth(TLATCH)
    DelayUS TSPACE
EndProc


Abdullah

Hola, ¿puedo conectar un control remoto a su interruptor de botón actual para que, al presionar cualquier botón, se encienda un LED y, al presionar otro, se encienda otro LED? De igual manera, todos los LED se encienden al presionar un botón y, al presionar un botón específico, se apagan todos. Muchas gracias.

Abdullah

Hello sir, can I connect a remote control to your existing button switch so that by pressing any button on the remote, one LED turns on and by pressing another button, another LED turns on. Similarly, all the LEDs turn on by pressing a button and by pressing a specific button, all the LEDs turn off. Thank you very much.

Pepe

demo proteus with code for 8 leds control with nec ir protocol

' =======================================
' NEC IR Remote Receiver - PIC16C72A
' Proton IDE / Positron BASIC
' =======================================

;-------------------------------------------------------------------------------
;**** Added by Fuse Configurator ****
; Use the Fuse Configurator plug-in to change these settings

Device = 16C72A

Config FOSC_HS, WDTE_OFF, PWRTE_OFF, CP_OFF, BOREN_OFF

;**** End of Fuse Configurator Settings ****
;-------------------------------------------------------------------------------
Xtal   = 20                     ' 20 MHz crystal
Declare Optimiser_Level = 3
Declare Create_Coff On
Declare Watchdog off

' NEC Protocol Timings (µs)
' -------------------------------
Symbol NEC_START_PULSE = 9000/2   ' 9 ms start pulse
Symbol NEC_START_SPACE = 4500/2   ' 4.5 ms start space
PORTB=0
TRISB = 0

' -------------------------------
' IR Sensor Input
' -------------------------------
Symbol IR_Sensor = PORTA.0
Input IR_Sensor

' -------------------------------
' Variables
' -------------------------------
Dim necCode As Dword
Dim timeout As Word

Do
 
 necCode = Read_NEC_Remote()

 If necCode.Byte0 <> 0 Then
 
                           Select Case necCode.Byte3
                             
                             Case $03
                                    PORTB = 0
                             Case $07
                                   Toggle PORTB.0                 
                             Case $0B
                                    Toggle PORTB.1       
                             Case $0f
                                    Toggle PORTB.2 
                             Case $13
                                    Toggle PORTB.3       
                             Case $17
                                    Toggle PORTB.4 
                             Case $1B
                                    Toggle PORTB.5       
                             Case $1f
                                    Toggle PORTB.6 
                             Case $23
                                    Toggle PORTB.7
                             Case $27
                                    PORTB = $ff       
                           EndSelect
       
 EndIf
 
Loop
   
   

' ===============================
' Read NEC Remote Code
' ===============================
Proc Read_NEC_Remote(), Dword
Dim bitCount  As Byte   
Dim spaceWidth As Word
 
 Result = 0   
 
 If Wait_For_Start() = 0 Then ExitProc
   
 If Wait_For_Space() = 0 Then ExitProc                   
   
   
   
 For bitCount = 0 To 31
        spaceWidth =  Read_Bit()
        If timeout = 0 Then
                            Result = 0
                            ExitProc
        EndIf
        ' NEC: 560us pulse + (560 for 0) / (1690 for 1) space
        If spaceWidth > 600 Then
            SetBit Result, bitCount       ' logic 1
        Else
            ClearBit Result, bitCount     ' logic 0
        End If
 Next bitCount
   
EndProc


' ===============================
' Wait for Start Pulse (˜9 ms)
' ===============================
Proc Wait_For_Start(),Bit
Dim timewait As Word  = 10000
   
    While IR_Sensor = 1
        Dec timewait
        If timewait = 0 Then
                             Result = 0
                             ExitProc
        EndIf                     
    Wend
    Result = 1
EndProc


' ===============================
' Wait for Start Space (˜4.5 ms)
' ===============================
Proc Wait_For_Space(),Bit
Dim space As Word
    ' Use proper PulseIn syntax with timeout as the last parameter
    space = PulseIn IR_Sensor, 1
    If space > NEC_START_SPACE * 0.7 And space < NEC_START_SPACE * 1.3 Then
                                                                          Result = 1
                                                                     Else
                                                                          Result = 0     
    EndIf
EndProc


' ===============================
' Read Single Bit
' ===============================
Proc Read_Bit(), Word
timeout = 1 
    ' 560us (0) or 1690us (1) space - use proper PulseIn syntax
    Result = PulseIn IR_Sensor, 1
    If Result < 200 Then timeout = 0
EndProc

' =======================================
' End of Program
' =======================================

Abdullah

Thanks a lot SIR god bless you your angel in my life

Muchas gracias SEÑOR Dios lo bendiga su ángel en mi vida

Abdullah

Sir how to convert  $03,$23, in Decimal and what is meaning of this $03,$23

Abdullah

' =======================================
' NEC IR Remote Receiver - PIC16C72A
' Proton IDE / Positron BASIC
' Con NEC clásico, extendido y repeat automático
' =======================================

Device = 16C72A
Config FOSC_HS, WDTE_OFF, PWRTE_OFF, CP_OFF, BOREN_OFF

Xtal   = 20                     ' 20 MHz crystal
Declare Optimiser_Level = 3
Declare Create_Coff On
Declare Watchdog Off

' -------------------------------
' LCD Configuration (16x2)
' -------------------------------
Declare LCD_DTPin PORTC.0
Declare LCD_ENPin PORTC.5
Declare LCD_RSPin PORTC.4
Declare LCD_Interface 4
Declare LCD_Lines 2
Declare LCD_Type  0

' -------------------------------
' NEC Protocol Timings (µs)
' -------------------------------
Symbol NEC_START_PULSE  = 9000/2
Symbol NEC_START_SPACE  = 4500/2
Symbol NEC_REPEAT_SPACE = 2250/2

' -------------------------------
' IR Sensor Input
' -------------------------------
Symbol IR_Sensor = PORTA.0
Input IR_Sensor

' -------------------------------
' Variables
' -------------------------------
Dim necCode    As Dword
Dim bitCount   As Byte
Dim Result     As Word
Dim spaceWidth As Word
Dim timewait   As Word
Dim timeout    As Bit

Dim Addr    As Word
Dim Cmd     As Word
Dim necMode As Byte   ' 0=invalido,1=NEC clasico,2=NEC ext
Dim repeatFlag As Bit

Dim LastAddr As Word
Dim LastCmd  As Word

' ===============================
' Main Program
' ===============================
Cls
Print At 1,1, "16C72A IR Test"

Main_Loop:
    GoSub Read_NEC_Remote
    If timeout = 1 Then
        If repeatFlag = 1 Then
            ' Repetir último comando
            Addr = LastAddr
            Cmd  = LastCmd
        Else
            GoSub DecodeNEC
            ' Guardar último comando válido
            LastAddr = Addr
            LastCmd  = Cmd
        End If

        ' Mostrar en LCD
        If necMode = 1 Then
            Print At 2,1, "ADD:", Hex2 Addr, " CMD:", Hex2 Cmd, "   "
        ElseIf necMode = 2 Then
            Print At 2,1, "ADD:", Hex4 Addr, " CMD:", Hex4 Cmd
        Else
            Print At 2,1, "Codigo invalido   "
        EndIf
    End If
     


 If necCode.Byte0 <> 0 Then
 
                           Select Case necCode.Byte3
                             
                             Case $03
                                    PORTB = 0
                             Case $07
                                   Toggle PORTB.0                 
                             Case $0B
                                    Toggle PORTB.1       
                             Case $0f
                                    Toggle PORTB.2 
                             Case $13
                                    Toggle PORTB.3       
                             Case $17
                                    Toggle PORTB.4 
                             Case $1B
                                    Toggle PORTB.5       
                             Case $1f
                                    Toggle PORTB.6 
                             Case $23
                                    Toggle PORTB.7
                             Case $27
                                    PORTB = $ff       
                           EndSelect
       
 EndIf
 
    GoTo Main_Loop
   

' ===============================
' Read NEC Remote Code
' ===============================
Read_NEC_Remote:
    GoSub Wait_For_Start
    If timeout = 0 Then Return
    GoSub Wait_For_Space
    If timeout = 0 Then Return
    If repeatFlag = 1 Then Return   ' repetir último comando
   
    necCode = 0
    For bitCount = 0 To 31
        GoSub Read_Bit
        If timeout = 0 Then Return
       
        If spaceWidth > 600 Then
            SetBit necCode, bitCount       ' logic 1
        Else
            ClearBit necCode, bitCount     ' logic 0
        End If
    Next bitCount
    Return

' ===============================
' Wait for Start Pulse (~9 ms)
' ===============================
Wait_For_Start:
    timewait = 10000
    While IR_Sensor = 1
        Dec timewait
        If timewait = 0 Then
            timeout = 0
            Return
        EndIf                     
    Wend
    timeout = 1
    Return

' ===============================
' Wait for Start Space (4.5 ms o 2.25 ms)
' ===============================
Wait_For_Space:
    Result = PulseIn IR_Sensor, 1
    repeatFlag = 0
    If Result > NEC_START_SPACE * 0.7 And Result < NEC_START_SPACE * 1.3 Then
        timeout = 1
    ElseIf Result > NEC_REPEAT_SPACE * 0.7 And Result < NEC_REPEAT_SPACE * 1.3 Then
        repeatFlag = 1
        timeout = 1
    Else
        timeout = 0
    End If
    Return

' ===============================
' Read Single Bit
' ===============================
Read_Bit:
    spaceWidth = PulseIn IR_Sensor, 1
    If spaceWidth < 200 Then
        timeout = 0
        Return
    End If
    timeout = 1
    Return

' ===============================
' Decode NEC (clásico o extendido)
' ===============================
DecodeNEC:
    necMode = 0
   
    ' --- Caso NEC clásico ---
    If necCode.Byte0 ^ necCode.Byte1 = $FF And necCode.Byte2 ^ necCode.Byte3 = $FF Then
       Addr = necCode.Byte0
       Cmd  = necCode.Byte2
       necMode = 1
       Return
    EndIf

    ' --- Caso NEC extendido ---
    Addr.HighByte = necCode.Byte1
    Addr.LowByte  = necCode.Byte0   ' Dirección de 16 bits

    Cmd.HighByte  = necCode.Byte3
    Cmd.LowByte   = necCode.Byte2   ' Comando de 16 bits

    necMode = 2
    Return

' =======================================
' End of Program
' =======================================
PORTB.2 AND PORTB.6 NOT WORKING NOT TURNING ON

Pepe

moved to code examples

Abdullah

Thank you very much Sir i don't have word to thankful to you