// //////////////////////////////////////////////
// ESP (CS 33301-001)
// Project 4: ADC and temp
//
// Kent State University
// Dept. of Computer Science
// Ean Dodge
// //////////////////////////////////////////////
//////////////////////////////////////////////////
//////////////////////////////////////////////////
#define BIT5_MASK 0x20 // 0010 0000 --> Pin 5
#define BIT4_MASK 0x10 // 0001 0000 --> Pin 4
#define BIT2_MASK 0x04 // 0000 0100 --> Pin 4
#define PORTD_MASK 0x2B //for input port
#define DDRD_MASK 0x2A// for the DDRB
#define PIND_MASK 0x29 //for input device
#define PORTB_MASK 0x25 //for input port
#define DDRB_MASK 0x24// for the DDRB
// Registers' Address Setting
unsigned char *ADMUX_ESP;
unsigned char *ADCSRA_ESP;
unsigned char *ADCSRB_ESP;
unsigned char *ADCL_ESP;
unsigned char *ADCH_ESP;
/* Which analog pin we want to read from. The pins are labeled "ADC0"
"ADC1" etc on the pinout in the data sheet. In this case ADC_PIN
being 0 means we want to use ADC0. On the ATmega328P this is also
the same as pin PC0 */
int ADC_PIN = 0;
/* This function just keeps the reading code out of the loop itself.
It takes the analog pin number as a parameter and returns the
analog reading on that pin as a result. */
uint16_t adc_read(uint8_t adcx);
// Register Pointer Declaration
unsigned char *TCCR1A_ESP; //0x80
unsigned char *TCCR1B_ESP; //0x81
unsigned char *TCNT1H_ESP; //0x85
unsigned char *TCNT1L_ESP; //0x84
unsigned char *OCR1AH_ESP; //0x89
unsigned char *OCR1AL_ESP; //0x88
unsigned char *TIMSK1_ESP; //0x6F
unsigned char *portDDRB; //declaring DDRB
unsigned char *portB; //declaring port B to use as output D
unsigned char *portPinD; //for input
unsigned char *portDDRD; //declaring DDRB
void MyDelay(unsigned long mSec);
int problem = 1;
void setup() {
//////////////////////////////////////////////////
// Serial Library
Serial.begin(9600); // open the serial port at 9600 bps:
//////////////////////////////////////////////////
// Registers' Address Setting
ADMUX_ESP = (unsigned char*) 0x7c;
ADCSRA_ESP = (unsigned char*) 0x7a;
ADCSRB_ESP = (unsigned char*) 0x7b;
ADCL_ESP = (unsigned char*) 0x78;
ADCH_ESP = (unsigned char*) 0x79;
TCCR1A_ESP = (unsigned char*) 0x80;
TCCR1B_ESP = (unsigned char*) 0x81;
TCNT1H_ESP = (unsigned char*) 0x85;
TCNT1L_ESP = (unsigned char*) 0x84;
OCR1AH_ESP = (unsigned char*) 0x89;
OCR1AL_ESP = (unsigned char*) 0x88;
TIMSK1_ESP = (unsigned char*) 0x6F;
portDDRB = (unsigned char *) DDRB_MASK; //pointing DDRB to a hardcoded value of 0x24
*portDDRB |= BIT5_MASK; //Configure bit 5 of DDRB as 1, or an output
portB = (unsigned char *) PORTB_MASK; //pointing PortB to a hardcoded value of 0x25
*portB &= ~BIT5_MASK; //turns off internal LED to initialize it as off
unsigned char *portD;
portD = (unsigned char *) 0x2B;
*portD |= 0x04;
// Configure external interrupt 0 to generate an interrupt request on any
// logical change using External Interrupt Control Register A (EICRA)
unsigned char *AT328_EICRA;
AT328_EICRA = (unsigned char *) 0x69;
*AT328_EICRA |= 0x01;
*AT328_EICRA &= ~(0x02);
// Enable external interrupt 0 using the External Interrupt Mask Register (EIMSK)
unsigned char *AT328_EIMSK;
AT328_EIMSK = (unsigned char *) 0x3D;
*AT328_EIMSK |= 0x01;
*TCCR1A_ESP = 0x00;
*TCCR1B_ESP = 0x0C; // CTC mode - BIT 3; 256 prescaler BIT2
*TCNT1H_ESP = 0x00;
*TCNT1L_ESP = 0x00;
*OCR1AH_ESP = 0xF2; //for 1 second changes
*OCR1AL_ESP = 0x24; //for 1 second changes
*TIMSK1_ESP = 0x02; // enable timer compare interrupt - BIT1
}
int flag = 0;
bool done = false;
int potpin = 0; // analog pin used to connect the potentiometer
int val; // variable to read the value from the analog pin
void loop() {
/* Enable the ADC */
*ADCSRA_ESP |= 0b10000000;
val = adc_read(ADC_PIN);
if (val <= 270) {
done = true;
}else{
done = false;
*portB &= ~BIT5_MASK; //turns off internal LED to initialize it as off
}
int BETA = 3950;
float newVal = 1 / (log(1 / (1023. / val - 1)) / BETA + 1.0 / 298.15) - 273.15;
//this is on the wokwi reference page for the sensor,
//thought it would be easier to read
Serial.print ("This is problem: ");
Serial.print (problem);
Serial.print (" Temp: ");
Serial.println(newVal);
}
ISR(TIMER1_COMPA_vect)
{
if(done == true){
if (flag == 0)
{
*portB &= ~0x20; // Internal LED off
flag = 1;
} else {
*portB |= 0x20; // Internal LED on
flag = 0;
}
}
}
ISR(INT0_vect){
if (++problem == 5){
problem = 1;
}
// Serial.print (problem);
// Serial.print (" ");
switch(problem){
case 1:
ADC_PIN = 0; //A0
break;
case 2:
ADC_PIN = 1; //A1
break;
case 3:
ADC_PIN = 15; //ground
break;
case 4:
ADC_PIN = 14; //AVCC(1.4V)
break;
}
}
uint16_t adc_read(uint8_t adcx) {
/* adcx is the analog pin we want to use. ADMUX's first few bits are
the binary representations of the numbers of the pins so we can
just 'OR' the pin's number with ADMUX to select that pin.
We first zero the four bits by setting ADMUX equal to its higher
four bits. */
*ADMUX_ESP &= 0xf0;
*ADMUX_ESP |= adcx;
/* This starts the conversion. */
*ADCSRA_ESP |= 0b01000000;
/* Finally, we return the converted value to the calling function. */
unsigned char cl = *ADCL_ESP;
unsigned char ch = *ADCH_ESP;
return (cl | (ch << 8));
}