This is an interesting basic project which probably has some practical application in case you are going to use a custom cabinet for assembled desktop. Here is How To Create An Arduino LCD CPU RAM Monitor So That The Values Can Be Seen With USB Connection Without Need of Looking Via GUI. We need a Python script which will gather data and send to a connected Arduino board which upon receiving data will displays it on a 16×2 LCD display. We are following content from a GitHub repo :
1 | https://github.com/djbarker/cpu-status-display |
There are many variations of such projects available all over the internet. Understanding basic is important. We can blink a LED connected to computer via command line.
Code For Arduino LCD CPU RAM Monitor
Here is the Python code for Windows :
---
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | import os import serial import time import datetime import wmi import pythoncom import win32serviceutil import win32service import win32event import servicemanager import socket class AppServerSvc(win32serviceutil.ServiceFramework): _svc_name_ = 'LCDStatus' _svc_display_name_ = 'Arduino LCD Status' stop_flag = False def __init__(self,args): win32serviceutil.ServiceFramework.__init__(self,args) self.hWaitStop = win32event.CreateEvent(None,0,0,None) socket.setdefaulttimeout(60) def SvcStop(self): self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING) win32event.SetEvent(self.hWaitStop) self.stop_flag = True def SvcDoRun(self): servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE, servicemanager.PYS_SERVICE_STARTED, (self._svc_name_,'')) self.main() def main(self): try: w = wmi.WMI() com = serial.Serial('COM3', baudrate=9600, timeout=1) time.sleep(2.5) # allows time for the serial connection to establish com.write("\nTIf a line is longer than 16 characters it will scroll to display itself.".encode()) while True: if self.stop_flag: break c = w.Win32_OperatingSystem()[0] m = c.wmi_property('FreePhysicalMemory') mem = float(m.value)/2**10 # convert to MB c = w.CIM_Processor()[0] m = c.wmi_property('CurrentClockSpeed') cpu_clock = int(m.value) # Mhz c = w.Win32_Processor()[0] m = c.wmi_property('LoadPercentage') cpu_load = m.value now = datetime.datetime.now() tstr = now.strftime("%H:%M") if cpu_load!=None: com.write((("\nTCPU %02d%% %04dMHz")%(cpu_load,cpu_clock)).encode()) string = ("\nBMEM %4.0fMB "%mem)+tstr com.write(string.encode()) time.sleep(0.25) finally: com.write("\nBClosing serial connection.".encode()) com.close() self.ReportServiceStatus(win32service.SERVICE_STOPPED) # end main if __name__ == '__main__': win32serviceutil.HandleCommandLine(AppServerSvc) |
Make sure you’re running the program as administrator, otherwise it will fail or give error codes when trying to test/run/execute your code. Here is code for Arduino, notice that LCD is using Pin 2 to 7 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 | #include <LiquidCrystal.h> /* * Parameters */ #define MAX_LEN 250 // maximum line length unsigned long timeout = 60; // seconds unsigned long refresh = 50; // milliseconds unsigned long scroll = 400; // milliseconds /* * Variables */ LiquidCrystal lcd(7, 6, 5, 4, 3, 2); char line1[MAX_LEN]; char line2[MAX_LEN]; short pos1=0, pos2=0; short len1=0, len2=0; short active_line = 1; unsigned long last_available = 0; unsigned long last_refresh = 0; unsigned long last_scroll = 0; bool had_data = true; /* Periodic memory copy function with padding. * * dest - destination pointer * source - source pointer * pos - where to start copying from in source * num - number of data to copy from source to dest * len - the length of the source array * padding - what to pad with at the end * pad_length - how much to pad at the end */ void memcpyp(char* dest, char* source, unsigned int num, unsigned int pos, unsigned int len, char padding, unsigned char pad_len) { if(pos+num<len) { memcpy(dest,source+pos,num); } else { int copied = 0; for(int i=0;i<num;++i) { if(pos+i<len) { dest[i] = source[pos+i]; } else if(i<(len-pos)+pad_len) { dest[i] = padding; } else { dest[i] = source[copied]; copied++; } } } } void setup() { Serial.begin(9600); lcd.begin(16, 2); lcd.clear(); for(int i=0;i<MAX_LEN;++i) line1[i] = line2[i] = ' '; } void loop() { if(Serial.available()>0) { last_available = millis(); had_data = true; /* Read any available data. */ while(Serial.available()>0) { int ch = Serial.read(); if(ch=='\r' || ch=='\t') { /* Ignore carriage returns and tabs. */ continue; } else if(ch=='\n') { delay(10); // allow serial buffer to catch up /* which line to update? */ ch = Serial.read(); switch(ch) { case (int)'T': // top line active_line = 1; memset(line1,' ',MAX_LEN); pos1 = len1 = 0; break; case (int)'B': // bottom line active_line = 2; memset(line2,' ',MAX_LEN); pos2 = len2 = 0; break; case (int)'D': // move top line down memcpy(line2,line1,MAX_LEN); pos2 = pos1; len2 = len1; active_line = 1; memset(line1,' ',MAX_LEN); pos1 = len1 = 0; break; default: // move bottom line up memcpy(line1,line2,MAX_LEN); pos1 = pos2; len1 = len2; active_line = 2; memset(line2,' ',MAX_LEN); pos2 = len2 = 0; } } else { /* Store new characters in the active line if there is space. */ if(len1<MAX_LEN-1 && active_line==1) { line1[len1] = (char)ch; len1++; } else if(len2<MAX_LEN-1 && active_line==2) { line2[len2] = (char)ch; len2++; } } } } /* If enough time has elapsed and we have received some data refresh. */ if((millis()-last_refresh)>=refresh && had_data) { char tmp[17]; tmp[16] = '\0'; // zero terminate if(len1<=16) memcpy(tmp,line1,16); else memcpyp(tmp,line1,16,pos1,len1,' ',4); lcd.setCursor(0,0); lcd.print(tmp); if(len2<=16) memcpy(tmp,line2,16); else memcpyp(tmp,line2,16,pos2,len2,' ',4); lcd.setCursor(0,1); lcd.print(tmp); last_refresh = millis(); } /* If enough time has elapsed scroll any long lines along by one character. */ if((millis()-last_scroll)>=scroll && had_data) { if(len1>16) pos1 = (pos1+1)%(len1+4); if(len2>16) pos2 = (pos2+1)%(len2+4); last_scroll = millis(); } /* If we haven't received any data for a while display the timeout message. */ if((millis()-last_available)>=timeout*1000 && had_data) { lcd.setCursor(0,0); lcd.print("--- Awaiting ---"); lcd.setCursor(0,1); lcd.print("--- data ... ---"); had_data = false; } } |