void lcd_Putc ( uint8_t chr ) { if (Row >= _LCD_ROWS) return; if (chr == '\r') { /* Carriage Return */ lcd_Locate(Row, 0); return; } if (chr == '\n') { /* Line Feed */ lcd_Locate(Row + 1, 0); return; } if (chr == '\f') { /* Clear Screen and Return Home */ lcd_Write(0, 0x01); _delay_us(LCD_DT1); lcd_Locate(0, 0); return; } if (Column >= _LCD_COLS) return; lcd_Write((LCD_IF_DUAL && Row >= 2) ? 3 : 5, chr); Column++; if (LCD_IF_SPLIT && Column == _LCD_COLS / 2) lcd_Write(0, 0x40); if (Column >= _LCD_COLS) lcd_Locate(Row + 1, 0); }
void lcd_Cursor ( uint8_t stat /* 0:off, 1:blinking block, 2:under-line */ ) { Csr = stat & 3; lcd_Locate(Row, Column); }
int main(void) { // turn on the serial port for setting or querying the time . xSerialPort = xSerialPortInitMinimal( USART0, 115200, portSERIAL_BUFFER_TX, portSERIAL_BUFFER_RX); // serial port: WantedBaud, TxQueueLength, RxQueueLength (8n1) // Memory shortages mean that we have to minimise the number of // threads, hence there are no longer multiple threads using a resource. // Still, semaphores are useful to stop a thread proceeding, where it should be stopped because it is using a resource. if( xADCSemaphore == NULL ) // Check to see if the ADC semaphore has not been created. { xADCSemaphore = xSemaphoreCreateBinary(); // binary semaphore for ADC - Don't sample temperature when hands are moving (voltage droop). if( ( xADCSemaphore ) != NULL ) xSemaphoreGive( ( xADCSemaphore ) ); // make the ADC available } // initialise I2C master interface, need to do this once only. // If there are two I2C processes, then do it during the system initiation. I2C_Master_Initialise((ARDUINO<<I2C_ADR_BITS) | (pdTRUE<<I2C_GEN_BIT)); avrSerialxPrint_P(&xSerialPort, PSTR("\r\nHello World!\r\n")); // Ok, so we're alive... xTaskCreate( TaskWriteLCD , (const portCHAR *)"WriteLCD" , 192 , NULL , 2 , NULL ); // */ xTaskCreate( TaskWriteRTCRetrograde , (const portCHAR *)"WriteRTCRetrograde" , 120 , NULL , 1 , &xTaskWriteRTCRetrograde ); // */ xTaskCreate( TaskMonitor , (const portCHAR *)"SerialMonitor" , 256 , NULL , 3 , NULL ); // */ avrSerialPrintf_P(PSTR("\r\nFree Heap Size: %u\r\n"), xPortGetFreeHeapSize() ); // needs heap_1, heap_2 or heap_4 for this function to succeed. vTaskStartScheduler(); avrSerialPrint_P(PSTR("\r\n\nGoodbye... no space for idle task!\r\n")); // Doh, so we're dead... #if defined (portHD44780_LCD) lcd_Locate (0, 1); lcd_Print_P(PSTR("DEAD BEEF!")); #endif }
static void TaskBlinkRedLED(void *pvParameters) // Main Red LED Flash { (void) pvParameters;; portTickType xLastWakeTime; /* The xLastWakeTime variable needs to be initialised with the current tick count. Note that this is the only time we access this variable. From this point on xLastWakeTime is managed automatically by the vTaskDelayUntil() API function. */ xLastWakeTime = xTaskGetTickCount(); // int8_t i; // uint8_t j; // lcd_Init(); DDRB |= _BV(DDB7); for(;;) { PORTB |= _BV(PORTB7); // main (red IO_B7) LED on. EtherMega LED on vTaskDelayUntil( &xLastWakeTime, ( 500 / portTICK_RATE_MS ) ); // lcd_Locate (0, 0); // lcd_Printf_P(PSTR("HighWater @ %u"), uxTaskGetStackHighWaterMark(NULL)); // lcd_Cursor (1); #if _USE_FUEL lcd_Locate (1, 0); lcd_PutFuel (--i, 0); if (i < 0) i = 6; #endif #if _USE_BAR lcd_Locate (1, 2); lcd_PutBar (j++, 14, 2); #endif PORTB &= ~_BV(PORTB7); // main (red IO_B7) LED off. EtherMega LED off vTaskDelayUntil( &xLastWakeTime, ( 500 / portTICK_RATE_MS ) ); // xSerialxPrintf_P(&xSerialPort, PSTR("RedLED HighWater @ %u\r\n"), uxTaskGetStackHighWaterMark(NULL)); } }
void lcd_SetCG ( uint8_t chr, /* Character code to be registered (0..7) */ uint8_t n, /* Number of characters to register */ const uint8_t* p /* Pointer to the character pattern (8 * n bytes) */ ) { lcd_Write(0, 0x40 | chr * 8); n *= 8; do lcd_Write(1, *p++); while (--n); lcd_Locate(Row, Column); }
static void TaskWriteLCD(void *pvParameters) // Write to LCD { (void) pvParameters; TickType_t xLastWakeTime; /* The xLastWakeTime variable needs to be initialised with the current tick count. Note that this is the only time we access this variable. From this point on xLastWakeTime is managed automatically by the vTaskDelayUntil() API function. */ xLastWakeTime = xTaskGetTickCount(); uint8_t temperature_print; // true if temperature can be displayed. eeprom_read_block(&xMaximumTempTime, &xMaximumEverTempTime, sizeof(xRTCTempArray)); eeprom_read_block(&xMinimumTempTime, &xMinimumEverTempTime, sizeof(xRTCTempArray)); lcd_Init(); // initialise LCD, move cursor to start of top line while(1) { if(getDateTimeDS1307(&xCurrentTempTime.DateTime)) { if ( (xCurrentTempTime.Temperature = ReadADCSensors())) // if non 0 then a reading returned. { // trigger a temperature reading temperature_print = true; xCurrentTempTime.Temperature -= 273.15; // Convert from Kelvin to Celcius if( (xCurrentTempTime.Temperature < 65) && (xCurrentTempTime.Temperature > xMaximumTempTime.Temperature)) // check for maximum temp // we don't expect the temperature sensor to work above 65C { xMaximumTempTime = xCurrentTempTime; // Now we commit the time and temperature to the EEPROM, forever... eeprom_update_block(&xMaximumTempTime, &xMaximumEverTempTime, sizeof(xRTCTempArray)); } if( (xCurrentTempTime.Temperature > (-30)) && (xCurrentTempTime.Temperature < xMinimumTempTime.Temperature)) // and check for minimum temp // we don't expect the temperature sensor to work below -30C { xMinimumTempTime = xCurrentTempTime; // Now we commit the time and temperature to the EEPROM, forever... eeprom_update_block(&xMinimumTempTime, &xMinimumEverTempTime, sizeof(xRTCTempArray)); } } else temperature_print = false; lcd_Locate(0, 0); // go to the first character of the first LCD line switch( xCurrentTempTime.DateTime.tm_wday ) { case SUNDAY: lcd_Print_P(PSTR("Sunday ")); break; case MONDAY: lcd_Print_P(PSTR("Monday ")); break; case TUESDAY: lcd_Print_P(PSTR("Tuesday ")); break; case WEDNESDAY: lcd_Print_P(PSTR("Wednesday")); break; case THURSDAY: lcd_Print_P(PSTR("Thursday ")); break; case FRIDAY: lcd_Print_P(PSTR("Friday ")); break; case SATURDAY: lcd_Print_P(PSTR("Saturday ")); break; default: lcd_Print_P(PSTR("NotMyDay ")); break; } // display Day Date/Month/Year lcd_Locate(0, 10); // go to the eleventh character of the first LCD line lcd_Printf_P( PSTR("%2u/%2u/%4u"), xCurrentTempTime.DateTime.tm_mday, xCurrentTempTime.DateTime.tm_mon, (xCurrentTempTime.DateTime.tm_year + 1900) ); // display the current temperature lcd_Locate(1, 1); // LCD cursor to third character of the second LCD line if ( temperature_print ) // print the temperature if you got it lcd_Printf_P( PSTR("%6.2f"), xCurrentTempTime.Temperature); // print Celcius temperature // display the current time lcd_Locate(1, 9); // go to the ninth character of the second LCD line lcd_Printf_P(PSTR("%2u:%02u:%02u"),xCurrentTempTime.DateTime.tm_hour, xCurrentTempTime.DateTime.tm_min, xCurrentTempTime.DateTime.tm_sec); // display the maximum temperature, time and date lcd_Locate(2, 0); // go to the first character of the third LCD line lcd_Printf_P(PSTR("Max%5.1f"),xMaximumTempTime.Temperature); // print the maximum temperature value lcd_Locate(2, 9); // go to the ninth character of the third LCD line lcd_Printf_P(PSTR("%2u:%02u %2u/%2u"),xMaximumTempTime.DateTime.tm_hour, xMaximumTempTime.DateTime.tm_min, xMaximumTempTime.DateTime.tm_mday, xMaximumTempTime.DateTime.tm_mon ); // display the m temperature, time and date lcd_Locate(3, 0); // go to the first character of the forth LCD line lcd_Printf_P(PSTR("Min%5.1f"),xMinimumTempTime.Temperature); // print the minimum temperature value lcd_Locate(3, 9); // go to the ninth character of the fourth LCD line lcd_Printf_P(PSTR("%2u:%02u %2u/%2u"),xMinimumTempTime.DateTime.tm_hour, xMinimumTempTime.DateTime.tm_min, xMinimumTempTime.DateTime.tm_mday, xMinimumTempTime.DateTime.tm_mon ); if(xCurrentTempTime.DateTime.tm_sec == 0) // resume the xTaskWriteRTCRetrograde() task, now that we need to write the analogue hands. vTaskResume( xTaskWriteRTCRetrograde ); } // xSerialPrintf_P(PSTR("LCD: Stack HighWater @ %u\r\n"), uxTaskGetStackHighWaterMark(NULL)); vTaskDelayUntil( &xLastWakeTime, ( 200 / portTICK_PERIOD_MS ) ); } }