熱門文章

2017年10月24日 星期二

電導式濕度測量(組裝2)

保濕度儀器再精進:
原本設計沒有顯示器,直接接筆電,以excel 表示。
此進階板保留excel功能,加上 LCD. Nokia5110.,用起來更直觀,也比目前市售產品的畫面更好看。
附上照片及code




/*****************************************************************************
 * Origin Code :    http://www.instructables.com/id/Nokia-5110-Arduino-Oscilloscope/ 
 * Skin GSR Theory: http://www.theanthillsocial.co.uk/sketch/163
                    http://www.coherence.com/gsr_html_production.htm
 * Part: 300K ohm ,1UF Capacity(no 0.1UF,so use this)
 * Also link " Microsot Excel "
 * 171010 modify
 * Conductance in water :4.76 ,no contace:0.76
****************************************************************************** */
#include <adafruit_gfx.h>
#include <adafruit_pcd8544.h>
#include <spi.h>
#define DISPLAY_WIDTH 84
#define DISPLAY_HEIGHT 48
#define ARDUINO_PRECISION 1023.0
Adafruit_PCD8544 display = Adafruit_PCD8544(7, 6, 5, 4, 3);
int channelAI = A0;      // probe
#define DELAY_POTENTIMETER //disabled it I don't have it connected
#ifdef DELAY_POTENTIMETER
int delayAI = A1;       // delay potentiometer
#endif
float delayVariable = 0;
float scale = 0;
int xCounter = 0;
int yPosition = 0;
int readings[DISPLAY_WIDTH+1];
int counter = 0;
unsigned long drawtime = 0;
unsigned long lastdraw = 0;
int frames = 0;
int a = 0;

void setup(void) 
{
  display.begin();
  display.setContrast(60);// you might have a slightly different display so it might not be the optimal value for you
  display.clearDisplay();
  Serial.begin(9600);
  Serial.println("LABEL,Number,Conductance");
  }

void loop() 
{  
  #ifdef DELAY_POTENTIMETER
  delayVariable = analogRead(delayAI);
  delayVariable = (delayVariable/100);
  #endif
  scale = (float)(DISPLAY_HEIGHT-1)/ARDUINO_PRECISION; 
    //record readings
  for(xCounter = 0; xCounter <= DISPLAY_WIDTH; xCounter++)
  {                                 
    yPosition = analogRead(channelAI);
    readings[xCounter] = (yPosition*scale);
    #ifdef DELAY_POTENTIMETER
    delay (delayVariable);
    #endif
  }
  
  display.clearDisplay();

  //Draw Voltage Ref Lines
  display.drawLine( 10, 0, 10, DISPLAY_HEIGHT-1, BLACK);
  display.drawLine( 5, (DISPLAY_HEIGHT-1)-(.2 *ARDUINO_PRECISION * scale), 10, (DISPLAY_HEIGHT-1)-(.2 *ARDUINO_PRECISION * scale), BLACK);
  display.drawLine( 0, (DISPLAY_HEIGHT-1)-(.4 *ARDUINO_PRECISION * scale), 10, (DISPLAY_HEIGHT-1)-(.4 *ARDUINO_PRECISION * scale), BLACK);
  display.drawLine( 5, (DISPLAY_HEIGHT-1)-(.6 *ARDUINO_PRECISION * scale), 10, (DISPLAY_HEIGHT-1)-(.6 *ARDUINO_PRECISION * scale), BLACK);
  display.drawLine( 0, (DISPLAY_HEIGHT-1)-(.8 *ARDUINO_PRECISION * scale), 10, (DISPLAY_HEIGHT-1)-(.8 *ARDUINO_PRECISION * scale), BLACK);
  //display.drawLine( 5, (DISPLAY_HEIGHT-1)-(.84 *ARDUINO_PRECISION * scale), 10, (DISPLAY_HEIGHT-1)-(.84 *ARDUINO_PRECISION * scale), BLACK);
  
  //Draw Voltage Ref Numbers
  display.setCursor(0,((DISPLAY_HEIGHT-1)-(.2 *ARDUINO_PRECISION * scale))-3);
  display.print((int)(5.0*0.2));
  display.setCursor(0,((DISPLAY_HEIGHT-1)-(.4 *ARDUINO_PRECISION * scale))-3);
  display.print((int)(5.0*0.4));
  display.setCursor(0,((DISPLAY_HEIGHT-1)-(.6 *ARDUINO_PRECISION * scale))-3);
  display.print((int)(5.0*0.6));
  display.setCursor(0,((DISPLAY_HEIGHT-1)-(.8 *ARDUINO_PRECISION * scale))-3);
  display.print((int)(5.0*0.8));
  
  for(xCounter = 0; xCounter <= DISPLAY_WIDTH; xCounter++)
  {
    display.drawPixel(xCounter, (DISPLAY_HEIGHT-1)-readings[xCounter], BLACK);
    if(xCounter>1){
      display.drawLine(xCounter-1, (DISPLAY_HEIGHT-1)-readings[xCounter-1], xCounter, (DISPLAY_HEIGHT-1)-readings[xCounter], BLACK);
    }
  }
  //Draw FPS
  display.setCursor((DISPLAY_WIDTH-1)-11,0);
  display.print(frames);
  //Draw Voltage
  display.setCursor(((DISPLAY_WIDTH-1)/2),0);
  display.print(analogRead(channelAI)/ARDUINO_PRECISION*5.0);
  display.display();
  //Calculate FPS
  drawtime = micros();
  frames=1000000/*a second*//(drawtime-lastdraw);
  lastdraw = drawtime;
  a = a + 1 ;
  Serial.print("DATA");
  Serial.print(",");
  Serial.print("a");
  Serial.print(",");
  Serial.println(analogRead(channelAI)/204.6);//204.6 = ARDUINO_PRECISION*5.0
  //delay(1000);// NO delay() is good,otherwise frmae no work  
}

2017年8月31日 星期四

電容式濕度測量(討論)

保濕度檢測基本原理,逃不過測皮膚的電阻(電導)、電容、蒸氣壓。

蒸氣壓測法是最準的,該檢測分接觸式與不接觸式。
接觸式易由於皮膚的灰塵、油脂、電解質而影響精度,不過這測法最直觀的。

蒸氣壓屬非接觸法是最準 的,有二種測法,1個sensor 及 3sensor.
而3sensor是最準的,就是tewl方法,測起來是準的。


人家說電容式比電導式準,目前做出來的方法是以皮膚達到固定電容值的時間值來計算,
但數字較電導式不精準,待有時間再想想。




--- 程式碼 Code ----
/*****************************************************************************
 * Origin Code :    http://www.instructables.com/id/Nokia-5110-Arduino-Oscilloscope/ 
 * Skin Capacity Theory:https://swf.com.tw/?p=946
 * Part: 1M ohm ,100 PF Capacity(101),nokia5110 LCD
 * Also link " Microsot Excel "
 * 171011 modify
 * Conductance in water :4.76 ,no contace:0.76
****************************************************************************** */
#include 
#include 
#include 
#define DISPLAY_WIDTH 84
#define DISPLAY_HEIGHT 48
#define ARDUINO_PRECISION 1023.0
Adafruit_PCD8544 display = Adafruit_PCD8544(7, 6, 5, 4, 3);
#define DELAY_POTENTIMETER //disabled it I don't have it connected
#ifdef DELAY_POTENTIMETER
int delayAI = A1;       // delay potentiometer
#endif
float delayVariable = 0;
float scale = 0;
int xCounter = 0;
int yPosition = 0;
int readings[DISPLAY_WIDTH+1];
int counter = 0;
unsigned long drawtime = 0;
unsigned long lastdraw = 0;
int frames = 0;
int a = 0;

//紅pin 接 pin8
//綠pin 接 pinD7 
//白pin接Ground (100pf電容) (電容101) 
//藍pin 接 觸摸電容
//電阻由 1M改 300K   
#include 
// 設定電容觸控的訊號輸入和輸出腳位,pin9 emitionPin,pin8 acceptionPin
CapacitiveSensor   cs_4_2 = CapacitiveSensor(9,8);
//CapacitiveSensor   cs_4_2 = CapacitiveSensor(4,2);
//CapacitiveSensor   cs_4_6 = CapacitiveSensor(4,6);
//CapacitiveSensor   cs_4_8 = CapacitiveSensor(4,8);

void setup() {
  display.begin();
  display.setContrast(15);// you might have a slightly different display so it might not be the optimal value for you
  display.clearDisplay();
  Serial.begin(9600);  
  Serial.println("LABEL,Number,Capacity");
}

void loop() {
   // long total1 =  cs_4_2.capacitiveSensor(30);
  #ifdef DELAY_POTENTIMETER
  delayVariable = analogRead(delayAI);
  delayVariable = (delayVariable/100);
  #endif
  scale = (float)(DISPLAY_HEIGHT-1)/ARDUINO_PRECISION; 
    //record readings
  for(xCounter = 0; xCounter <= DISPLAY_WIDTH; xCounter++)
  {                                 
    long total1 =  cs_4_2.capacitiveSensor(30);
    // xx yPosition = analogRead(A1);
    yPosition = total1/4;
    readings[xCounter] = (yPosition*scale);
    #ifdef DELAY_POTENTIMETER
    delay (delayVariable);
    #endif
  }
  display.clearDisplay();
  //Draw Voltage Ref Lines
  display.drawLine( 10, 0, 10, DISPLAY_HEIGHT-1, BLACK);
  display.drawLine( 5, (DISPLAY_HEIGHT-1)-(.2 *ARDUINO_PRECISION * scale), 10, (DISPLAY_HEIGHT-1)-(.2 *ARDUINO_PRECISION * scale), BLACK);
  display.drawLine( 0, (DISPLAY_HEIGHT-1)-(.4 *ARDUINO_PRECISION * scale), 10, (DISPLAY_HEIGHT-1)-(.4 *ARDUINO_PRECISION * scale), BLACK);
  display.drawLine( 5, (DISPLAY_HEIGHT-1)-(.6 *ARDUINO_PRECISION * scale), 10, (DISPLAY_HEIGHT-1)-(.6 *ARDUINO_PRECISION * scale), BLACK);
  display.drawLine( 0, (DISPLAY_HEIGHT-1)-(.8 *ARDUINO_PRECISION * scale), 10, (DISPLAY_HEIGHT-1)-(.8 *ARDUINO_PRECISION * scale), BLACK);
  //display.drawLine( 5, (DISPLAY_HEIGHT-1)-(.84 *ARDUINO_PRECISION * scale), 10, (DISPLAY_HEIGHT-1)-(.84 *ARDUINO_PRECISION * scale), BLACK);
  //Draw Voltage Ref Numbers
  display.setCursor(0,((DISPLAY_HEIGHT-1)-(.2 *ARDUINO_PRECISION * scale))-3);
  display.print((int)(5.0*0.2));
  display.setCursor(0,((DISPLAY_HEIGHT-1)-(.4 *ARDUINO_PRECISION * scale))-3);
  display.print((int)(5.0*0.4));
  display.setCursor(0,((DISPLAY_HEIGHT-1)-(.6 *ARDUINO_PRECISION * scale))-3);
  display.print((int)(5.0*0.6));
  display.setCursor(0,((DISPLAY_HEIGHT-1)-(.8 *ARDUINO_PRECISION * scale))-3);
  display.print((int)(5.0*0.8));
  for(xCounter = 0; xCounter <= DISPLAY_WIDTH; xCounter++)
  {
    display.drawPixel(xCounter, (DISPLAY_HEIGHT-1)-readings[xCounter], BLACK);
    if(xCounter>1){
      display.drawLine(xCounter-1, (DISPLAY_HEIGHT-1)-readings[xCounter-1], xCounter, (DISPLAY_HEIGHT-1)-readings[xCounter], BLACK);
    }
  }
  //Draw FPS
  display.setCursor((DISPLAY_WIDTH-1)-11,0);
  display.print(frames);
  //Draw Voltage
  display.setCursor(((DISPLAY_WIDTH-1)/2),0);
  //display.print(analogRead(channelAI)/ARDUINO_PRECISION*5.0);
  display.print(cs_4_2.capacitiveSensor(30)/ARDUINO_PRECISION*5.0);
  display.display();
  //Calculate FPS
  drawtime = micros();
  frames=1000000/*a second*//(drawtime-lastdraw);
  lastdraw = drawtime;
  a = a + 1 ;
  Serial.print("DATA");
  Serial.print(",");
  Serial.print("a");
  Serial.print(",");
  Serial.println(cs_4_2.capacitiveSensor(30)/ARDUINO_PRECISION*5.0);//204.6 = ARDUINO_PRECISION*5.0
  //delay(1000);// NO delay() is good,otherwise frmae no work  
}

電導式濕度測量(討論)



測量手臂內側保濕度的變化

結果如下:


實際上使用還算滿準的,還可以記錄濕度變化,真方便~~

Flex Abrasion(組裝)

頭髮磨耗測定儀

Flex Abrasion(原理)

將像機器人的Hair combing machine 打橫躺下來,就是一台測頭髮強度(hair strength)機器。