Skip to main content
3 of 4
add real data

Unexpected bit when shifting out (ATtiny85)

I'm trying to spoof a 433 MHz remote and I have a sequence of 32 bytes that I want to repeatedly shift out to one of ATtiny85's pins. The signal then goes to a cheap Chinese-type 433 Mhz transmitter.

I utilized the built-in 8-bit Timer/Counter0. Unfortunately, in constant places in my sequence there are glitches in form of repeated bits.

For example (byte no. 5):

Bit number (starting from 0) 40 41 42 43 44 45 46 47
Correct                       0  0  1  0  0  1  0  0
Actual                        0  0  0  1  0  0  1  0

enter image description here

My code:

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>

#define OUT PB2

uint8_t bit = 0; // current bit
const uint8_t data[32] PROGMEM = {
        0b10101010,
        0b10101010,
        0b10101010,
        0b00000000,
        0b01001001,
        0b00100100,
        0b11010011,
        0b01101101,
        0b00110100,
        0b10010011,
        0b01001101,
        0b10100110,
        0b11010010,
        0b01001101,
        0b10100100,
        0b10011010,
        0b01101001,
        0b10110110,
        0b10011010,
        0b01101101,
        0b10110100,
        0b11011011,
        0b01101101,
        0b10110110,
        0b11011010,
        0b01101101,
        0b10110100,
        0b11011010,
        0b01101000,
        0b00000000,
        0b00000000,
        0b00000000,
};

int main() {
    DDRB |= _BV(OUT);

    TCCR0A |= _BV(WGM01); // clear timer on compare match
    TIMSK |= _BV(OCIE0A);

    // 2 kbps
    TCCR0B |= _BV(CS01); // prescaler: 8
    OCR0A = 62; // timer counts to 62 instead of 255

    sei();

    while (1) { }
}

ISR (TIMER0_COMPA_vect) {
    if (pgm_read_byte(&(data[bit / 8])) & (1 << bit % 8)) { // read current bit from progmem array
        PORTB |= _BV(OUT);
    } else {
        PORTB &= ~_BV(OUT);
    }

    // I tried
    // if (bit == 255) bit = 0; else bit++;
    // but it made no difference, so i left it like this
    // because it's shorter
    bit++; // let it overflow
}

I wondered if somebody could help me to troubleshoot this or maybe propose a better solution to this task which is just shifting out bytes without a clock.

EDIT: A comparison between "measured" and correct sequence (always the same, even after looping many times)

Bit Correct Measured

0   1   1   
1   0   0   
2   1   1   
3   0   0   
4   1   1   
5   0   0   
6   1   1   
7   0   0   
8   1   1   
9   0   0   
10  1   1   
11  0   0   
12  1   1   
13  0   0   
14  1   1   
15  0   0   
16  1   1   
17  0   0   
18  1   1   
19  0   0   
20  1   1   
21  0   0   
22  1   1   
23  0   0   
24  0   0   
25  0   0   
26  0   0   
27  0   0   
28  0   0   
29  0   0   
30  0   0   
31  0   1   DIFFERENT
32  0   0   
33  1   0   DIFFERENT
34  0   1   DIFFERENT
35  0   0   
36  1   0   DIFFERENT
37  0   1   DIFFERENT
38  0   0   
39  1   0   DIFFERENT
40  0   0   
41  0   1   DIFFERENT
42  1   0   DIFFERENT
43  0   0   
44  0   1   DIFFERENT
45  1   0   DIFFERENT
46  0   0   
47  0   1   DIFFERENT
48  1   1   
49  1   0   DIFFERENT
50  0   0   
51  1   1   
52  0   0   
53  0   1   DIFFERENT
54  1   1   
55  1   1   
56  0   0   
57  1   1   
58  1   1   
59  0   0   
60  1   1   
61  1   1   
62  0   0   
63  1   0   DIFFERENT
64  0   0   
65  0   1   DIFFERENT
66  1   0   DIFFERENT
67  1   1   
68  0   1   DIFFERENT
69  1   0   DIFFERENT
70  0   0   
71  0   1   DIFFERENT
72  1   1   
73  0   0   
74  0   0   
75  1   1   
76  0   0   
77  0   0   
78  1   1   
79  1   1   
80  0   0   
81  1   1   
82  0   1   DIFFERENT
83  0   0   
84  1   0   DIFFERENT
85  1   1   
86  0   0   
87  1   0   DIFFERENT
88  1   1   
89  0   1   DIFFERENT
90  1   0   DIFFERENT
91  0   0   
92  0   1   DIFFERENT
93  1   0   DIFFERENT
94  1   1   
95  0   0   
96  1   1   
97  1   0   DIFFERENT
98  0   0   
99  1   1   
100 0   0   
101 0   1   DIFFERENT
102 1   1   
103 0   1   DIFFERENT
104 0   0   
105 1   1   
106 0   1   DIFFERENT
107 0   0   
108 1   0   DIFFERENT
109 1   1   
110 0   0   
111 1   0   DIFFERENT
112 1   0   DIFFERENT
113 0   1   DIFFERENT
114 1   0   DIFFERENT
115 0   0   
116 0   1   DIFFERENT
117 1   0   DIFFERENT
118 0   1   DIFFERENT
119 0   0   
120 1   1   
121 0   0   
122 0   1   DIFFERENT
123 1   1   
124 1   0   DIFFERENT
125 0   0   
126 1   1   
127 0   1   DIFFERENT
128 0   0   
129 1   0   DIFFERENT
130 1   1   
131 0   0   
132 1   1   
133 0   1   DIFFERENT
134 0   0   
135 1   0   DIFFERENT
136 1   1   
137 0   1   DIFFERENT
138 1   0   DIFFERENT
139 1   1   
140 0   1   DIFFERENT
141 1   0   DIFFERENT
142 1   1   
143 0   0   
144 1   1   
145 0   0   
146 0   1   DIFFERENT
147 1   1   
148 1   0   DIFFERENT
149 0   0   
150 1   1   
151 0   1   DIFFERENT
152 0   0   
153 1   1   
154 1   1   
155 0   0   
156 1   1   
157 1   1   
158 0   0   
159 1   0   DIFFERENT
160 1   0   DIFFERENT
161 0   1   DIFFERENT
162 1   0   DIFFERENT
163 1   1   
164 0   1   DIFFERENT
165 1   0   DIFFERENT
166 0   1   DIFFERENT
167 0   1   DIFFERENT
168 1   1   
169 1   0   DIFFERENT
170 0   1   DIFFERENT
171 1   1   
172 1   0   DIFFERENT
173 0   1   DIFFERENT
174 1   1   
175 1   1   
176 0   0   
177 1   1   
178 1   1   
179 0   0   
180 1   1   
181 1   1   
182 0   0   
183 1   0   DIFFERENT
184 1   1   
185 0   1   DIFFERENT
186 1   0   DIFFERENT
187 1   1   
188 0   1   DIFFERENT
189 1   0   DIFFERENT
190 1   1   
191 0   0   
192 1   1   
193 1   0   DIFFERENT
194 0   1   DIFFERENT
195 1   1   
196 1   0   DIFFERENT
197 0   1   DIFFERENT
198 1   1   
199 0   1   DIFFERENT
200 0   0   
201 1   1   
202 1   1   
203 0   0   
204 1   1   
205 1   1   
206 0   0   
207 1   0   DIFFERENT
208 1   0   DIFFERENT
209 0   1   DIFFERENT
210 1   0   DIFFERENT
211 1   1   
212 0   1   DIFFERENT
213 1   0   DIFFERENT
214 0   1   DIFFERENT
215 0   0   
216 1   1   
217 1   0   DIFFERENT
218 0   1   DIFFERENT
219 1   1   
220 1   0   DIFFERENT
221 0   1   DIFFERENT
222 1   1   
223 0   0   
224 0   0   
225 1   0   DIFFERENT
226 1   1   
227 0   0   
228 1   1   
229 0   1   DIFFERENT
230 0   0   
231 0   0   
232 0   0   
233 0   0   
234 0   0   
235 0   0   
236 0   0   
237 0   0   
238 0   0   
239 0   0   
240 0   0   
241 0   0   
242 0   0   
243 0   0   
244 0   0   
245 0   0   
246 0   0   
247 0   0   
248 0   0   
249 0   0   
250 0   0   
251 0   0   
252 0   0   
253 0   0   
254 0   0   
255 0   0   
256     0