-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.c
227 lines (170 loc) · 6.94 KB
/
main.c
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
#include <stdio.h>
#include "pico/stdlib.h"
#include <math.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include "pico/stdlib.h"
#include "pico/binary_info.h"
#include "hardware/gpio.h"
#include "hardware/i2c.h"
#include "nec_receive_library/nec_receive.h"
#include "nec_transmit_library/nec_transmit.h"
#define PIN_SDA 4 // I2C Data
#define PIN_SCL 5 // I2C Clock
//IR LED connected to pin 14
const int ADDRESS = 0x44;
const uint8_t adr = 0b10100000; // hardware address. Each node per hub has a unique 3-bit address. Use the 3 highest significant bits
const int repeat_transmissions = 64; // Number of times the same reading is transmitted in a row. More transmissions increase reliability
// but reduce the total number of readings that can be transmitted in a short time period
// I2C reserves some addresses for special purposes. We exclude these from the scan.
// These are any addresses of the form 000 0xxx or 111 1xxx
bool reserved_addr(uint8_t addr) {
return (addr & 0x78) == 0 || (addr & 0x78) == 0x78;
}
int main() {
const uint led_pin = 25;
int time_to_transmit_ms = 5000;
int time_to_sleep_min = 5;
int time_to_sleep_ms = (time_to_sleep_min * 60) * 1000;
// Initialize LED pin
gpio_init(led_pin);
gpio_set_dir(led_pin, GPIO_OUT);
// Initialize chosen serial port
stdio_init_all();
PIO pio = pio0; // choose which PIO block to use (RP2040 has two: pio0 and pio1)
uint tx_gpio = 14; // choose which GPIO pin is connected to the IR LED
uint rx_gpio = 15; // choose which GPIO pin is connected to the IR detector
// configure and enable the state machines
int tx_sm = nec_tx_init(pio, tx_gpio); // uses two state machines, 16 instructions and one IRQ
int rx_sm = nec_rx_init(pio, rx_gpio); // uses one state machine and 9 instructions
if (tx_sm == -1 || rx_sm == -1) {
printf("could not configure PIO\n");
return -1;
}
sleep_ms(5000);
printf("working USB out!");
// This example will use I2C0 on the default SDA and SCL pins (GP4, GP5 on a Pico)
i2c_init(i2c0, 100 * 1000);
gpio_set_function(PIN_SDA, GPIO_FUNC_I2C);
gpio_set_function(PIN_SCL, GPIO_FUNC_I2C);
gpio_pull_up(PIN_SDA);
gpio_pull_up(PIN_SCL);
/*
printf("\nI2C Bus Scan\n");
printf(" 0 1 2 3 4 5 6 7 8 9 A B C D E F\n");
for (int addr = 0; addr < (1 << 7); ++addr) {
if (addr % 16 == 0) {
printf("%02x ", addr);
}
// Perform a 1-byte dummy read from the probe address. If a slave
// acknowledges this address, the function returns the number of bytes
// transferred. If the address byte is ignored, the function returns
// -1.
// Skip over any reserved addresses.
int ret;
uint8_t rxdata;
if (reserved_addr(addr))
ret = PICO_ERROR_GENERIC;
else
ret = i2c_read_blocking(i2c0, addr, &rxdata, 1, false);
printf(ret < 0 ? "." : "@");
printf(addr % 16 == 15 ? "\n" : " ");
}
printf("Done.\n");
sleep_ms(1000);
*/
// printf("read from sht40\n");
uint8_t tx_bytes;
uint8_t rx_bytes[6];
uint16_t t_ticks;
uint8_t checksum_t;
uint16_t rh_ticks;
uint8_t checksum_rh;
float t_degC;
float rh_pRH;
uint32_t tx_frame;
// transmit and receive frames
uint8_t tx_address = 0x00, tx_data = 0x00, rx_address, rx_data;
uint8_t key = 0;
uint8_t msg_id = 0;
uint8_t random_key = 0;
// init time
absolute_time_t time = get_absolute_time();
// init random number generator
srand(time);
// Loop forever
while (true) {
time = get_absolute_time();
uint32_t starttime = to_ms_since_boot(time);
uint32_t endtime = starttime + time_to_transmit_ms;
while (starttime < endtime) {
time = get_absolute_time();
starttime = to_ms_since_boot(time);
gpio_put(led_pin, 1);
tx_bytes = 0xFD;
/*
for (int i = 0; i <= 6; i++)
printf("byte %d = %x\n", i, rx_bytes[i]);
*/
int bytes_written = i2c_write_blocking(i2c0, ADDRESS, &tx_bytes, 1, false);
// printf("Bytes Written = %d\n", bytes_written);
sleep_ms(10);
int bytes_read = i2c_read_blocking(i2c0, ADDRESS, rx_bytes, 6, false);
/*
printf("Bytes Read = %d\n", bytes_read);
printf("Buffer = %x\n", rx_bytes);
for (int i = 0; i <= 6; i++)
printf("byte %d = %x\n", i, rx_bytes[i]);
*/
t_ticks = (rx_bytes[0] * 256) + rx_bytes[1];
checksum_t = rx_bytes[2];
rh_ticks = (rx_bytes[3] * 256) + rx_bytes[4];
checksum_rh = rx_bytes[5];
// printf("t_ticks = %d\nrh_ticks = %d\n", t_ticks, rh_ticks);
t_degC = -45 + (175 * ((float)t_ticks/65535));
rh_pRH = -6 + (125 * ((float)rh_ticks/65535));
if (rh_pRH > 100)
rh_pRH = 100;
if (rh_pRH < 0)
rh_pRH = 0;
printf("Temperature: %.2f deg C\nRelative Humidity: %.2f%%\n", t_degC, rh_pRH);
// randomize address
random_key = rand() % 7;
key = random_key << 2;
printf("%x\n", random_key);
for (int i = 0; i < repeat_transmissions; i++) {
msg_id = 0;
tx_address = adr + key + msg_id;
tx_data = rx_bytes[0]; // t part 1
tx_frame = nec_encode_frame(tx_address, tx_data);
pio_sm_put(pio, tx_sm, tx_frame);
printf("sent: %02x, %02x\n", tx_address, tx_data);
sleep_ms(90);
msg_id = 1;
tx_address = adr + key + msg_id;
tx_data = rx_bytes[1]; // t part 2
tx_frame = nec_encode_frame(tx_address, tx_data);
pio_sm_put(pio, tx_sm, tx_frame);
printf("sent: %02x, %02x\n", tx_address, tx_data);
sleep_ms(90);
msg_id = 2;
tx_address = adr + key + msg_id;
tx_data = rx_bytes[3]; // rh part 1
tx_frame = nec_encode_frame(tx_address, tx_data);
pio_sm_put(pio, tx_sm, tx_frame);
printf("sent: %02x, %02x\n", tx_address, tx_data);
sleep_ms(90);
msg_id = 3;
tx_address = adr + key + msg_id;
tx_data = rx_bytes[4]; // rh part 2
tx_frame = nec_encode_frame(tx_address, tx_data);
pio_sm_put(pio, tx_sm, tx_frame);
printf("sent: %02x, %02x\n", tx_address, tx_data);
sleep_ms(90);
}
//gpio_put(led_pin, 0);
}
//sleep_ms(time_to_sleep_ms); // sleep mode to charge super cap
}
}