1-Wire tester, shows ROM code and temperature on an LCD screen
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1wire-tester/main.c

158 lines
3.9 KiB

#include <avr/io.h> // register definitions
#include <avr/pgmspace.h> // storing data in program memory
#include <avr/interrupt.h> // interrupt vectors
#include <util/delay.h> // delay functions
#include <stdint.h> // C header for int types like uint8_t
#include <stdbool.h> // C header for the bool type
#include <stdlib.h>
#include <stdio.h>
// Include stuff from the library
#include "lib/iopins.h"
#include "lib/usart.h"
#include "lcd.h"
#include "onewire.h"
// Pins
#define LED 13
#define OW_PIN D9
void _lcd_wait_bf();
void _lcd_write_byte(uint8_t bb);
#if 0
// UART receive handler
ISR(USART_RX_vect)
{
// "ECHO" function:
uint8_t b = usart_rx();
usart_tx(b); // send back
}
#endif
void main()
{
#if 0
usart_init(BAUD_115200);
usart_isr_rx_enable(true); // enable RX interrupt handler
#endif
// configure pins
as_output(LED);
lcd_init();
lcd_clear();
lcd_puts("");
// globally enable interrupts (for the USART_RX handler)
sei();
uint8_t addr[8];
char charbuf[21];
int dots = 0;
bool signal = false, last_signal;
while (1) {
last_signal = signal;
signal = ow_reset(OW_PIN);
if (!signal) {
if (last_signal) {
lcd_clear();
}
lcd_puts_xy(0,0,"No 1-Wire detected..");
dots = 0;
} else {
if (!last_signal) {
lcd_clear();
}
ow_write(OW_PIN, 0x33);
ow_read_arr(OW_PIN, addr, 8);
// Show chip type
switch (addr[0]) {
case 0x10:
sprintf(charbuf, "18S20 ");
break;
case 0x28:
sprintf(charbuf, "18B20 ");
break;
case 0x01:
sprintf(charbuf, "iButton");
break;
default:
sprintf(charbuf, "UNKNOWN");
break;
}
lcd_puts_xy(12, 0, charbuf);
// Show address
char *p = charbuf;
for(uint8_t i = 0; i < 4; i++) {
p += sprintf(p, "%02X", addr[i]);
if (i < 3) *p++ = ':';
}
lcd_puts_xy(0, 0, charbuf);
p = charbuf;
for(uint8_t i = 0; i < 4; i++) {
p += sprintf(p, "%02X", addr[4+i]);
if (i < 3) *p++ = ':';
}
lcd_puts_xy(0, 1, charbuf);
// Measure temperature
int16_t cels;
if (addr[0] == 0x10 || addr[0] == 0x28) {
ds18x20_single_measure(OW_PIN);
if (addr[0] == 0x10) {
// 18S20
cels = ds18s20_read_temp_c(OW_PIN);
} else {
// 18B20
cels = ds18b20_read_temp_c(OW_PIN);
}
if (cels == TEMP_ERROR || cels == 850) {
lcd_xy(12, 1);
for (uint8_t i = 0; i <= dots; i++) {
lcd_putc('.');
}
dots = (dots + 1) % 3;
}
else {
p = charbuf;
if (cels < 0) {
*p++ = '-';
cels = -cels;
}
p += sprintf(p, "%d", cels / 10);
*p++ = '.';
p += sprintf(p, "%d", cels % 10);
*p++ = 0xDF; // ring symbol
*p++ = 'C';
*p++ = ' '; // padding to prevent artifacts if the number shrinks (we're not clearing screen when 1w is connected)
*p++ = ' ';
*p++ = ' ';
*p = 0;
lcd_puts_xy(12, 1, charbuf);
}
}
}
pin_toggle(13); // blink the LED
_delay_ms(100);
}
}