domingo, 20 de abril de 2014

EKG simulator: first version (deprecated)


Hello! I choose Codea to make an old project: an EKG simulator (and multiparameter monitor simulator) for educational purposes. I am a nurse, working and living in Chile. I work on an hospital and teaching on a University to Nursing students. So, i use a lot an early prototype and now i started from draft because i want it to put on AppStore. I also learning to code directly on XCode but i choose Codea because aircode and i can test on the fly my program. I want to show you some photos of my first prototype, working but very buggy.


Copy and paste this code, if program stops just put play again,LANDSCAPE only.


The new version is more object oriented. The precision is very low, so 60BPM actually wont run at 60/minute.




 -- Monitor Sim  
 -- Use this function to perform your initial setup  
 function setup()  
   backingMode(RETAINED)  
   deltaCumulative=0  
   ecgVal=0  
   ecgLastX=0  
   ecgLastY=0  
   smooth()  
   startTime= os.clock()  
   deltaFps=0  
   fpsDelta= os.clock()  
   intFps=0  
   currentFrecState=0  
   valFps=0  
   Sist = 0  
   Diast = 0  
   deltaEcgBox=10  
   ecgBoxWidth = 3  
   parameter.integer("FC",0,180,70)  
   parameter.integer("FR",0,50,17)  
   parameter.integer("Sist",0,240,125, function() if Sist < Diast then Diast = Sist end end)  
   parameter.integer("Diast",0,140,80, function() if Diast > Sist then Sist = Diast end end)  
   parameter.integer("Sat",0,100,95)  
   parameter.action("Sano",function() setPar(70, 17, 125, 80, 90) end)  
   parameter.action("Sepsis", function() setPar(140, 24, 94, 50, 92) end)  
   parameter.action("Bradi. Asintomática", function() setPar(41, 19, 123, 87, 94) end)  
   parameter.action("Bradi. Sintomática", function() setPar(34, 23, 86, 43, 85) end)  
   parameter.action("Crisis HTA", function() setPar(90, 21, 210, 102, 93) end)  
   parameter.action("Insuf. Resp I", function() setPar(142, 47, 115, 72, 72) end)  
   parameter.action("Insuf. Resp II", function() setPar(45, 5, 0, 0, 30) end)  
   parameter.action("Vaciar", function() setPar(0,0,0,0,0) end)  
   intResolution = 6  
   XCuad = (WIDTH / intResolution)-30  
   YCuad = (HEIGHT / intResolution)-10  
   textAlign(RIGHT)  
   font("Futura-Medium")  
   textMode(CORNER)  
   sep="- -"  
 end  
 function setPar(intFC, intFR, intSist, intDiast, intSat)  
   FC=intFC  
   FR=intFR  
   Sist=intSist  
   Diast=intDiast  
   Sat=intSat  
 end  
 -- This function gets called once every frame  
 function draw()  
   -- This sets a dark background color   
   -- background(0, 0, 0, 255)  
   stroke(0, 0, 0, 255)  
   fill(25, 25, 25, 255)  
   rect(WIDTH/2,0,WIDTH/2,HEIGHT)  
   rect(0,0,12, HEIGHT)  
   fps()  
   -- Formatting  
   strokeWidth(1)  
   stroke(69, 69, 69, 0)  
   for ix=1, intResolution - 1 do  
     line(XCuad*ix,0,XCuad*ix,HEIGHT)  
   end  
   for iy=1, intResolution - 1 do  
     line(0, YCuad*iy,WIDTH, YCuad*iy)  
   end  
   if FC == 0 then sFC = sep else sFC = FC end  
   if FR == 0 then sFR = sep else sFR = FR end  
   if Sist == 0 then sSist = sep else sSist = Sist end  
   if Diast == 0 then sDiast = sep else sDiast = Diast end  
   if Sat == 0 then sSat = sep else sSat = Sat end  
   txt("FREC CARDIACA",10,"G",XCuad * (intResolution - 3), YCuad * (intResolution - 1))  
   txt(sFC , 120,"G", XCuad * (intResolution - 2), YCuad * (intResolution - 1)-30)  
   txt("FREC RESP", 10, "W", XCuad * (intResolution - 3), YCuad * (intResolution - 2))  
   txt(sFR , 100, "W", XCuad * (intResolution - 2), YCuad * (intResolution - 2)-30)  
   if Sist == sep or Diast == sep then  
     PAM = sep  
   else  
     PAM = math.floor((Sist + Diast + Diast)/ 3)  
   end  
   if Sist == Diast then PAM = sep end  
   txt("PANI", 10, "R" , XCuad * (intResolution - 3), YCuad * (intResolution - 3))  
   txt(sSist .. "/" .. sDiast , 90, "R", XCuad * (intResolution - 2), YCuad * (intResolution - 3)-5)  
   txt("(" .. PAM .. ")", 30, "R", XCuad * (intResolution) +30, YCuad * (intResolution - 3)-30)  
   txt("SpO2", 10, "Y", XCuad * (intResolution - 3), YCuad * (intResolution - 4))  
   txt(sSat, 120, "Y", XCuad * (intResolution - 2), YCuad * (intResolution - 4)-30)  
   debugFpsData()  
   eraseBg()  
   drawECG()  
 end  
 function drawECG()  
   -- Mostrar corazon  
   if currentFrecState <= 0.2 then   
     txt("SYMBOL",20,"W",XCuad * (intResolution) + 40, YCuad * (intResolution - 1) +50)  
   end  
   -- Trazar linea  
   -- fill(40, 255, 0, 255)  
   -- ecgVal=HEIGHT -120 + (math.sin(currentFrecState*2*math.pi)*30)  
   ecgVal=HEIGHT -120 + (getEcgVal())  
   --ecgVal=g  
   -- ellipse(deltaEcgBox -5,ecgVal,5,5)  
   strokeWidth(2)  
   stroke(58, 255, 0, 255)  
   if ecgLastX == 0 then   
   else  
     line(ecgLastX,ecgLastY,deltaEcgBox,ecgVal)   
   end  
   ecgLastX=deltaEcgBox  
   ecgLastY=ecgVal  
   fill(255, 255, 255, 255)  
   ellipse(deltaEcgBox +4,ecgVal,4,4)  
 end  
 -- tiempo = 60' = 120'  
 -- 60 seg = 1  = 2  
 --       
 function eraseBg()  
   fill(0, 0, 0, 255)  
   noStroke()  
   rect(deltaEcgBox,0,ecgBoxWidth,HEIGHT)  
   fill(20, 20, 20, 255)  
   rect(deltaEcgBox+ecgBoxWidth,0,ecgBoxWidth,HEIGHT)  
   deltaEcgBox = deltaEcgBox + ecgBoxWidth -1  
   if deltaEcgBox >= WIDTH/2 then   
     deltaEcgBox=10   
     ecgLastX=0  
   end   
 end  
 function debugFpsData()  
   deltaTime = os.clock() - startTime  
   currentFrecState = currentFrecState + (deltaTime * FC/ 60)  
   startTime = os.clock()  
   deltaCumulative = deltaCumulative + 1  
   if currentFrecState>=1 then   
     print(currentFrecState)  
     currentFrecState = 0.001  
     print(deltaCumulative)  
     deltaCumulative = 0  
   end  
   txt("fps=" .. valFps, 12, "Y", XCuad * (intResolution - 1), YCuad * (intResolution - 4)-70)  
 end  
 function getEcgVal()  
   local ecgStringId = math.ceil(currentFrecState*(string.len(ecgData)/3))  
   local eValue = tonumber(string.sub(ecgData,(ecgStringId*3),(ecgStringId*3)+2))/10  
   txt(eValue, 12, "Y", XCuad * (intResolution - 1), YCuad * (intResolution - 3))  
   return eValue  
 end  
 function txt(strString, intSize, strColor, intX, intY) -- Imprime un texto en la pantalla  
   cR = 255  
   cG = 255  
   cB = 255  
   if strColor == "R" then  
     cR=255  
     cG=0  
     cB=0  
   elseif strColor == "G" then  
     cR=0  
     cG=255  
     cB=0  
   elseif strColor == "Y" then  
     cR = 255  
     cG = 255  
     cB = 0  
   elseif strColor == "W" then  
     cB = 255  
     cR = 255  
     cG = 255  
   end  
   fill(cR,cG,cB,255)  
   fontSize(intSize)  
   text(strString,intX, intY)  
 end  
 function fps()  
   intFps = intFps + 1  
   local finalFps = deltaFps +1  
   if os.clock()>=finalFps then   
     deltaFps = os.clock()  
     valFps=intFps  
     intFps=0  
   end  
 end  
 --ECG DATABANK  
 ecgData="00500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550550551552553554555556557557558558559559560560560559559558558557556555554552550547543539535531528526524522520518517516515514512510509508507506505504503502501500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500499498497496495494493492491490488486484482480478476474472470467464461458455452449446442438434430426422420435450465480495510525540555570585600615630645660675690705720735750765780795810825840855870885900915930945930915900885870855840825810795780765750735720705690675660645630615600585570555540525510495480465450435420405390375360345375405435450460468474480485489492494496497498499500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630630631631632632633633632632631631630629628627625622620618616614612610608606604602600598596594592590588586584582580578576574572570568566564562560558556554552550548546544542540538536534532530528526524522520518516515514513512511510509509508508507507506506505505504504504503503503502502502501501501500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500501501501502502502503503504504505505506506507508509510511512513514515516516517517518518518519519519519520520520520520520519519519518518518517517517516515514513512511510509508507506505504504503503503502502502502501501501501501500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500500"  

No hay comentarios:

Publicar un comentario