2014年已经来到了3月份,这篇文章算是开年以来的第一篇文章,开始前还是先扯些别的话题吧。
首先是关于马航客机,祝愿他们平安回来,不论生命多么脆弱,为他们祈祷,为他们祝福。
周日的晚上,听着right here waiting,另一边做着永远也做不完的公务员考试题,别样的感觉。也许在一些人眼中,公务员是一份那么形式大于内容的差事,但是并不是说改变没有可能,在困难和阻碍中就蕴藏着改变世界的机会。如果你有足够的勇气和能力,那就加入这个队伍吧,你可以贡献自己的一份力量。
前不久又重新装了一次手机系统,我的电子产品们似乎产生了一种周期性的重装冲动,每每面对这样的场景,我不知道是应该用欲哭无泪来形容还是脱胎换骨来形容,其实算是兼而有之吧。重装使得我可以把过去的不太重要的事情,资料直接忘却,然后就是那些重要的部分留待解决了。比如通讯录中那些存在却不拨打的号码,比如你在记事本里面写下的不切合实际的计划和任务,夹杂一些琐事和无耻吸引注意力的细枝末节。所以,不得不说是一种好事。
好了,新年的开头第一篇,进去正题吧。
其实说到这个max6675,之前并没有概念,是在和别人合作的一个项目中碰巧用到了它,所以也就进行了一些了解,也不算是深入吧,如果有更多的兴趣,您大可以多去文库和wiki找找介绍和datasheet。不过有一点需要插进这个地方,max6675是用来测定温度的,测定温度的,你可能会想起温度传感器来,之前我接触过这个东西,比如热敏电阻,算是一种粗糙但实用的温度测量元件,只不过需要你自己去校准。max6675在这里显然更加高级了,通过自带芯片进行校准计算,最后通讯输出温度值,可以说方便而且实用。那么,仅仅如此吗?不全是,max6675多用于工业场合,或是近似于工业的场合,在一些高温,我说的是上百度的地方,这个时候就没法用普通元件或是传感器了,而且也不太准(热敏电阻可能反而会好),这里还有一个热电偶的出现,在我理解里面,相当于一个温度电压转换装置,由电偶近身接触目标,然后送回数据,给max6675处理,最后协同完成温度测定的光荣使命。
这里控制max6675的中心我用的就是闻名的arduino了,没有闻过这一名的请先绕道恶补五分钟arduino的知识。在arduino的官方网站上是有一个对应的库的,专门给max6675控制用,怎么样,很强大吧。而我在这里介绍的,就是其中的一个示例程序。下面我慢慢道来:
在一份资料中,如下:
The MAX6675 performs cold-junction compensation and digitizes the signal from a type-K thermocouple. The data is output in a 12-bit resolution, SPI tm-compatible, read-only format.
This converter resolves temperatures to 0.25°C, allows readings as high as +1024°C, and exhibits thermocouple accuracy of 8 LSBs for temperatures ranging from 0°C to +700°C.
Key Features
Cold-Junction Compensation
Simple SPI-Compatible Serial Interface
12-Bit, 0.25°C Resolution
Open Thermocouple Detection
讲到max6675的输出是12位的精度,那么按理应该是2的12次方的温度精度,而实际只到1024摄氏度,这是为什么呢?原来,在0摄氏度的右边还有一些空间,也就是到了0.25摄氏度,这样就是2的-2次方了,其精度就是0.25度。而通信方式在其中也提到了,就是SPI。那么现在我们如果想要得到温度值,就需要通过arduino以及SPI协议将max6675驱动起来,读出它不断送出的温度值。直接上arduino中的示例程序吧:
/*
Single_Temp.pde - Example using the MAX6675 Library.
Created by Ryan McLaughlin <ryanjmclaughlin@gmail.com>
*/
#include <MAX6675.h>
int LED1 = 9; // Status LED Pin
int CS = 10; // CS pin on MAX6675
int SO = 12; // SO pin of MAX6675
int SCK = 13; // SCK pin of MAX6675
int units = 0; // Units to readout temp (0 = ˚F, 1 = ˚C)
float error = 0.0; // Temperature compensation error
float temperature = 0.0; // Temperature output variable
// Initialize the MAX6675 Library for our chip
MAX6675 temp0(CS0,SO,SCK,units,error);
// Setup Serial output and LED Pin
// MAX6675 Library already sets pin modes for MAX6675 chip!
void setup() {
Serial.begin(9600);
pinMode(LED1, OUTPUT);
}
void loop() {
temperature = temp0.read_temp(5); // Read the temp 5 times and return the average value to the var
if(temperature == -1) { // If there is an error with the TC, temperature will be -1
Serial.println("Thermocouple Error!!"); // Temperature is -1 and there is a thermocouple error
digitalWrite(LED1, HIGH); // Turn on the status LED
} else {
Serial.print("Current Temperature: ");
Serial.println( temperature ); // Print the temperature to Serial
digitalWrite(LED1, LOW); // Turn on the status LED
}
delay(1000); // Wait one second before reading again
}
不妨再看看它的声明头文件:
/*
MAX6675.h - Library for reading temperature from a MAX6675.
Created by Ryan McLaughlin <ryanjmclaughlin@gmail.com>
*/
#ifndef MAX6675_h
#define MAX6675_h
#include "WProgram.h"
class MAX6675
{
public:
MAX6675(int CS_pin, int SO_pin, int SCK_pin, int units, float error);
float read_temp(int samples);
private:
int _CS_pin;
int _SO_pin;
int _SCK_pin;
int _units;
float _error;
};
#endif
可以看到这里使用的是c++编程语言。将max6675的相关数据和操作都进行了很好的封装,其实在类似这样的场合,c语言才是使用的最多的语言,主要可能还是更加贴近低层的硬件吧。
在源文件中,可以看到明显的arduino编程的特点,一个是setup,还有一个是loop也就是相当于c程序中的while语句,不断的进行执行。最开始的地方进行引脚的设定,这也是推荐的一种方式,如果采用硬编码的方式进行制定,难免在后期的改变过程中引入不必要的麻烦,而且还有相当大的可能性会被改错。对照相应的数字连接arduino上的引脚,然后这里通过串口就可以读出实际的温度值了,注意,在max6675的同名构造函数中,有一个参数名叫units,这个参数是用来指定输出的温度值的单位的,别忘了设定成摄氏度哦。将程序烧写入arduino,然后就可以在arduino集成开发环境自带的串口监视器中看到实时的温度值啦。
由于这里的max6675对相关的重要操作都进行了很好的封装,难免给人一种很简单的感觉,其实,主要的spi等实现细节都在cpp文件中,如果想要研究是可以自己去好好看看的,这里贴上:
/*
MAX6675.cpp - Library for reading temperature from a MAX6675.
Created by Ryan McLaughlin <ryanjmclaughlin@gmail.com>
*/
#include <WProgram.h>
#include <MAX6675.h>
MAX6675::MAX6675(int CS_pin, int SO_pin, int SCK_pin, int units, float error)
{
pinMode(CS_pin, OUTPUT);
pinMode(SO_pin, INPUT);
pinMode(SCK_pin, OUTPUT);
digitalWrite(CS_pin, HIGH);
_CS_pin = CS_pin;
_SO_pin = SO_pin;
_SCK_pin = SCK_pin;
_units = units;
_error = error;
}
float MAX6675::read_temp(int samples)
{
int value = 0;
int error_tc = 0;
float temp = 0;
for (int i=samples; i>0; i--){
digitalWrite(_CS_pin,LOW); // Enable device
/* Cycle the clock for dummy bit 15 */
digitalWrite(_SCK_pin,HIGH);
digitalWrite(_SCK_pin,LOW);
/* Read bits 14-3 from MAX6675 for the Temp
Loop for each bit reading the value and
storing the final value in 'temp'
*/
for (int i=11; i>=0; i--){
digitalWrite(_SCK_pin,HIGH); // Set Clock to HIGH
value += digitalRead(_SO_pin) << i; // Read data and add it to our variable
digitalWrite(_SCK_pin,LOW); // Set Clock to LOW
}
/* Read the TC Input inp to check for TC Errors */
digitalWrite(_SCK_pin,HIGH); // Set Clock to HIGH
error_tc = digitalRead(_SO_pin); // Read data
digitalWrite(_SCK_pin,LOW); // Set Clock to LOW
digitalWrite(_CS_pin, HIGH); //Disable Device
}
value = value/samples; // Divide the value by the number of samples to get the average
/*
Keep in mind that the temp that was just read is on the digital scale
from 0˚C to 1023.75˚C at a resolution of 2^12. We now need to convert
to an actual readable temperature (this drove me nuts until I figured
this out!). Now multiply by 0.25. I tried to avoid float math but
it is tough to do a good conversion to ˚F. THe final value is converted
to an int and returned at x10 power.
*/
value = value + _error; // Insert the calibration error value
if(_units == 0) { // Request temp in ˚F
temp = ((value*0.25) * (9.0/5.0)) + 32.0; // Convert value to ˚F (ensure proper floats!)
} else if(_units == 1) { // Request temp in ˚C
temp = (value*0.25); // Multiply the value by 0.25 to get temp in ˚C
}
/* Output -1 if there is a TC error, otherwise return 'temp' */
if(error_tc != 0) {
return -1;
} else {
return temp;
}
}
这里的引脚驱动主要是使用的digitalwrite这个函数来实现的,当然,严格按照时序。在另一份实现中,我看到作者使用了arduino自带的SPI库,这样可能更加的方便吧,不过其实实现起来基本是一样的。好了,新年第一帖,就此结束吧。给大家拜个晚年啦。
用户1152031 2014-3-20 16:03