2019年10月22日 星期二

輔導團到校輔導2

107學年第一次的輔導團到校輔導,我分享的是
1.教具『手機顯微鏡』與操作方法,並讓每個到場的老師領取10個手機顯微鏡
2.十二年國教新課綱素養導向教學-學習表現-探究能力-問題解決,包含其內涵與課程設計方法

108學年先接續107年分享部分,說明手機顯微鏡的進階用法,與其他輔助顯微鏡觀察的好工具
1.手機顯微鏡操作

2.手機顯微鏡觀察水中小生物
3.顯微鏡輔助器材-顯微鏡用手機夾

另外關於十二年國教新課綱自然領域,介紹的是
素養導向教學-學習表現-探究能力-思考智能-建立模型
簡報內容如下


首先將科學分類成三大部分
1.知識概念
2.工具技能
3.科學方法



試著將七、八、九年級上下學期的自然科實驗分成:有無實驗設計、量化或質化,並做成四象限圖,可以發現七年級首重觀察,八年級重視量化跟實驗設計,而我們每週1次的探究教學也可以從這個方向去發想






除了探究教學以外,新課綱素養導向教學還有另一個區域是:思考智能
要訓練學生的思考智能之前,我們必須先知道什麼東西是思考智能,這部分可以參考阿簡老師-新竹光華國中簡志祥老師的文章
演講紀錄-探究課程工作坊之分析與發現(6)-用運算思維進行科學方法
這一系列的文章都很經典,也是探究教學的很好入門磚。

在這樣的課程設計下,教師必須先檢視每個實驗課程的細節,並抽絲剝繭到最小化單位為止,以理化課程竹筷乾餾為例,教師應該拆解出竹筷乾餾的最小單位,並去蕪存菁的詢問自己:這個實驗到底是要教學什麼概念?

如果授課時只是覺得竹筷乾餾是一個很有趣的課程,可以噴火還可以在課後用炭筆寫字,這樣的層次其實是不太科學的,而這部分我們分析起來可以發現:竹筷乾餾是放在-有機物,這個單元裡面,目的其實是為了驗證什麼是有機物
進一步思考為什麼要乾餾竹筷,不乾餾其他東西呢?還是因為竹筷比較有趣?
判斷是否為有機物就只能用乾餾而已嗎?
因此教師也可以更聚焦在運用乾餾這個技巧來讓學生觀察日常生活中的東西是否為有機物,或是直接給不一樣的組別操作不同材料,並統整學生需要學習的素養有哪些,這樣就可以是一個探究教學課程規劃的方式了。

另外的方法我們也可以用在所有的科學實驗,將這些實驗模組化、去蕪存菁、思考要教授的知識、技能與情意個別是那些,先問自己WHY,在問自己HOW,這樣設計起來的科學實驗就會更符合探究教學的精神了。而老師思考課程的同時,也就是訓練教師的思考智能,包含建立模型-運算思維-問題拆解-模組化-化繁為簡-演算法...這些技巧也就能夠潛移默化在課程當中,讓學生學習到符合科學與問題解決的態度了。


2019年10月18日 星期五

arduino整合:DHT11/超音波測距...

自從學了比較正統的語言學之後,雖然覺得還是差很多練習,但是有感覺比較順一點了,目前工作進度是這樣,預計整合DHT11溫溼度、DS18b20溫度、超音波測距、顏色顯示與調整1按鈕1可變電阻、馬達可變電阻調整角度、發聲頻率調整等...
以下是目前的進度

int
PulseWire = A2,
Threshold = 550,
potPin = A3,
R = 0,
ds18b20 = 1,
button = 2,
buzzer = 3,
motorPin = 4,
DHTPin = 10,
ledRPin = 5,
ledGPin = 6,
ledBPin = 11,
cR=0,cG=0,cB=0,
trigPin = 12,        //Trig Pin
echoPin = 13,        //Echo Pin
cm = 0,
menu1N = 4,
menu2N = 6,
delaytime = 100;

//motor
#include <Servo.h>
Servo myservo;

//DHT11/22
#include <DHT.h>
DHT dht(DHTPin, DHT11);

//DS18b20
#include <DallasTemperature.h>
OneWire oneWire(ds18b20);
DallasTemperature sensors(&oneWire);

//程式庫標頭檔
#include <OneWire.h>

//OLED
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
//OLEDsetting
#define LOGO16_GLCD_HEIGHT 16
#define LOGO16_GLCD_WIDTH  16
#if (SSD1306_LCDHEIGHT != 32)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif

//menu
int mode1=1, mode2=0;

void setup() {
  Serial.begin(9600);
  Wire.begin();

  //buzzer
  pinMode(buzzer,OUTPUT);

  //soundsonic
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);

  //ds18b20
  sensors.begin();

  //button
  pinMode(button, INPUT_PULLUP);

  //DHT
  dht.begin();

  //motor
  myservo.attach(motorPin);
  myservo.write(90);

  //OLED
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.clearDisplay();
}

void loop() {
  int sw = digitalRead(button);
  R = analogRead(potPin);
  display.setTextColor(WHITE);
  display.setCursor(0,0);             //字體位置
  display.setTextSize(1);             //字體大小
  if(sw == HIGH)menu();
  if(mode2 == 0)RGBLED();
    if ( mode2 != 0 ) {
      analogWrite(ledRPin, 0);
      analogWrite(ledGPin, 0);
      analogWrite(ledBPin, 0);
    }
  if(mode2 == 1)DHTxx();
  if(mode2 == 2)Buzzer();
    if ( mode2 != 2 ) {
      noTone(buzzer);
    } 
  if(mode2 == 3)supersonic();
  if(mode2 == 4)motor();
  if(mode2 == 5)openmenu();
}

void menu(){
  unsigned long duration = pulseIn(button, HIGH ,2500000);
  if (duration != 0) {               
    Serial.print("duration: ");
    Serial.print(duration);
    Serial.println(" microseconds");
    mode1 = mode1 + 1;
  } else {
    Serial.println("timeout");
    mode2 = mode2 + 1;
  }
  if ( mode2 == menu2N ) mode2 = 0;
  if ( mode1 == (menu1N+1) ) mode1 = 1;
}

void openmenu(){
  display.setTextSize(1);
  display.print("orangeV design");
  display.setTextSize(2);
  display.setCursor(0,12);
  display.print("DCJHS LAB");
  display.display();
  display.clearDisplay();
  R = 0;
  mode1 = 1;
}

void Buzzer(){
  R = analogRead(potPin);
  int R1=0,R10=0;
  if ( mode1 >= 3 ) mode1 = 1;
  display.print("Sound");
  display.setCursor(40,0);
  if (mode1==1){
    display.println(" 0 ~ 1000 HZ");
  }else{
    display.println(" 0 ~ 10000 HZ");
  }
  display.setTextSize(2);
  if(R<10){
    noTone(buzzer);
    display.print(0); 
  }else{
    if(mode1==1){
    R1 = R - 10;
    tone(buzzer,R1);
    display.print(R1);
    }else if(mode1==2){
    R10 = R*10-100;
    tone(buzzer,R10);
    display.print(R10);
    } 
  }
  display.setCursor(60,12);
  display.println("Hz");
  display.display();
  display.clearDisplay();
  delay(100);
}

void supersonic(){
  digitalWrite(trigPin, LOW);
  delayMicroseconds(5);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  long duration = pulseIn (echoPin, HIGH),
       cm = (duration) / 58.2
  ;

  if ( mode1 >= 3 ) mode1 = 1;
  display.print("SoundSonic");
  display.setCursor(100,0);
  display.print("mod");
  display.println(mode1);
  display.setTextSize(2);
  display.print(cm);
  display.setCursor(50,9); 
  display.println("CM");
  display.setTextSize(1);
  display.print("sampling=  ");
  R = analogRead(potPin);
  delaytime = R + 100;
  display.print(delaytime);
  display.setCursor(100,24);
  display.print("ms");
  display.display();
  display.clearDisplay();

  if(mode1==2){
    Serial.print(cm);
    Serial.print("CM");
    Serial.print(delaytime);
    Serial.println("ms");
  }
  delay(delaytime);
}

void DHTxx(){
  float DHThum = dht.readHumidity();
  float DHTtemp= dht.readTemperature();
  display.println("DHT");
  display.setTextSize(2);
  display.print(DHThum,0);  //小數點0位
  display.print("% ");
  display.print(DHTtemp,1); //小數點1位
  display.print("C");
  display.display();
  display.clearDisplay();
  delay(delaytime);
}

void motor(){
  R = analogRead(potPin);
  R = map(R, 0, 1020, 0, 180);  // 0-1024 -> 0-180
  myservo.write(R);
  display.println("motor");
  display.setTextSize(2);
  display.print("angle  ");
  display.print(R);
  delay(15);
  display.display();
  display.clearDisplay();
}

void RGBLED(){
  if ( mode1 >= 4 ) mode1 = 1;
  R = analogRead(potPin);
  R = map(R, 0, 1020, 0, 255);  // 0-1024 -> 0-255
  display.print("RGB LED");
  if(mode1==1){
    display.println("   R");
    cR=R;
  }else if(mode1==2){
    display.println("   G");
    cG=R;
  }else if(mode1==3){
    display.println("   B");
    cB=R;
  }else{
    display.println("   clear");
    cR=0;
    cG=0;
    cB=0;
  }
  display.print("R=");
  display.println(cR);
  display.print("G=");
  display.println(cG);
  display.print("B=");
  display.println(cB);
  display.display();
  display.clearDisplay();
  analogWrite(ledRPin, cR);
  analogWrite(ledGPin, cG);
  analogWrite(ledBPin, cB);
}


----------第二版--------
int
PulseWire = A2,
Threshold = 550,
potPin = A3,
R = 0,
ds18b20 = 1,
button = 2,
buzzer = 3,
motorPin = 4,
DHTPin = 10,
ledRPin = 5,
ledGPin = 6,
ledBPin = 11,
cR=0,cG=0,cB=0,
trigPin = 12,        //Trig Pin
echoPin = 13,        //Echo Pin
cm = 0,
menu1N = 4,
menu2N = 6,
delaytime = 100;

int i=0 , j,cm0[6]={0};

//motor
#include <Servo.h>
Servo myservo;

//DHT11/22
#include <DHT.h>
DHT dht(DHTPin, DHT11);

//DS18b20
#include <DallasTemperature.h>
OneWire oneWire(ds18b20);
DallasTemperature sensors(&oneWire);

//程式庫標頭檔
#include <OneWire.h>

//OLED
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
//OLEDsetting
#define LOGO16_GLCD_HEIGHT 16
#define LOGO16_GLCD_WIDTH  16
#if (SSD1306_LCDHEIGHT != 32)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif

//menu
int mode1=1, mode2=0;

void setup() {
  Serial.begin(9600);
  Wire.begin();

  //buzzer
  pinMode(buzzer,OUTPUT);

  //soundsonic
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);

  //ds18b20
  sensors.begin();

  //button
  pinMode(button, INPUT_PULLUP);

  //DHT
  dht.begin();

  //motor
  myservo.attach(motorPin);
  myservo.write(0);

  //OLED
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.clearDisplay();
}

void loop() {
  int sw = digitalRead(button);
  R = analogRead(potPin);
  display.setTextColor(WHITE);
  display.setCursor(0,0);
  display.setTextSize(1);
  if(sw == HIGH)menu();
  if(mode2 == 3)RGBLED();
    if ( mode2 != 0 ) {
      analogWrite(ledRPin, 0);
      analogWrite(ledGPin, 0);
      analogWrite(ledBPin, 0);
    }
  if(mode2 == 1)DHTxx();
  if(mode2 == 2)Buzzer();
    if ( mode2 != 2 ) {
      noTone(buzzer);
    }
  if(mode2 == 0)supersonic();
  if(mode2 == 4)motor();
  if(mode2 == 5)openmenu();
}

void menu(){ 
  int k0,k1,tt=0;
  AA1: k0=digitalRead(button);  delay(30);
  k1 = digitalRead(button);
  if (k1==LOW) goto AA1;  //判断按键是否低电平,如果低,循环检测,如果高则下一句
  AA2: tt++;             //对按键高电平计数
  k0 = digitalRead(button);  delay(10);
  k1 = digitalRead(button);
  if (k1==HIGH) goto AA2;  //判断按键是否高电平,如果高,继续计数,如果低电平,则表示按键结束
  if (tt<30)   mode1 = mode1 + 1;         //如果按键时间小于30*10ms=0.3s
  if (tt>80)  mode2 = mode2 + 1;         //如果按键时间大于80*10ms=0.8s
  if ( mode2 == menu2N ) mode2 = 0;
  if ( mode1 == (menu1N+1) ) mode1 = 1;
}

void openmenu(){
  display.setTextSize(1);
  display.print("orangeV design");
  display.setTextSize(2);
  display.setCursor(0,12);
  display.print("DCJHS LAB");
  display.display();
  display.clearDisplay();
  R = 0;
  mode1 = 1;
}

void Buzzer(){
  R = analogRead(potPin);
  int R1=0,R10=0;
  if ( mode1 >= 3 ) mode1 = 1;
  display.print("Sound");
  display.setCursor(40,0);
  if (mode1==1){
    display.println(" 0 ~ 1000 HZ");
  }else{
    display.println(" 0 ~ 10000 HZ");
  }
  display.setTextSize(2);
  if(R<10){
    noTone(buzzer);
    display.print(0);
  }else{
    if(mode1==1){
    R1 = R - 10;
    tone(buzzer,R1);
    display.print(R1);
    }else if(mode1==2){
    R10 = R*10-100;
    tone(buzzer,R10);
    display.print(R10);
    } 
  }
  display.setCursor(60,12);
  display.println("Hz");
  display.display();
  display.clearDisplay();
  delay(100);
}

void supersonic(){
  digitalWrite(trigPin, LOW);
  delayMicroseconds(5);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  long duration = pulseIn (echoPin, HIGH),
      cm = (duration) / 58.2
  ;
  if ( mode1 >= 3 ) mode1 = 1;
  display.print("SoundSonic");
  display.setCursor(100,0);
  display.print("mod");
  display.println(mode1);
  display.setTextSize(1);
  display.print("sampling=  ");
  R = analogRead(potPin);
  delaytime = R/100 * 100+100;
  display.print(delaytime);
  display.setCursor(100,8);
  display.println("ms");

  display.setTextSize(2);
  if (cm<60&&cm>3){
    display.print(cm);
  }else{
    display.print("??");
  }
  display.setCursor(45,16);
  display.println("CM");
  display.display();
  display.clearDisplay();

  if(mode1==2){
    Serial.print(cm);
    Serial.print("CM");
    Serial.print(delaytime);
    Serial.println("ms");
    if(i>=6)i=0;
    if(i<6){
      if (cm<60&&cm>3){
        cm0[i]=cm;
      }else{
        cm0[i]=0;
      }
      display.setTextSize(1);
      display.setCursor(75,16);
      display.print(cm0[0]);
      display.setCursor(95,16);
      display.print(cm0[1]);
      display.setCursor(115,16);
      display.print(cm0[2]);
      display.setCursor(75,23);
      display.print(cm0[3]);
      display.setCursor(95,23);
      display.print(cm0[4]);
      display.setCursor(115,23);
      display.print(cm0[5]);
      i++;
    }
  }
  delay(delaytime);
}

void DHTxx(){
  float DHThum = dht.readHumidity();
  float DHTtemp= dht.readTemperature();
  display.println("DHT");
  display.setTextSize(2);
  display.print(DHThum,0);  //小數點0位
  display.print("% ");
  display.print(DHTtemp,1); //小數點1位
  display.print("C");
  display.display();
  display.clearDisplay();
  delay(delaytime);
}

void motor(){
  R = analogRead(potPin);
  R = map(R, 0, 1020, 0, 180);  // 0-1024 -> 0-180
  myservo.write(R);
  display.println("motor");
  display.setTextSize(2);
  display.print("angle  ");
  display.print(R);
  delay(15);
  display.display();
  display.clearDisplay();
}

void RGBLED(){
  if ( mode1 >= 4 ) mode1 = 1;
  R = analogRead(potPin);
  R = map(R, 0, 1020, 0, 255);  // 0-1024 -> 0-255
  display.print("RGB LED");
  if(mode1==1){
    display.println("   R");
    cR=R;
  }else if(mode1==2){
    display.println("   G");
    cG=R;
  }else if(mode1==3){
    display.println("   B");
    cB=R;
  }else{
    display.println("   clear");
    cR=0;
    cG=0;
    cB=0;
  }
  display.print("R=");
  display.println(cR);
  display.print("G=");
  display.println(cG);
  display.print("B=");
  display.println(cB);
  display.display();
  display.clearDisplay();
  analogWrite(ledRPin, cR);
  analogWrite(ledGPin, cG);
  analogWrite(ledBPin, cB);
}

----第三版------
int
PulseWire = A2,
Threshold = 550,
potPin = A3,
R = 0,
button = 2,
buzzer = 3,
motorPin = 4,
ds18b20 = 9,
DHTPin = 10,
ledRPin = 5,
ledGPin = 6,
ledBPin = 11,
cR=0,cG=0,cB=0,
trigPin = 12,        //Trig Pin
echoPin = 13,        //Echo Pin
menu1N = 4,
menu2N = 6,
delaytime = 100;

float cm = 0.0;
int i=0 , j,cm0[9]={0};

//motor
#include <Servo.h>
Servo myservo;

//DHT11/22
#include <DHT.h>
DHT dht(DHTPin, DHT11);



//
#include <OneWire.h>

//DS18b20
#include <DallasTemperature.h>
OneWire oneWire(ds18b20);
DallasTemperature sensors(&oneWire);


//OLED
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
//OLEDsetting
#define LOGO16_GLCD_HEIGHT 16
#define LOGO16_GLCD_WIDTH  16
#if (SSD1306_LCDHEIGHT != 32)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif

//menu
int mode1=1, mode2=0;

void setup() {
  Serial.begin(9600);
  Wire.begin();

  //buzzer
  pinMode(buzzer,OUTPUT);

  //soundsonic
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);

  //ds18b20
  sensors.begin();

  //button
  pinMode(button, INPUT_PULLUP);

  //DHT
  dht.begin();

  //motor
  myservo.attach(motorPin);
  myservo.write(0);

  //OLED
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.clearDisplay();
}

void loop() {
  int sw = digitalRead(button);
  R = analogRead(potPin);
  display.setTextColor(WHITE);
  display.setCursor(0,0);
  display.setTextSize(1);
  if(sw == HIGH)menu();
  if(mode2 == 0)DHTxx();
  if(mode2 == 1)RGBLED();
    if ( mode2 != 1 ) {
      analogWrite(ledRPin, 0);
      analogWrite(ledGPin, 0);
      analogWrite(ledBPin, 0);
    }
  if(mode2 == 2)Buzzer();
    if ( mode2 != 2 ) noTone(buzzer);
  if(mode2 == 3)supersonic();
  if(mode2 == 4)motor();
    if ( mode2 != 4 ) myservo.write(0);
  if(mode2 == 5)openmenu();
}

void menu(){ 
  int k0,k1,tt=0;
  AA1: k0=digitalRead(button);  delay(30);
  k1 = digitalRead(button);
  if (k1==LOW) goto AA1;  //判断按键是否低电平,如果低,循环检测,如果高则下一句
  AA2: tt++;             //对按键高电平计数
  k0 = digitalRead(button);  delay(10);
  k1 = digitalRead(button);
  if (k1==HIGH) goto AA2;  //判断按键是否高电平,如果高,继续计数,如果低电平,则表示按键结束
  if (tt<30)   mode1 = mode1 + 1;         //如果按键时间小于30*10ms=0.3s
  if (tt>80)  mode2 = mode2 + 1;         //如果按键时间大于80*10ms=0.8s
  if ( mode2 == menu2N ) mode2 = 0;
  if ( mode1 == (menu1N+1) ) mode1 = 1;
}

void openmenu(){
  display.setTextSize(1);
  display.print("orangeV design");
  display.setTextSize(2);
  display.setCursor(0,12);
  display.print("DCJHS LAB");
  display.display();
  display.clearDisplay();
  R = 0;
  mode1 = 1;
}

void Buzzer(){
  R = analogRead(potPin);
  int R1=0,R10=0;
  if ( mode1 >= 3 ) mode1 = 1;
  display.print("Sound");
  display.setCursor(40,0);
  if (mode1==1){
    display.println(" 0 ~ 1000 HZ");
  }else{
    display.println(" 0 ~ 10000 HZ");
  }
  display.setTextSize(2);
  if(R<10){
    noTone(buzzer);
    display.print(0);
  }else{
    if(mode1==1){
    R1 = R - 10;
    tone(buzzer,R1);
    display.print(R1);
    }else if(mode1==2){
    R10 = R*10-100;
    tone(buzzer,R10);
    display.print(R10);
    } 
  }
  display.setCursor(60,12);
  display.println("Hz");
  display.display();
  display.clearDisplay();
  delay(100);
}

void supersonic(){
  digitalWrite(trigPin, LOW);
  delayMicroseconds(5);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  float duration = pulseIn (echoPin, HIGH),
      cm = (duration) / 58.2
  ;
  if ( mode1 >= 4 ) mode1 = 1;
  display.print("SoundSonic 2to60");
  display.setCursor(100,0);
  display.print("mod");
  display.println(mode1);
  display.setTextSize(1);
  display.print("t= ");
  R = analogRead(potPin);
  delaytime = R/100 * 100+100;
  if(mode1==3) delaytime = delaytime/10;
  display.print(delaytime);
  display.setCursor(44,8);
  display.println("ms");
  int cm10=cm*10;
  display.setTextSize(2);
  if (cm<60&&cm>2){
    display.print(cm10/10);
    display.setTextSize(1);
    display.setCursor(25,23);
    display.print(".");
    int cm100=cm*100;
    display.print(cm100%100/10);
  }else{
    display.print("err");
  }
  display.setTextSize(2);
  display.setCursor(37,16);
  display.println("CM");

  display.display();
  display.clearDisplay();

  if(mode1==2||mode1==3){
    Serial.print(cm);
    Serial.print("CM");
    Serial.print(delaytime);
    Serial.println("ms");
    if(i>=9)i=0;
    if(i<9){
      if (cm<60&&cm>3){
        cm0[i]=cm;
      }else{
        cm0[i]=0;
      }
      display.setTextSize(1);
      display.setCursor(70+20*(i%3),(i/3)*7+10);
      display.print("*");
      display.setCursor(75,10);
      display.print(cm0[0]);
      display.setCursor(95,10);
      display.print(cm0[1]);
      display.setCursor(115,10);
      display.print(cm0[2]);
      display.setCursor(75,16);
      display.print(cm0[3]);
      display.setCursor(95,16);
      display.print(cm0[4]);
      display.setCursor(115,16);
      display.print(cm0[5]);
      display.setCursor(75,23);
      display.print(cm0[6]);
      display.setCursor(95,23);
      display.print(cm0[7]);
      display.setCursor(115,23);
      display.print(cm0[8]);
      i++;
    }
  }
  delay(delaytime);
}

void DHTxx(){
  sensors.requestTemperatures();
  float DHThum = dht.readHumidity();
  float DHTtemp= dht.readTemperature();
  float cc = sensors.getTempCByIndex(0);

  display.print("T & H ");

  if ( mode1 >= 4 ) mode1 = 1;
  display.print("t = ");
  R = analogRead(potPin);
  delaytime = R/100 * 100+100;
  if(mode1==3) delaytime = delaytime*10;
  display.print(delaytime);
  display.println(" ms");

  display.print(DHThum,0);  //小數點0位
  display.print("% ");
  display.print(DHTtemp,1); //小數點1位
  display.println("C");
  display.setTextSize(2);
  if(cc>-127){
    display.print(cc,1);
  }
  display.print("C");

  if(mode1>=2){
    if(i>=6)i=0;
    if(i<6){
      if (cc>-170){
        cm0[i]=cc;
      }else{
        cm0[i]=0;
      }
      display.setTextSize(1);
      display.setCursor(60+30*(i%2),(i/2)*6+10);
      display.print("*");
      display.setCursor(65,10);
      display.print(cm0[0],1);
      display.setCursor(95,10);
      display.print(cm0[1],1);
      display.setCursor(65,16);
      display.print(cm0[2],1);
      display.setCursor(95,16);
      display.print(cm0[3],1);
      display.setCursor(65,22);
      display.print(cm0[4],1);
      display.setCursor(95,22);
      display.print(cm0[5],1);
      i++;
    }
  }
  display.display();
  display.clearDisplay();
  delay(delaytime);
  delaytime = 0;
}

void motor(){
  R = 0;
  R = analogRead(potPin);
  R = map(R, 0, 1020, 0, 180);  // 0-1024 -> 0-180
  myservo.write(R);
  display.println("motor");
  display.setTextSize(2);
  display.print("angle  ");
  display.print(R);
  delay(15);
  display.display();
  display.clearDisplay();
}

void RGBLED(){
  R = 0;
  if ( mode1 >= 4 ) mode1 = 1;
  R = analogRead(potPin);
  R = map(R, 0, 1020, 0, 255);  // 0-1024 -> 0-255
  display.print("RGB LED");
  if(mode1==1){
    display.println("   R");
    cR=R;
  }else if(mode1==2){
    display.println("   G");
    cG=R;
  }else if(mode1==3){
    display.println("   B");
    cB=R;
  }else{
    display.println("   clear");
    cR=0;
    cG=0;
    cB=0;
  }
  display.print("R=");
  display.println(cR);
  display.print("G=");
  display.println(cG);
  display.print("B=");
  display.println(cB);
  display.display();
  display.clearDisplay();
  analogWrite(ledRPin, cR);
  analogWrite(ledGPin, cG);
  analogWrite(ledBPin, cB);
}


----
按鍵程式參考
https://www.geek-workshop.com/thread-28007-1-1.html



2019年8月9日 星期五

運算思維:演算法教與學-以用micro:bit設計一個運動輔助儀器專題為例

暑假我設計了一個課程,學生從無到有學習micro:bit並且可以設計一個運動輔助的儀器,給學生的材料大致上是運用micro:bit本身上面有的學習單元去進行引導,最後給與一張結合運算思維演算法的學習單,先用紙筆進行規劃,想好在上去設計程式,不過我覺得很想設計程式的人容易跳過紙筆思考流程的步驟,實在是很可惜的一件事情,畢竟很多時候卡住了會跟一開始流程設計的順不順有關係,如果能先把流程設定好,應該是比較容易抓蟲的。
以下是moodle的課程表,課程請點(連結)

每次跟著micro:bit課程做完一個小專案,我就請學生進行檢核,讓他知道這個專案希望他學會什麼能力

基本上4堂課可以半自學一些基礎能力,像是基本、輸入、邏輯、變數、隨機取數,這次比之前的課程設計多了廣播的教學,希望他們可以做出多機互動,不過唯2想做多機互動的一個遊戲設計太複雜沒辦法在時間內做完,而且他根本不想畫演算法,所以造成思惟上的混亂,如果好好用演算法圖是爬梳一下,應該會比較好想出卡關的點才對

至於書面資料跟上機操作其實是相符相乘,所以如果某一邊卡住,往另一邊做看看,就可以反覆補齊整個程式了,這也是往後我自己在寫程式的時候可以思考的一種程序。
至於有了書面資料,也比較方便我跟學生溝通,至少他們少了什麼部分,我可以說:不知道怎麼隨機變換顯示的動作,你先做做看猜拳那個專案;不知道怎麼亂數取號,你先做做看骰子那個專案;不知道方塊在哪裡,你可以看學習單上面的項次,就可以提升我們溝通的效率與效能了。
下方是最後的學生成品與設計單,如果一次段考之間也差不多是6-7堂課,應該也可以做出一個小專案才是。









以下是學習單供下載與參考



(word下載)



2019年8月1日 星期四

東京科學活動出展心得-青少年のための科学祭典全国大会at東京科學技術館

屏東至正國中邱彥文老師邀約台南佳興國中陳坤龍老師跟我一起組團,由台東大學林自奮教授跟小熊貓教具的白仲偉提供材料,來參加日本數一數二的民營科學活動:青少年のための科学祭典全国大会at東京科學技術館,這可能是他們1992年開辦以來少數的台灣團體。在申請活動的過程中,光看彥文老師跟主辦事務所email往返,就知道日本人做事情是多麼嚴謹,而在申請經費的部分又是多麼大方跟直接,人家的sop都已經進展到非常完善的狀態,書面的資料跟程序都非常的清楚,而承辦也十分細心的溝通協調,很佩服他們在傳承與延續的用心,是我們要好好學習的重要關鍵。

(左起:筆者、台東大學林自奮教授、屏東至正國中邱彥文、台南佳興國中陳坤龍)



9:30開場,9:00就要排隊入場的盛況,每個人都抓緊時間想要多跑幾攤,今天科學祭典免費,甚至2F的常設展高中以下也免費,而且這個博物館本身是民營的幾家公司贊助營運,還有一個協會負責各地的科學祭典(全國大會算是最盛大的一場)、科學活動贊助與基礎科學的支援,是民營的啊啊啊啊啊!





我們的攤位連續六日兩天,從早上9:30-16:30,不含休息一個小時,共6個小時的科學手作活動,每組約15分鐘,每次3個人次,主要由我本人以全日文講解科學概念,(如果有英文或是中文就會請夥伴老師協助),另外兩位老師協助手作部分與事前聯繫跟材料準備,總算完成整個活動與交流。








我們有申請一個助手,兩天各有一個日本大學生來協助(田口さん&菅原さん),兩位大學生都非常有耐心且盡責的協助我們整體的運作,覺得日本人素質真的很高,而兩位關注到的面相剛好不同,也補足了我們教學上的的缺失與需求。

在活動中兩位都盡心盡力、努力學習,6個小時裡我都站著或彎腰,他們兩位也沒有坐下來的時候,連一次也沒離開,全程跟我們一起撐住整場,這點讓我很佩服他們的服務精神。而且他們很有『講師都沒休息坐下了,我們也不能休息坐下』的倫常概念。

我會後跟志工討論今天的狀況如何呢?我先提出為什麼某些點要這麼處理的教學技巧後,他們也很快就可以抓到其他重點,甚至於是提出很真切的建議,即使他們才18歲左右,面對我們這些大叔,可以毫不忌諱輩分問題,且提出的觀點直指核心。

第一天田口さん說我建立流程的速度很快,而且過了幾輪測試後就很順,但是如果在很多人的時候是否先統一講解後再排隊等製作?或是維持原樣有維持原樣的好處?
第二天菅原さん說我是生物老師怎麼可以把物理這麼難的東西(用日文)講的很清楚,然後說東京人其實不喜歡別人嗓門大;不過我不是東京人我這方面可以很放心的入境不隨俗啊,
(這叫文化衝擊XDDD,但是真的東京人壓力很大,容易緊張,心思纖細,的確不太喜歡太吵鬧的狀態,遊客自己請自重。)

在日本時間是很重要的觀念,我們也入境隨俗,什麼時候開始、休息、結束都照表操課,休息時桌面都清空,這是我們試著融入人家的規矩,不要讓對方覺得我們太沒有禮貌,雖然還是有文化差異或衝突,但是我們是外國人,也已經盡力了,對方應該也比較能寬容一些


(活動中一半站著另一半都是彎腰)

整個活動雖然辛苦,但是很充實,第二天最後幾場我其實有種:已經不是20歲小伙子的感慨(因為我是18歲我知道),一直彎腰教學起來我都快歪腰了,但是我可以發自內心的保證我有耐心的對待每個參加活動的小孩大人,而且堅持我們科學教育的尺,雖然聽眾8成是小孩,但是你可以發現日本小孩非常有耐心的聆聽你的教學,一雙眼睛水汪汪的期待下一個梗,回答問題也很熱絡,兩天下來大約有150人次,只有1,2個比較過激的小孩,要稍微建立秩序與默契以外,其他每個都很認真,而且不少家長都會在後面一起學習並安靜等候(而不是下指導棋),當然我們可以說:會一大早帶小孩排隊參加科學活動的家庭素質都比較高,但是日本人是真的超高超高,暑假假日沒事,家長帶小孩來參加免費的科學活動,金源主要還不是政府,而是企業捐款的科學活動,你就知道這個國家推動科學教育是如何的用心與踏實,如何把平凡且重要的事做好。
(家長大多會陪著靜靜觀看或共同學習)

(這一組是台灣來的大學生,就交給自奮教授跟彥文了)


最後,很開心自己的語言已經可以用來跟日本人不只是溝通,而是傳授一個科學概念,而且大人小孩感覺都很有收穫,至少小孩的笑容是不會騙人的(當然我也知道日本人很會做表面,他們現在稱讚我日文說的很好我也不會開心,因為三年前我很爛的時候他們就會稱讚我日文很好了,大概你只要會三餐問候他們就會說好棒棒的感覺,不過當有商家誤會我是沖繩來的,或是在日本工作之類的,我就會覺得心裡比較踏實一些,表示大概能溝通了)但是還是覺得不太夠,學習就是永遠不夠吧...

在教學過程中,我還是秉持幾個我個人的基本理念,那就是能讓對方觀察的就先觀察,能讓對方親手操作的就先放手讓他做,只提供必要且我認為的最低底線輔助,而且要淺顯易懂,其中有個小孩似乎是聽障而且手指小肌肉比較無力,我還是僅僅提供最低限度的輔助,讓他多親手操作,這樣學員如果願意做的話,就能從學習中得到快樂與成就了,像我自己長大後的每個學習的樣子,無論是教學這門專業,或是日文,或是其他。學習的過程常常是反覆的,但是你必須在反覆中有效的逐漸進步成長,讓自己酸但不痛,腦筋跟肌肉都是如此,沒有痛苦與逐漸合理的加強,跨出自己的舒適圈,人是不會成長茁壯的。

持續學習成長,讓自己成為一個更好的人。

關於我們台灣可以學習的事情有
1.很多活動即使辦了很多年,但是常常換主辦與單位主管後,活動就走樣了(而且我們很常換主辦或是換人,沒有一個很穩定的統籌單位,真的是我們教育的沉痾),應該要有確實的流程或是專責傳承這件事情的人
2.輩分與敬重這件事情重點是在楷模與經驗的學習,但如果你沒有值得效仿的部分,只能用輩分壓別人那麼當然就......,我們國內常常是上樑出嘴要下樑自己正,這也是要深思的,日本常常可以見到祭典當中有老中青不同年齡層負責不同任務的傳承,但是這些老的也是非常專注的帶領跟守儀,這樣才能讓更多傳承者願意投入,台灣的話...你光是看學校行政有多少40歲以上要出來扛責任與經驗傳承就知道......我們最喜歡年輕人多做多學了呢
3.科學教育應該是普及且日常的,應該是實作體驗的,應該是基礎且紮穩馬步的,不像我們很常追求新潮流,然後就只是追求新潮流而已,沒有基礎,煙火式的活動無法培養出強大的科學國力。
4.企業社會責任,除了這個由企業組成的科學博物館與活動以外,像是Panasonic Center Tokyo博物館裡,把困難的數學與科學概念用遊戲式的科技呈現,你可以邊玩邊體驗質數、光學、波形等複雜的概念,軟硬體部分展現強大的設計感與科學力。軟體與美感部分也是我們幾乎無視的區塊,希望漸漸能夠注重啊。
5.博物館活動套票只要2200日日幣,可以在2個月內玩體驗超多東京的博物館、動物園、水族館等,無論小孩子的暑假或是平常假日,都很適合浸潤在文化的環境中,而且是非常親民的價錢,希望我們也能有類似的套票組合。(東京博物館通票Grutto pass2019連結,我用這個去了panasonic center、葛西臨海水族園、上野動物園,如果有時間真的可以慢慢享受知性之旅)

(這攤都是骨頭跟皮我很想要聽但是沒時間聽啊,不過其實動物名字我也會聽不懂,老鼠的毛皮跟海蟾蜍的外皮摸起來很有趣)

葉脈標本製作是生物老師的好朋友

(第一天開場前的試做與說明)






(這是我們這次介紹的靜電檢測器的說明文件)
我們介紹的流程
0.小活動介紹摩擦帶電,例如隔空吸引吸管、用玩具吸引頭髮等
1.靜電檢測器4選1,找出其中不同的靜電檢測器(有一個是正負電反應相反),觀察並說出差異
2.靜電檢測器對正負電的反應觀察與比較,使用正電玩具跟PVC塑膠摩擦後分別測試檢測器,觀察反應並說出差異
3.LED介紹,先觀察LED構造之獨特性並說明(腳與燈泡各一);LED正負極與電池串聯方式猜測如何接才是正確,說明逆接可能燒掉
4.簡易說明電晶體原理,本電晶體可受到電壓與電荷影響造成開關效果
5.觀察快速接頭結構,說明快速接頭使用方法
6.說明串接方式,測試後完成

感謝小熊貓教具的仲偉提供這麼簡易就可以製作的靜電感測器,也謝謝林自奮教授願意以活動援助材料經費並親自參與活動。
感謝彥文跟坤龍提供照片,彥文還問我有沒有拍照,我只差還他一個白眼...

2019年6月3日 星期一

樣區法計算-大成國中操場有多少草+google map計算距離面積

關於課本樣區法運用黑白棋計算,總是覺得離現實生物太遠,那麼我們可以運用什麼方式去計算會更好呢?其實校園內很有可能有一大片的草地,或是選舉造勢晚會常常有人數分析,這些都是很好的思考標的,往年一直都會去計算出校園內一片草地的草的個體數,今年因為探究教學與圖形化的自我訓練下,關於製作講義的功力自覺大幅提升,於是分享一下這次邏輯較完整的計算草地方式,作為參考

課前準備:
學校要有一大片草
4人一組
4隻竹筷/組
4公尺長紅色塑膠繩,並於每1公尺處畫上黑色記號

授課時間:
1節計算草的數量,回家作業+0.5節討論or1節統整學習單問題
帶學生到操場附近陰涼處
Q1請問學校草地這麼大片,要如何計算草的個體數?
Q2:如果要全部都算的優點是什麼?缺點是什麼?
Q3:如果採樣區法,要取幾個要區比較好?為什麼?
Q4:如果樣區多的優缺點是?樣區少的優缺點是?

帶學生到草地上 請每個學生都拔起"一棵草"
Q5:請問什麼是一棵草,一個草的個體?
Q6:請問如果有匍匐莖該如何計算一棵草? 

示範圍地+釘樁(竹筷)
Q7:請問1平方公尺這麼大,那麼操場大概幾平方公尺?我們有沒有辦法精確計算出來?

示範從角落開始計算草的數量方式


學生開始算草20分鐘






word檔案下載
https://drive.google.com/open?id=11oQAxJpEmtzdADhW1xmaOBdVFwsbrXK4

數字計算的部分我是幫忙學生按計算機,面積算出來雖然是5400平方公尺,但是我讓他們用5500平方公尺計算,另外五個樣區取平均也是用手機幫忙計算,僅有3個樣區平均讓他們自己處理,但是會要求一定要寫完整算式。


google map計算距離面積-參考-[重灌狂人]如何在 Google Maps 中測量距離、計算總面積?
1.開啟google map
 2.按衛星地圖

3.在要測量的起點按滑鼠右鍵

4.在要測量的端點按滑鼠左鍵圈出範圍

4.在要測量的端點按滑鼠左鍵圈出範圍

5.包圍出一個封閉圖形就會有面積了

6.包圍完可以拖拉[線]或是[端點]調整範圍