Browse Source

Solved inaccuracy problem with adc. Started with a nice overview for the raw samples

software_develop
Elmar van Rijnswou 7 years ago
parent
commit
6b49cbebb3
  1. 19
      software/app/adc.h
  2. 30
      software/app/ads101x.cpp
  3. 5
      software/app/ads101x.h
  4. 200
      software/app/web_interface.cpp
  5. 111
      software/app/web_interface.h
  6. 22
      software/files/index.html
  7. 5
      software/files/index.js

19
software/app/adc.h

@ -12,13 +12,30 @@
namespace rijnfel {
/**
* Abstract interface for Analog to Digital converters.
* Template holds sample type and voltage type
*/
template<typename Sample, typename Voltage>
class cADC: public cSensor<Sample> {
public:
/**
* Default constructor
*/
cADC() {
}
virtual Voltage ConvertSample(Sample & sample) = 0;
/**
* This virtual function should be implemented to convert a sample to a voltage
* @param i_sample the raw sample that should be converted
* @return a voltage in mili-volt
*/
virtual Voltage ConvertSample(Sample & i_sample) = 0;
/**
* Default destructor
*/
virtual ~cADC() {
}

30
software/app/ads101x.cpp

@ -74,27 +74,34 @@ bool cADS101x::IsReady(void) {
}
uint16_t cADS101x::CreateSettings(uint8_t start) {
return OS_BIT(start) | MUX_BIT(m_mux) | PGA_BIT(m_gain)
| MODE_BIT(m_oneShot) | DR_BIT(m_sampleSpeed);
return OS_BIT(start) | MUX_BIT(m_mux) | PGA_BIT(m_gain) | MODE_BIT(m_oneShot) | DR_BIT(m_sampleSpeed);
}
void cADS101x::WriteSettings(uint16_t i_settings) {
#ifdef DUMMY_ADC
return;
#else
Wire.beginTransmission(m_address);
Wire.write((uint8_t) REGISTER_CONFIG);
Wire.write((uint8_t) (i_settings >> 8));
Wire.write((uint8_t) (i_settings & 0xFF));
int8_t ret = Wire.endTransmission();
if (ret) {
Serial.printf("Err writing settings ret: %d\n\r", ret);
//Serial.printf("Err writing settings ret: %d\n\r", ret);
}
#endif
}
uint16_t cADS101x::ReadRegister(uint8_t i_register) {
#ifdef DUMMY_ADC
return 1;
#else
Wire.beginTransmission(m_address);
Wire.write(i_register);
Wire.endTransmission();
Wire.requestFrom(m_address, static_cast<uint8_t>(2));
return ((Wire.read() << 8) | (Wire.read()));
#endif
}
void cADS101x::OneShot(void) {
@ -105,7 +112,11 @@ void cADS101x::OneShot(void) {
}
uint16_t cADS101x::GetSettings(void) {
return ReadRegister(REGISTER_CONFIG);;
#ifdef DUMMY_ADC
return CreateSettings(0);
#else
return ReadRegister(REGISTER_CONFIG);
#endif
}
ads_voltage_t cADS101x::ConvertSample(ads_sample_t & sample) {
//Raw sample is in (parts of) millivolts, go to micro to remove fractions
@ -140,12 +151,20 @@ ads_voltage_t cADS101x::ConvertSample(ads_sample_t & sample) {
}
ads_sample_t cADS101x::RawSample(void) {
#ifdef DUMMY_ADC
ads_sample_t sample;
sample.gain = m_gain;
sample.mux = m_mux;
sample.rawSample = m_counter++;
return sample;
#else
OneShot();
ads_sample_t sample;
sample.rawSample = ReadRegister(REGISTER_CONVERSION);
sample.gain = m_gain;
sample.mux = m_mux;
m_latestSample = sample;
#endif
return sample;
}
@ -154,6 +173,9 @@ void cADS101x::SetDefaults(void) {
m_gain = eGainAmplifier::FSR_2_048;
m_sampleSpeed = eSampleSpeed::SPS_1600;
m_oneShot = true;
#ifdef DUMMY_ADC
m_counter = 0;
#endif
}
}

5
software/app/ads101x.h

@ -9,6 +9,7 @@
#define APP_ADS101X_H_
#include <stdint.h>
#include "hardware.h"
#include "adc.h"
namespace rijnfel {
@ -65,6 +66,10 @@ private:
enum eInputMux m_mux;
enum eGainAmplifier m_gain;
enum eSampleSpeed m_sampleSpeed;
private:
#ifdef DUMMY_ADC
uint16_t m_counter;
#endif
};
}
}

200
software/app/web_interface.cpp

@ -7,20 +7,18 @@
#include "web_interface.h"
#include <SmingCore/SmingCore.h>
//TODO remove this
#include "ads101x.h"
#include <SmingCore/Network/WebConstants.h>
namespace rijnfel {
cWebInterface *cWebInterface::s_instance = 0;
static void onIndex(HttpRequest &request, HttpResponse &response) {
cWebInterface::GetInstance()->OnIndex(request, response);
static void onIndex(HttpRequest & i_request, HttpResponse & i_response) {
cWebInterface::GetInstance()->OnIndex(i_request, i_response);
}
static void onRefresh(HttpRequest &request, HttpResponse &response) {
cWebInterface::GetInstance()->OnRefresh(request, response);
static void onRefresh(HttpRequest & i_request, HttpResponse & i_response) {
cWebInterface::GetInstance()->OnRefresh(i_request, i_response);
}
static void onConfiguration(HttpRequest &request, HttpResponse &response) {
@ -34,159 +32,174 @@ static void onConfiguration_json(HttpRequest &request, HttpResponse &response) {
cWebInterface::cWebInterface() :
m_serverStarted(false) {
for (int i = 0; i < 4; i++) {
m_adc_value[i] = 0;
m_adc_value_average[i] = 0;
}
// Integer requires 8 digits, and one for the comma
m_jsonBuffer = new char[RAW_SAMPLES * 8 + RAW_SAMPLES * 2];
if (m_jsonBuffer == NULL) {
Serial.print("Not enough ram");
}
// TODO Auto-generated constructor stub
}
void onFile(HttpRequest &request, HttpResponse &response) {
String file = request.getPath();
void onFile(HttpRequest & i_request, HttpResponse & i_response) {
String file = i_request.getPath();
if (file[0] == '/')
file = file.substring(1);
if (file[0] == '.')
response.forbidden();
i_response.forbidden();
else {
response.setCache(86400, true); // It's important to use cache for better performance.
response.sendFile(file);
i_response.setCache(86400, true); // It's important to use cache for better performance.
i_response.sendFile(file);
}
}
void cWebInterface::Start() {
void cWebInterface::StartServer() {
if (m_serverStarted)
return;
server.addPath("/", onIndex);
server.addPath("/state", onRefresh);
server.addPath("/config", onConfiguration);
server.addPath("/config.json", onConfiguration_json);
server.setDefaultHandler(onFile);
server.listen(80);
m_server.addPath("/", onIndex);
m_server.addPath("/state", onRefresh);
m_server.addPath("/config", onConfiguration);
m_server.addPath("/config.json", onConfiguration_json);
m_server.setDefaultHandler(onFile);
m_server.listen(80);
}
void cWebInterface::Stop() {
void cWebInterface::StopServer() {
if (!m_serverStarted)
return;
m_serverStarted = false;
}
void cWebInterface::OnIndex(HttpRequest &request, HttpResponse &response) {
response.setCache(86400, true); // It's important to use cache for better performance.
response.sendFile("index.html");
void cWebInterface::OnIndex(HttpRequest &i_request, HttpResponse & i_response) {
i_response.setCache(86400, true); // It's important to use cache for better performance.
i_response.sendFile("index.html");
}
void cWebInterface::OnRefresh(HttpRequest &request, HttpResponse &response) {
void cWebInterface::OnRefresh(HttpRequest & i_request, HttpResponse & i_response) {
JsonObjectStream* stream = new JsonObjectStream();
JsonObject& json = stream->getRoot();
json["adc_1"] = m_adc_value[0];
json["adc_2"] = m_adc_value[1];
json["adc_1"] = m_adc_value_average[0];
json["adc_2"] = m_adc_value_average[1];
#ifdef REV_1
json["adc_3"] = m_adc_value[3];
json["adc_4"] = m_adc_value[2];
json["adc_3"] = m_adc_value_average[3];
json["adc_4"] = m_adc_value_average[2];
#else
json["adc_3"] = m_adc_value[2];
json["adc_4"] = m_adc_value[3];
json["adc_3"] = m_adc_value_average[2];
json["adc_4"] = m_adc_value_average[3];
#endif
response.sendJsonObject(stream);
char * writePos = m_jsonBuffer;
for (int sample = 0; sample < m_adc_values_raw_cnt[RAW_CHANNEL]; sample++) {
const int pos = sprintf(writePos, "%d,", m_adc_values_raw[RAW_CHANNEL][sample]);
writePos = &m_jsonBuffer[pos];
}/*
json["raw_adc"] = m_jsonBuffer; //ss.str();
*/
i_response.sendJsonObject(stream);
m_adc_values_raw_cnt[RAW_CHANNEL] = 0;
}
void cWebInterface::OnRawUpdate(HttpRequest& i_request, HttpResponse& i_response) {
}
void cWebInterface::UpdateAdc(cADC<ads::ads_sample_t, int32_t> & adc,
cDoubleBuffer<ads::ads_sample_t>& adcBuffer) {
ads::ads_sample_t * buf = &adcBuffer.GetReadyBuffer()[0];
void cWebInterface::UpdateAdc(cADC<ads::ads_sample_t, int32_t> & i_adc, cDoubleBuffer<ads::ads_sample_t>& i_adcBuffer) {
ads::ads_sample_t * buf = &i_adcBuffer.GetReadyBuffer()[0];
if (buf != NULL) {
ads::ads_sample_t averageSample;
averageSample.gain = buf->gain;
averageSample.mux = buf->mux;
int pos = buf->mux - ads::eInputMux::AIN_0;
int64_t average = 0;
//Serial.printf("Channel: %d\n\r", buf->mux - ads::eInputMux::AIN_0);
int size = adcBuffer.GetSize();
int size = i_adcBuffer.GetSize();
for (int i = 0; i < size; i++) {
average += buf[i].rawSample;
//Serial.printf("%d ", buf[i].rawSample);
average += i_adc.ConvertSample(buf[i]);
if (pos == RAW_CHANNEL) {
int idx = m_adc_values_raw_cnt[RAW_CHANNEL];
if (idx < RAW_SAMPLES) {
m_adc_values_raw[RAW_CHANNEL][idx] = i_adc.ConvertSample(buf[i]);
m_adc_values_raw_cnt[RAW_CHANNEL]++;
}
}
}
//Serial.printf("\n\r before: %d", average);
if (size != 0) {
average /= size;
}
//Serial.printf("after: %d [%d]\n\r", average, size);
averageSample.rawSample = static_cast<int16_t>(average);
int pos = averageSample.mux - ads::eInputMux::AIN_0;
m_adc_value[pos] = adc.ConvertSample(averageSample);
m_adc_value_average[pos] = static_cast<int32_t>(average);
}
}
void cWebInterface::PrintValues() {
Serial.printf("c[0]: %d c[1]: %d c[2]: %d c[3]: %d\n\r", m_adc_value[0],
m_adc_value[1], m_adc_value[2], m_adc_value[3]);
Serial.printf("c[0]: %d c[1]: %d c[2]: %d c[3]: %d\n\r", m_adc_value_average[0], m_adc_value_average[1],
m_adc_value_average[2], m_adc_value_average[3]);
}
void cWebInterface::UpdateTemp(cDoubleBuffer<uint32_t>& adcBuffer) {
void cWebInterface::UpdateTemp(cDoubleBuffer<uint32_t>& i_tempBuffer) {
}
cWebInterface::~cWebInterface() {
// TODO Auto-generated destructor stub
}
void cWebInterface::OnConfiguration(HttpRequest &request, HttpResponse &response)
{
void cWebInterface::ResetRawValues() {
for (int channel = 0; channel < 4; channel++) {
for (int sample = 0; sample < 1000; sample++) {
m_adc_values_raw[channel][sample] = 0;
}
}
}
void cWebInterface::OnConfiguration(HttpRequest &request, HttpResponse &response) {
if (request.method == HTTP_POST)
{
debugf("Update config");
if (strcmp(request.getRequestMethod().c_str(), RequestMethod::POST) == 0) {
//debugf("Update config");
// Update config
if (request.getBody() == NULL)
{
if (request.getBody() == NULL) {
Serial.println(request.getPostParameter("StaSSID"));
debugf("NULL bodyBuf");
//debugf("NULL bodyBuf");
return;
}
else
{
} else {
StaticJsonBuffer<200> jsonBuffer;
JsonObject& root = jsonBuffer.parseObject(request.getBody());
//root.prettyPrintTo(Serial); //Uncomment it for debuging
/* if (root["StaSSID"].success()) // Settings
{
uint8_t PrevStaEnable = ActiveConfig.StaEnable;
ActiveConfig.StaSSID = String((const char *)root["StaSSID"]);
ActiveConfig.StaPassword = String((const char *)root["StaPassword"]);
ActiveConfig.StaEnable = root["StaEnable"];
if (PrevStaEnable && ActiveConfig.StaEnable)
{
WifiStation.enable(true);
WifiAccessPoint.enable(false);
WifiStation.config(ActiveConfig.StaSSID, ActiveConfig.StaPassword);
}
else if (ActiveConfig.StaEnable)
{
WifiStation.enable(true, true);
WifiAccessPoint.enable(false, true);
WifiStation.config(ActiveConfig.StaSSID, ActiveConfig.StaPassword);
}
else
{
WifiStation.enable(false, true);
WifiAccessPoint.enable(true, true);
WifiAccessPoint.config("TyTherm", "ENTERYOURPASSWD", AUTH_WPA2_PSK);
}
}*/
{
uint8_t PrevStaEnable = ActiveConfig.StaEnable;
ActiveConfig.StaSSID = String((const char *)root["StaSSID"]);
ActiveConfig.StaPassword = String((const char *)root["StaPassword"]);
ActiveConfig.StaEnable = root["StaEnable"];
if (PrevStaEnable && ActiveConfig.StaEnable)
{
WifiStation.enable(true);
WifiAccessPoint.enable(false);
WifiStation.config(ActiveConfig.StaSSID, ActiveConfig.StaPassword);
}
else if (ActiveConfig.StaEnable)
{
WifiStation.enable(true, true);
WifiAccessPoint.enable(false, true);
WifiStation.config(ActiveConfig.StaSSID, ActiveConfig.StaPassword);
}
else
{
WifiStation.enable(false, true);
WifiAccessPoint.enable(true, true);
WifiAccessPoint.config("TyTherm", "ENTERYOURPASSWD", AUTH_WPA2_PSK);
}
}*/
}
//saveConfig(ActiveConfig);
}
else
{
} else {
response.setCache(86400, true); // It's important to use cache for better performance.
response.sendFile("config.html");
}
}
void cWebInterface::OnConfiguration_json(HttpRequest &request, HttpResponse &response)
{
void cWebInterface::OnConfiguration_json(HttpRequest &request, HttpResponse &response) {
JsonObjectStream* stream = new JsonObjectStream();
JsonObject& json = stream->getRoot();
@ -194,9 +207,8 @@ void cWebInterface::OnConfiguration_json(HttpRequest &request, HttpResponse &res
json["StaPassword"] = 23;
json["StaEnable"] = 24;
response.sendDataStream(stream, MIME_JSON);
response.sendDataStream(stream, ContentType::JSON);
}
} /* namespace rijnfel */

111
software/app/web_interface.h

@ -9,44 +9,119 @@
#define APP_WEB_INTERFACE_H_
#include "adc.h"
//TODO remove this
#include "ads101x.h"
#include "dummy_adc.h"
#include "double_buffer.h"
#include <SmingCore/SmingCore.h>
namespace rijnfel {
#define RAW_CHANNEL 1
#define RAW_SAMPLES 1000
class cWebInterface {
public:
static cWebInterface *s_instance;
/**
* Returns the global cWebInterface instance.
* Only one webserver should ever be running
* @return global cWebInterface instance
*/
static cWebInterface *GetInstance() {
if (cWebInterface::s_instance == NULL)
cWebInterface::s_instance = new cWebInterface();
return cWebInterface::s_instance;
}
/// Singleton instance
static cWebInterface *s_instance;
public:
cWebInterface();
cWebInterface(cWebInterface const&) {
m_serverStarted = false;
}
cWebInterface& operator=(cWebInterface const&) {
}
void Start();
void Stop();
void UpdateAdc(cADC<ads::ads_sample_t, int32_t> & adc,
cDoubleBuffer<ads::ads_sample_t> & adcBuffer);
void UpdateTemp(cDoubleBuffer<uint32_t> & adcBuffer);
/**
* Should not be used because it's a singleton
* @param delete
*/
cWebInterface(cWebInterface const&) = delete;
/**
* Should not be used because it's a singleton
* @param delete
* @return delete
*/
cWebInterface& operator=(cWebInterface const&) = delete;
/**
* Registers the paths and starts the server
*/
void StartServer();
/**
* Stops the server
*/
void StopServer();
/**
* Updates the adc on the website. Averages it
* @param i_adc Instance of the adc sensor
* @param i_adcBuffer Buffer containing the raw adc values
*/
void UpdateAdc(cADC<ads::ads_sample_t, int32_t> & i_adc, cDoubleBuffer<ads::ads_sample_t> & i_adcBuffer);
/**
* Updates the temperature on the website
* @param i_tempBuffer buffer containing temperature values
*/
void UpdateTemp(cDoubleBuffer<uint32_t> & i_tempBuffer);
/**
* This is a debug function that prints out the average values
* @todo remove this
*/
void PrintValues();
/**
* Destructor
*/
virtual ~cWebInterface();
public:
void OnIndex(HttpRequest &request, HttpResponse &response);
void OnRefresh(HttpRequest &request, HttpResponse &response);
void OnConfiguration_json(HttpRequest &request, HttpResponse &response);
/**
*
* @param i_request
* @param i_response Response to the client, index.html
*/
void OnIndex(HttpRequest & i_request, HttpResponse & i_response);
/**
* Function gets called from the mobile to refresh the average values
* @param i_request Request from the client
* @param i_response Response to the client, contains JSON with averages
*/
void OnRefresh(HttpRequest & i_request, HttpResponse & i_response);
/**
*
* @param i_request
* @param i_response
*/
void OnRawUpdate(HttpRequest& i_request, HttpResponse& i_response);
void OnConfiguration_json(HttpRequest &request, HttpResponse &response);
void OnConfiguration(HttpRequest &request, HttpResponse &response);
protected:
/**
* Initializes the variables
*/
cWebInterface();
private:
void ResetRawValues();
/// Whether the server has started or not
bool m_serverStarted;
int32_t m_adc_value[4];
HttpServer server;
/// Holds the average for all the channels
int32_t m_adc_value_average[4];
/// Server instance
HttpServer m_server;
char * m_jsonBuffer;
int32_t m_adc_values_raw[4][RAW_SAMPLES];
int m_adc_values_raw_cnt[4];
};
} /* namespace rijnfel */

22
software/files/index.html

@ -28,9 +28,27 @@
</nav>
<h3 class="text-muted">TyTherm</h3>
</div>
<div class="row">
<h2>&nbsp;</h2>
<div class="col-xs-offset-2">
<div class="col-xs-10">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Raw samples</h3>
</div>
<div class="panel-body">
<textarea id="raw_samples" rows="4" cols="50" style="width:100%;">
</textarea>
</div>
</div>
</div>
</div> <!-- /col -->
</div> <!-- /row -->
<div class="row">
<h2>&nbsp;</h2>
<div class="col-xs-offset-2">
<div class="col-xs-10 col-md-5">
<div class="panel panel-default">
@ -82,7 +100,7 @@
</div>
</div> <!-- /col -->
</div> <!-- /row -->
</div> <!-- /container -->
</body>
</html>

5
software/files/index.js

@ -7,7 +7,10 @@ $( document ).ready(function() {
document.getElementById('adc_3').textContent = data.adc_3;
document.getElementById('adc_4').textContent = data.adc_4;
setTimeout(worker, 1000);
//var text = document.getElementById('raw_adc');
//text.value += data.raw_adc;
setTimeout(worker, 500);
});
})();
});

Loading…
Cancel
Save