Nuke - Elektro Bastlirna: Diskuzní fórum
Zobrazit předchozí téma :: Zobrazit následující téma
Autor
Zpráva
Honza_dy Založen: Aug 20, 2004 Příspěvky: 2172 Bydliště: Brno-venkov
Zaslal: so duben 27 2019, 22:44 Předmět: V jakém prostředí naprogramovat Attiny44 ?
Koupil jsem na Ebay kapacitní čidla vlhkosti do květináčů. Je to udělané podle opensource projektu Chirp! .
Problém je v tom, že při vyčítání dat přes I2C se to chová divně a hodnoty nejsou na svých adresách. Vzhledem k tomu, že nemám tušení co tam číňan nasypal, chtěl bych program přehrát původním projektem . Akorát fakt netuším v čem program zkompilovat a nahrát do procesoru. Doteď jsem dělal jen s arduinem.
Programátor mám doma jen usbAsp, tím by to snad mělo jít. Jen mi prosím poraďte jaký SW použít? Naposledy upravil Honza_dy dne ne duben 28 2019, 9:57, celkově upraveno 1 krát.
Návrat nahoru
PCmaniac99 Založen: Feb 07, 2008 Příspěvky: 793 Bydliště: Jablonec nad Nisou
Zaslal: ne duben 28 2019, 8:07 Předmět:
Tady něco je.
EDIT: Tohle bude asi přesně ono, četl jsem jen úvod.
Návrat nahoru
Honza_dy Založen: Aug 20, 2004 Příspěvky: 2172 Bydliště: Brno-venkov
Zaslal: ne duben 28 2019, 10:01 Předmět:
Asi si nerozumíme. Nemám problém s HW částí. Potřeboval bych poradit v jakém vývojovém prostředí zkompilovat projekt z githubu abych jej dostal do procesoru. V arduino IDE to samozřejmě nejde.
Program:
kód: #include <inttypes.h>
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>
#include <avr/sleep.h>
#include <avr/eeprom.h>
#include "usiTwiSlave.h"
#define USI_SCK PA4
#define USI_MISO PA5
#define USI_CS PA6
#define BUZZER PA7
#define BUTTON PB2
#define LED_K PB0
#define LED_A PB1
//------------ peripherals ----------------
void inline initBuzzer() {
TCCR0A = 0; //reset timer1 configuration
TCCR0B = 0;
TCCR0A |= _BV(COM0B1); //Clear OC0B on Compare Match when up-counting. Set OC0B on Compare Match when down-counting.
TCCR0A |= _BV(WGM00); //PWM, Phase Correct, 8-bit
TCCR0B |= _BV(CS00); //start timer
}
void inline static beep() {
initBuzzer();
OCR0B = 48;
_delay_ms(42);
TCCR0B = 0; //stop timer
PORTA &= ~_BV(BUZZER);
}
void inline ledOn() {
DDRB |= _BV(LED_A) | _BV(LED_K); //forward bias the LED
PORTB &= ~_BV(LED_K); //flash it to discharge the PN junction capacitance
PORTB |= _BV(LED_A);
}
void inline ledOff() {
DDRB &= ~(_BV(LED_A) | _BV(LED_K)); //make pins inputs
PORTB &= ~(_BV(LED_A) | _BV(LED_K));//disable pullups
}
void static chirp(uint8_t times) {
PRR &= ~_BV(PRTIM0);
while (times-- > 0) {
beep();
_delay_ms(40);
}
PRR |= _BV(PRTIM0);
}
//------------------- initialization/setup-------------------
void inline setupGPIO() {
PORTA |= _BV(PA0); //nothing
PORTA &= ~_BV(PA0);
PORTA |= _BV(PA2); //nothing
PORTA &= ~_BV(PA2);
PORTA |= _BV(PA3); //nothing
PORTA &= ~_BV(PA3);
DDRA |= _BV(BUZZER); //piezo buzzer
PORTA &= ~_BV(BUZZER);
DDRB |= _BV(PB0); //nothing
PORTB &= ~_BV(PB0);
DDRB |= _BV(PB1); //nothing
PORTB &= ~_BV(PB1);
DDRB |= _BV(PB2); //sqare wave output
PORTB &= ~_BV(PB2);
}
void inline setupPowerSaving() {
DIDR0 |= _BV(ADC1D); //disable digital input buffer on AIN0 and AIN1
PRR |= _BV(PRTIM1); //disable timer1
PRR |= _BV(PRTIM0); //disable timer0
ADCSRA &=~ _BV(ADEN);
PRR |= _BV(PRADC);
PRR |= _BV(PRUSI);
}
//--------------- sleep / wakeup routines --------------
void inline initWatchdog() {
WDTCSR |= _BV(WDCE);
WDTCSR &= ~_BV(WDE); //interrupt on watchdog overflow
WDTCSR |= _BV(WDIE); //enable interrupt
WDTCSR |= _BV(WDP1) | _BV(WDP2); //every 1 sec
}
ISR(WATCHDOG_vect ) {
// nothing, just wake up
}
void inline sleep() {
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable();
MCUCR |= _BV(BODS) | _BV(BODSE); //disable brownout detection during sleep
MCUCR &=~ _BV(BODSE);
sleep_cpu();
sleep_disable();
}
void inline sleepWhileADC() {
set_sleep_mode(SLEEP_MODE_ADC);
sleep_mode();
}
ISR(ADC_vect) {
//nothing, just wake up
}
// ------------------ capacitance measurement ------------------
void startExcitationSignal() {
OCR0A = 0;
TCCR0A = _BV(COM0A0) | //Toggle OC0A on Compare Match
_BV(WGM01);
TCCR0B = _BV(CS00);
}
void stopExcitationSignal() {
TCCR0B = 0;
TCCR0A = 0;
}
uint16_t getADC1() {
ADCSRA |= _BV(ADPS2); //adc clock speed = sysclk/16
ADCSRA |= _BV(ADIE);
ADMUX |= _BV(MUX0); //select ADC1 as input
ADCSRA |= _BV(ADSC); //start conversion
// sleepWhileADC();
loop_until_bit_is_clear(ADCSRA, ADSC);
uint16_t result = ADCL;
result |= ADCH << 8;
return 1023 - result;
}
uint16_t getCapacitance() {
PRR &= ~_BV(PRADC); //enable ADC in power reduction
ADCSRA |= _BV(ADEN);
PRR &= ~_BV(PRTIM0);
startExcitationSignal();
// _delay_ms(1);
getADC1();
// _delay_ms(1);
uint16_t result = getADC1();
stopExcitationSignal();
PORTB &= ~_BV(PB2);
PRR |= _BV(PRTIM0);
ADCSRA &=~ _BV(ADEN);
PRR |= _BV(PRADC);
return result;
}
//--------------------- light measurement --------------------
volatile uint16_t lightCounter = 0;
volatile uint8_t lightCycleOver = 0;
ISR(PCINT1_vect) {
GIMSK &= ~_BV(PCIE1);//disable pin change interrupts
TCCR1B = 0; //stop timer
lightCounter = TCNT1;
lightCycleOver = 1;
}
ISR(TIM1_OVF_vect) {
lightCounter = 65535;
lightCycleOver = 1;
}
uint16_t getLight() {
PRR &= ~_BV(PRTIM1);
TIMSK1 |= _BV(TOIE1); //enable timer overflow interrupt
DDRB |= _BV(LED_A) | _BV(LED_K); //forward bias the LED
PORTB &= ~_BV(LED_K); //flash it to discharge the PN junction capacitance
PORTB |= _BV(LED_A);
PORTB |= _BV(LED_K); //reverse bias LED to charge capacitance in it
PORTB &= ~_BV(LED_A);
DDRB &= ~_BV(LED_K); //make Cathode input
PORTB &= ~(_BV(LED_A) | _BV(LED_K));//disable pullups
TCNT1 = 0;
TCCR1A = 0;
TCCR1B = _BV(CS12); //start timer1 with prescaler clk/256
PCMSK1 |= _BV(PCINT8); //enable pin change interrupt on LED_K
GIMSK |= _BV(PCIE1);
lightCycleOver = 0;
while(!lightCycleOver) {
set_sleep_mode(SLEEP_MODE_IDLE);
sleep_mode();
}
TCCR1B = 0;
GIMSK &= ~_BV(PCIE1);
PCMSK1 &= ~_BV(PCINT8);
TIMSK1 &= ~_BV(TOIE1);
PRR |= _BV(PRTIM1);
return lightCounter;
}
// ----------------- sensor mode loop hack ---------------------
void loopSensorMode() {
PRR &= ~_BV(PRADC); //enable ADC in power reduction
ADCSRA = _BV(ADEN) | _BV(ADPS2);
ADMUX |= _BV(MUX0); //select ADC1 as input
PRR &= ~_BV(PRTIM0);
startExcitationSignal();
_delay_ms(500);
uint16_t currCapacitance = 0;
uint16_t light = 0;
while(1) {
if(usiTwiDataInReceiveBuffer()) {
uint8_t usiRx = usiTwiReceiveByte();
if(0 == usiRx) {
ledOn();
currCapacitance = getCapacitance();
usiTwiTransmitByte(currCapacitance >> 8);
usiTwiTransmitByte(currCapacitance &0x00FF);
ledOff();
} else if(0x01 == usiRx) {
uint8_t newAddress = usiTwiReceiveByte();
if(newAddress > 0 && newAddress < 255) {
eeprom_write_byte((uint8_t*)0x01, newAddress);
}
} else if(0x02 == usiRx) {
uint8_t newAddress = eeprom_read_byte((uint8_t*) 0x01);
usiTwiTransmitByte(newAddress);
} else if(0x03 == usiRx) {
light = getLight();
} else if(0x04 == usiRx) {
usiTwiTransmitByte(light >> 8);
usiTwiTransmitByte(light & 0x00FF);
} else {
// while(usiTwiDataInReceiveBuffer()) {
// usiTwiReceiveByte();//clean up the receive buffer
// }
}
}
}
}
// --------------- chirp FSM states and utilities-----------------
#define STATE_INITIAL 0
#define STATE_HIBERNATE 1
#define STATE_ALERT 2
#define STATE_VERY_ALERT 3
#define STATE_PANIC 4
#define STATE_MEASURE 5
#define SLEEP_TIMES_HIBERNATE 225
#define SLEEP_TIMES_ALERT 37
#define SLEEP_TIMES_VERY_ALERT 1
#define SLEEP_TIMES_PANIC 1
#define MODE_SENSOR 0
#define MODE_CHIRP 1
uint8_t mode;
uint8_t sleepSeconds = 0;
uint32_t secondsAfterWatering = 0;
/**
* Sets wake up interval to 8s
**/
void inline wakeUpInterval8s() {
WDTCSR &= ~_BV(WDP1);
WDTCSR &= ~_BV(WDP2);
WDTCSR |= _BV(WDP3) | _BV(WDP0); //every 8 sec
sleepSeconds = 8;
}
/**
* Sets wake up interval to 1s
**/
void inline wakeUpInterval1s() {
WDTCSR &= ~_BV(WDP3);
WDTCSR &= ~_BV(WDP0);
WDTCSR |= _BV(WDP1) | _BV(WDP2); //every 1 sec
sleepSeconds = 1;
}
uint16_t lightThreshold = 65530;
void inline static chirpIfLight() {
getLight();
if(lightCounter < lightThreshold) {
chirp(3);
} else {
ledOn();
_delay_ms(10);
ledOff();
}
}
uint8_t isLightNotCalibrated() {
return 65535 == lightThreshold;
}
//-----------------------------------------------------------------
int main (void) {
setupGPIO();
uint8_t address = eeprom_read_byte((uint8_t*)0x01);
if(0 == address || 255 == address) {
address = 0x20;
}
usiTwiSlaveInit(address);
lightThreshold = eeprom_read_word((uint16_t*)0x02);
CLKPR = _BV(CLKPCE);
CLKPR = _BV(CLKPS1); //clock speed = clk/4 = 2Mhz
sei();
ledOn();
chirp(2);
ledOff();
_delay_ms(500);
getLight();
if(isLightNotCalibrated()) {
// getLight();
lightThreshold = lightCounter - lightCounter / 10;
eeprom_write_word((uint16_t*)0x02, lightThreshold);
chirp(1);
_delay_ms(300);
}
chirp(2);
if(usiTwiDataInReceiveBuffer()){
loopSensorMode();
}
uint16_t referenceCapacitance = getCapacitance();
USICR = 0;
setupPowerSaving();
initWatchdog();
uint8_t wakeUpCount = 0;
uint8_t playedHappy = 0;
uint8_t state = STATE_PANIC;
int16_t capacitanceDiff = 0;
uint8_t maxSleepTimes = 0;
uint16_t currCapacitance = 0;
uint16_t lastCapacitance = 0;
while(1) {
if(wakeUpCount < maxSleepTimes) {
sleep();
wakeUpCount++;
} else {
secondsAfterWatering = maxSleepTimes * sleepSeconds;
wakeUpCount = 0;
lastCapacitance = currCapacitance;
currCapacitance = getCapacitance();
capacitanceDiff = referenceCapacitance - currCapacitance;
if (!playedHappy && ((int16_t)lastCapacitance - (int16_t)currCapacitance) < -5 && lastCapacitance !=0) {
chirp(9);
_delay_ms(350);
chirp(1);
_delay_ms(50);
chirp(1);
playedHappy = 1;
}
if(capacitanceDiff <= -5) {
if(STATE_HIBERNATE != state) {
wakeUpInterval8s();
}
maxSleepTimes = SLEEP_TIMES_HIBERNATE;
state = STATE_HIBERNATE;
} else {
if(capacitanceDiff >= -5) {
chirpIfLight();
playedHappy = 0;
}
if(capacitanceDiff > -5 && capacitanceDiff < -2) {
if(STATE_ALERT != state) {
wakeUpInterval8s();
}
maxSleepTimes = SLEEP_TIMES_ALERT;
state = STATE_ALERT;
} else if(capacitanceDiff >= -2 && capacitanceDiff < 0) {
if(STATE_VERY_ALERT != state) {
wakeUpInterval8s();
}
state = STATE_VERY_ALERT;
maxSleepTimes = SLEEP_TIMES_VERY_ALERT;
} else if(capacitanceDiff >= 0) {
if(STATE_PANIC != state) {
wakeUpInterval1s();
}
state = STATE_PANIC;
maxSleepTimes = SLEEP_TIMES_PANIC;
}
}
}
}
}
Návrat nahoru
lesana87 Založen: Sep 20, 2014 Příspěvky: 3382
Zaslal: ne duben 28 2019, 10:20 Předmět:
Na Cčko asi Cčkovej kompilátor, třeba gcc z WinAVR.
Návrat nahoru
Honza_dy Založen: Aug 20, 2004 Příspěvky: 2172 Bydliště: Brno-venkov
Zaslal: ne duben 28 2019, 21:26 Předmět:
lesana: Díky za nakopnutí, pomohlo.
Návrat nahoru
rnbw Založen: Mar 21, 2006 Příspěvky: 34420 Bydliště: Bratislava
Zaslal: ne duben 28 2019, 21:30 Předmět:
kód: r@test:/usr/src$ git clone https://github.com/Miceuz/PlantWateringAlarm
Cloning into 'PlantWateringAlarm'...
remote: Enumerating objects: 536, done.
remote: Total 536 (delta 0), reused 0 (delta 0), pack-reused 536
Receiving objects: 100% (536/536), 14.69 MiB | 1.01 MiB/s, done.
Resolving deltas: 100% (248/248), done.
r@test:/usr/src$ cd PlantWateringAlarm/src
r@test:/usr/src/PlantWateringAlarm/src$ make
This Makefile has no default rule. Use one of the following:
make hex ....... to build main.hex
make program ... to flash fuses and firmware
make fuse ...... to flash the fuses
make flash ..... to flash the firmware (use this on metaboard)
make clean ..... to delete objects and hex file
r@test:/usr/src/PlantWateringAlarm/src$ make hex
avr-gcc -DF_CPU=1000000 -Iusbdrv -I. -DDEBUG_LEVEL=0 -Os -ffunction-sections -fdata-sections -save-temps -Wl,--gc-sections,--relax -mmcu=attiny44 -c main.c -o main.o
avr-gcc -DF_CPU=1000000 -Iusbdrv -I. -DDEBUG_LEVEL=0 -Os -ffunction-sections -fdata-sections -save-temps -Wl,--gc-sections,--relax -mmcu=attiny44 -c usiTwiSlave.c -o usiTwiSlave.o
avr-gcc -DF_CPU=1000000 -Iusbdrv -I. -DDEBUG_LEVEL=0 -Os -ffunction-sections -fdata-sections -save-temps -Wl,--gc-sections,--relax -mmcu=attiny44 -o main.elf main.o usiTwiSlave.o
rm -f main.hex main.eep.hex
avr-objcopy -j .text -j .data -O ihex main.elf main.hex
avr-size main.hex
text data bss dec hex filename
0 1956 0 1956 7a4 main.hex
Návrat nahoru
Nemůžete odesílat nové téma do tohoto fóra.Nemůžete odpovídat na témata v tomto fóru.Nemůžete upravovat své příspěvky v tomto fóru.Nemůžete mazat své příspěvky v tomto fóru.Nemůžete hlasovat v tomto fóru.Nemůžete připojovat soubory k příspěvkůmMůžete stahovat a prohlížet přiložené soubory
Powered by phpBB © 2001, 2005 phpBB Group
Informace na portálu Elektro bastlírny jsou prezentovány za účelem vzdělání čtenářů a rozšíření zájmu o elektroniku. Autoři článků na serveru neberou žádnou zodpovědnost za škody vzniklé těmito zapojeními. Rovněž neberou žádnou odpovědnost za případnou újmu na zdraví vzniklou úrazem elektrickým proudem. Autoři a správci těchto stránek nepřejímají záruku za správnost zveřejněných materiálů. Předkládané informace a zapojení jsou zveřejněny bez ohledu na případné patenty třetích osob. Nároky na odškodnění na základě změn, chyb nebo vynechání jsou zásadně vyloučeny. Všechny registrované nebo jiné obchodní známky zde použité jsou majetkem jejich vlastníků. Uvedením nejsou zpochybněna z toho vyplývající vlastnická práva. Použití konstrukcí v rozporu se zákonem je přísně zakázáno. Vzhledem k tomu, že původ předkládaných materiálů nelze žádným způsobem dohledat, nelze je použít pro komerční účely! Tento nekomerční server nemá z uvedených zapojení či konstrukcí žádný zisk. Nezodpovídáme za pravost předkládaných materiálů třetími osobami a jejich původ. V případě, že zjistíte porušení autorského práva či jiné nesrovnalosti, kontaktujte administrátory na diskuzním fóru EB. Copyright © 2005 by Francisco Burzi. This is free software, and you may redistribute it under the . PHP-Nuke comes with absolutely no warranty, for details, see the . Čas potřebný ke zpracování stránky 0.23 sekund