Hey, still pretty noob here but I have tried to make a packet system so I can send an integer via a 433Mhz module with an attiny85 MCU, to an RX module with an Attiny85 that then passes the values to an arduino via Software Serial.
Attiny85 -------433Mhz------> Attiny85 ----------SoftSerial--------->UNO
Well, it works...but it is not exactly the output id expect.
In short my packet data "should be" like this:
Byte1 : First half of start_int : 255
Byte 2: Second of start_int : 255
Byte 3: First half temperature int : Usually 0 (temp under 255).
Byte 4: Second half of temperature int: Usually around 19-35 (heated with hands etc.)
Byte 5: First half Battery Volts in mV: Varies...
Byte 6: Second half of Batttery Volts in mV: Varies...
Byte 7 and 8: The parts of the end_of_message int : 255,254.
But I seem to be missing Bytes 3 and 5, 7 and 8 in my captured data...
Here is my code, I assume I am just doing something daft. There is a positive response to charging the super cap and heating/cooling the sensor. Just missing the first 8bits of the ints for them it seems!
The Transmitter on ATTiny85:
/*
Manchester Transmitter example
In this example transmitter will send one 16 bit number
per transmission.
Try different speeds using these constants, your maximum
possible speed will depend on various factors like transmitter
type, distance, microcontroller speed, ...
MAN_300 0
MAN_600 1
MAN_1200 2
MAN_2400 3
MAN_4800 4
MAN_9600 5
MAN_19200 6
MAN_38400 7
WATCHDOG TIMER SETUP VALUES: // 0=16ms, 1=32ms,2=64ms,3=128ms,4=250ms,5=500ms
// 6=1 sec,7=2 sec, 8=4 sec, 9= 8sec
*/
//D4 = LED
//D0 = DS1820 Data line
//D1 = Data Line 433Mhz TX
#include <Manchester.h>
#include <avr/sleep.h>
#include <avr/wdt.h>
#include <OneWire.h>
OneWire TemperatureSensor(0); // Dallas one wire data buss pin, a 4.7K resistor pullup is needed
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif
#define TX_PIN 1 //pin where your transmitter is connected
uint16_t transmit_data = 0; // a 16 bit unsigned int to hold data (2 bytes +ve) for transmit by 433Mhz.
float sleep_minutes=0.1;
volatile boolean f_wdt = 0; // Flasg for WDT
byte num_sleeps = 0; // COunt times slept for extended sleep. Wake->Count->Sleep
byte led = 4; // The LED pin
uint16_t endbytes=65536;
uint16_t startbytes=65535;
//======CODE FOR LED BLINKS=====//
/* These LED functions blink the tens and units of a number 1-99.
They blink_tens divides the int by ten and flashes the LED that many times.
The blink_units does the same, except is the modulus (remainder) when the number is divided by 10.
*/
void blink_tens(byte tens) {
for (byte i = 0; i < tens; i++) {
digitalWrite(led, 1);
delay (250);
digitalWrite(led, 0);
delay (125);
}
}
void blink_units(byte units) {
delay(150);
for (byte i = 0; i < units; i++) {
digitalWrite(led, 1);
delay (125);
digitalWrite(led, 0);
delay (60);
}
}
//===========END OF CODE FOR LED BLINKS===========//
void setup() {
setup_watchdog(9); // approximately 2 seconds sleep
man.setupTransmit(TX_PIN, MAN_300); // Set up the 433Mhz library -> Setting for max range (300 BAUD / 300bps).
pinMode(4, OUTPUT); // Set the LED as an output pin.
}
void loop() {
if (f_wdt == 1) { // If the watchdog has just been triggered and now back in program, do the stuff in loop()
f_wdt = 0;
while (num_sleeps < 7.5*sleep_minutes) { // WD set to 8 seconds (setting 9), 60/8 = 7.5 So sleep minutes required * 7.5 = how long sleep will occur between measurements.
system_sleep();
num_sleeps++;
}
num_sleeps = 0;
byte i;
byte data[12];
int16_t raw;
int celsius;
TemperatureSensor.reset(); // reset one wire buss
TemperatureSensor.skip(); // select only device
TemperatureSensor.write(0x44); // start conversion
while (!TemperatureSensor.read()) { // WHILE there is no data to read (waiting for conversion), turn the LED On to show it is waiting for a conversion.
digitalWrite(led, 0);
}
digitalWrite(led, 0);
TemperatureSensor.reset();
TemperatureSensor.skip();
TemperatureSensor.write(0xBE); // Read Scratchpad
for ( i = 0; i < 9; i++) { // 9 bytes
data[i] = TemperatureSensor.read();
}
// Convert the data to actual temperature
raw = (data[1] << 8) | data[0];
celsius = (int)raw / 16.0;
transmit_data = (int)celsius;
man.transmit(startbytes);
delay(100);
man.transmit(transmit_data);
delay(100);
man.transmit(readVcc());
delay(100);
man.transmit(endbytes);
delay(100);
low_volt_chk(readVcc());
}
}
void low_volt_chk(int millivolts) { // Low voltage, just sleep till mV is > 2.8
int x = 0;
int current_mV;
current_mV = millivolts;
while (current_mV < 2800) { // While the millivolts<2800...
while (x < 10) { // 1. // While x is less than 10, sleep.
system_sleep();
x++;
}
x = 0; // 2. // Reset x
current_mV = readVcc(); // 3. //read capacitor millivolts....if it is still under 2800, the loop will repeat at step 1.
}
}
int readVcc() {
// Read 1.1V reference against AVcc
// // set the reference to Vcc and the measurement to the internal 1.1V reference
// #if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
// ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
// #elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
// ADMUX = _BV(MUX5) | _BV(MUX0);
#if defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
ADMUX = _BV(MUX3) | _BV(MUX2);
#endif
delay(2); // Wait for Vref to settle
ADCSRA |= _BV(ADSC); // Start conversion
while (bit_is_set(ADCSRA, ADSC)); // measuring
uint8_t low = ADCL; // must read ADCL first - it then locks ADCH
uint8_t high = ADCH; // unlocks both
int result = (high << 8) | low;
result = 1125300L / result; // Calculate Vcc (in mV); 1125300 = 1.1*1023*1000
return result; // Vcc in millivolts
}
void system_sleep() {
cbi(ADCSRA, ADEN); // switch Analog to Digitalconverter OFF
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode is set here
sleep_enable();
sleep_mode(); // System sleeps here
sleep_disable(); // System continues execution here when watchdog timed out
sbi(ADCSRA, ADEN); // switch Analog to Digitalconverter ON
}
void setup_watchdog(int ii) {
byte bb;
int ww;
if (ii > 9 ) ii = 9;
bb = ii & 7;
if (ii > 7) bb |= (1 << 5);
bb |= (1 << WDCE);
ww = bb;
MCUSR &= ~(1 << WDRF);
// start timed sequence
WDTCR |= (1 << WDCE) | (1 << WDE);
// set new watchdog timeout value
WDTCR = bb;
WDTCR |= _BV(WDIE);
}
ISR(WDT_vect) {
f_wdt = 1; //set global flag to 1.
}
The Code on the "433Mhz to SoftSerial" Attiny85 converter:
#include <Manchester.h>
#include<SoftwareSerial.h>
SoftwareSerial mys(1,2);
/*
Manchester Receiver example
In this example receiver will receive one 16 bit number per transmittion
try different speeds using this constants, your maximum possible speed will
depend on various factors like transmitter type, distance, microcontroller speed, ...
MAN_300 0
MAN_600 1
MAN_1200 2
MAN_2400 3
MAN_4800 4
MAN_9600 5
MAN_19200 6
MAN_38400 7
*/
#define RX_PIN 0
#define led 4
int x=0;
long time_start=millis();
void setup() {
pinMode(led, OUTPUT);
digitalWrite(led, 1);
man.setupReceive(RX_PIN, MAN_300);
man.beginReceive();
mys.begin(9600);
time_start=millis();
}
void loop() {
if (man.receiveComplete()) {
x++;
uint16_t m = man.getMessage();
man.beginReceive(); //start listening for next message right after you retrieve the message
mys.write(m);
delay(50);
}
}