This repository was archived by the owner on Jun 9, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.go
More file actions
129 lines (119 loc) · 2.79 KB
/
Copy pathmain.go
File metadata and controls
129 lines (119 loc) · 2.79 KB
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/*
A library for interacting with infrared remote controls which use the NEC protocol
*/
package rpiif
import (
"errors"
"fmt"
"math/big"
"time"
"github.com/stianeikeland/go-rpio/v4"
)
// Only used internally
type pulse struct {
Value uint8
Length int64
}
// Main module struct
type IfScanner struct {
Pin rpio.Pin
Initialized bool
Scanning bool
}
var (
Scanner = IfScanner{
Pin: 0,
Initialized: false,
Scanning: false,
}
)
var (
ErrInitialized = errors.New("cannot initialize scanner: scanner is already initialized")
ErrNotInitialized = errors.New("cannot scan: not initialized: use Setup() before scanning")
ErrAlreadyScanning = errors.New("cannot concurrently scan: wait until scanning is finished before starting another scan")
ErrCannotInitialize = errors.New("failed to initialize: hardware failure")
)
// Functions
// Scans for received codes, this method is blocking
// Can return errors ErrNotInitialized or ErrAlreadyScanning
// Returns the received code as a hexadecimal string
func (scanner *IfScanner) Scan() (string, error) {
if scanner.Scanning {
return "", ErrAlreadyScanning
}
if !scanner.Initialized {
return "", ErrNotInitialized
}
scanner.Scanning = true
var count1 int = 0
var command []pulse = make([]pulse, 0)
var binary = make([]byte, 0)
binary = append(binary, 1)
var previousValue uint8 = 0
var value = uint8(scanner.Pin.Read())
for value == 1 {
value = uint8(scanner.Pin.Read())
time.Sleep(time.Microsecond * 100)
}
startTime := time.Now()
for {
time.Sleep(time.Nanosecond * 50)
if value != previousValue {
now := time.Now()
pulseLength := now.Sub(startTime)
startTime = now
command = append(command, pulse{Value: previousValue, Length: pulseLength.Microseconds()})
}
if value == 1 {
count1 += 1
} else {
count1 = 0
}
if count1 > 10000 {
break
}
previousValue = value
value = uint8(scanner.Pin.Read())
}
for _, item := range command {
if item.Value == 1 {
if item.Length > 1000 {
binary = append(binary, 0)
binary = append(binary, 1)
} else {
binary = append(binary, 0)
}
}
}
if len(binary) > 34 {
binary = binary[:34]
}
res := ""
for _, v := range binary {
if v == 1 {
res += "1"
} else {
res += "0"
}
}
result := new(big.Int)
result.SetString(res, 2)
scanner.Scanning = false
return fmt.Sprintf("%x", result), nil
}
// Initializes the scanner and binds it to a certain pin
// Example: `scanner.Setup(4)`
// This function has to be called before using `scanner.Scan()`
func (scanner *IfScanner) Setup(pinNumber uint8) error {
if scanner.Initialized {
return ErrInitialized
}
if err := rpio.Open(); err != nil {
return err
}
// Set the pin to input
scanner.Pin = rpio.Pin(pinNumber)
scanner.Pin.Input()
scanner.Initialized = true
return nil
}