Prof. J. Walter - Informationstechnik, Mikrocomputertechnik, Digitale Medien Quellcode
Hochschule Karlsruhe Logo Fach: Human Information Technik
Projekt: Kraftmessung 1:4 E-Vertical
Wintersemester 2017/2018
abfu1011
koyo1011

Quellcode

//Library für
//#include "soc/rtc.h" //Verlangsam die ESP Prozesse

//Library für OLED Display
#include <Wire.h> // I2C
#include <Adafruit_GFX.h> // OLED
#include <Adafruit_SSD1306.h> // Graphic
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);

//Library fuer Acces Point ESP32
#include <WiFi.h>
#include <SD.h>
#include "SDCard.h"
#include "FS.h"
#include "SD.h"
#include "SPI.h" // SPI bus

//Library für Wägezellen
#include "cWaage.h"
//****************************************************************************************************************************
typedef struct Timestempel {
int millisec = 0;
int seconds = 0;
int minutes = 0;
int hours = 0;
int gesamt = 0;
} Timestempel;
typedef struct Waagedata {
Timestempel Time;
float kraft1 = 0;
float kraft2 = 0;
float kraft3 = 0;
float kraft4 = 0;
} Waagedata;
typedef struct charWaagedata {
char hours[5];
char minutes[5];
char seconds[5];
char millisec[5];
char kraft1[10];
char kraft2[10];
char kraft3[10];
char kraft4[10];
} charWaagedata;
cWaage Waage1, Waage2, Waage3, Waage4;
Waagedata Daten;
charWaagedata charDaten;
//****************************************************************************************************************************
const char* ssid = "ESP32eVert";
const char* password = "12345678";
IPAddress myIP;
WiFiServer server(80);
WiFiClient client;
// size of buffer used to capture HTTP requests
#define REQ_BUF_SZ 50
char HTTP_req[REQ_BUF_SZ] = {0}; // buffered HTTP request stored as null terminated string
char req_index = 0; // index into HTTP_req buffer
//****************************************************************************************************************************
const char* file = "/index.txt";
#define LOGDATEI "/Log"
//char* dateiName = LOGDATEI "00.csv";
char* dateiName = "/Log00.csv";
File webFile; // the web page file on the SD card
File dataFile;

//****************************************************************************************************************************
void printDeviceInformation() {
Serial.println();
Serial.println("-------------------------------------------------------------------------------------------------" );
Serial.print("Chip ID: ");
Serial.println(ESP.getChipRevision());
Serial.print("Free Heap Size: ");
Serial.println(ESP.getFreeHeap());
Serial.print("Chip Size: ");
Serial.println(ESP.getFlashChipSize());
Serial.print("Chip Speed: ");
Serial.print((float)ESP.getFlashChipSpeed() / 1000000);
Serial.println("Mhz");
Serial.print("Chip Mode: ");
Serial.println(ESP.getFlashChipMode());
Serial.println("-------------------------------------------------------------------------------------------------" );
Serial.println();
}
void I2CDisplayEinstellung() {
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);// mit I2C-Adresse 0x3c initialisieren
display.display(); // Zeigt Adafruit Initialisation Symbol
delay(2000); // 2000ms = 2s
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(INVERSE);
}
void AccesPointEinstellung(const char* _ssid, const char* _password) {
Serial.begin(115200);
// Connect to WiFi network
Serial.println();
Serial.print(F("Connecting to "));
Serial.println(ssid);

WiFi.mode(WIFI_AP);

WiFi.softAP(ssid, password);

delay(1000);

myIP = WiFi.softAPIP();
// Start the server
server.begin();
Serial.println(F("Server started"));
}
void printWifiInfo() {
byte mac[6];
Serial.println();
Serial.println("-------------------------------------------------------------------------------------------------" );
Serial.print("SSID: ");
Serial.println(ssid);
Serial.print("IP Address: ");
Serial.println(myIP);
WiFi.macAddress(mac);
Serial.print("Device MAC Address: ");
for (int i = 5; i >= 1; i--) {
Serial.print(mac[i], HEX);
Serial.print(":");
}
Serial.println(mac[0]);
Serial.print("Signal strength (RSSI): ");
Serial.print(WiFi.RSSI());
Serial.println(" dBm");
Serial.println("-------------------------------------------------------------------------------------------------" );
Serial.println();
}
void SDKarteEinstellung() {
// SD Karte Adapter Einstellungen
Serial.println("Initializing SD card...");
if (!SD.begin()) {
Serial.println("ERROR - SD card initialization failed!");
return;
}
uint8_t cardType = SD.cardType();

if (cardType == CARD_NONE) {
Serial.println("No SD card attached");
return;
}

Serial.print("SD Card Type: ");
if (cardType == CARD_MMC) {
Serial.println("MMC");
} else if (cardType == CARD_SD) {
Serial.println("SDSC");
} else if (cardType == CARD_SDHC) {
Serial.println("SDHC");
} else {
Serial.println("UNKNOWN");
}

uint64_t cardSize = SD.cardSize() / (1024 * 1024);
Serial.printf("SD Card Size: %lluMB\n", cardSize);
Serial.println("SUCCESS - SD card initialized.");



Serial.println("-------------------------------------------------------------------------------------------------" );
Serial.println();
}
void IndexFilefinden() {
// check for index.htm file
if (!SD.exists(file)) {
Serial.println("ERROR - Can't find index.txt file!");
return; // can't find index file
}
Serial.println("SUCCESS - Found index.txt file.");

/*
const uint8_t NAMENSLAENGE = sizeof(LOGDATEI) - 1;

while (SD.exists(dateiName))
{
if (dateiName[NAMENSLAENGE + 1] != '9') {
dateiName[NAMENSLAENGE + 1]++;
}
else if (dateiName[NAMENSLAENGE] != '9') {
dateiName[NAMENSLAENGE + 1] = '0';
dateiName[NAMENSLAENGE]++;
}
else {
Serial.println("Kann Datei nicht erzeugen");
}
}
*/
}
void HeaderErstellen() {
dataFile = SD.open(dateiName, FILE_WRITE);
Serial.print("SUCCESS - create "); Serial.println(dateiName);
if (!dataFile) {
Serial.println("Failed to open file for appending");
return;
}
else
{
dataFile.println(F("Messungen von 1:4 Multikopter"));
dataFile.print(F("Zeit"));
dataFile.print(',');
dataFile.print(F("Kraft1"));
dataFile.print(',');
dataFile.print(F("Kraft2"));
dataFile.print(',');
dataFile.print(F("Kraft3"));
dataFile.print(',');
dataFile.print(F("Kraft4"));
dataFile.print(',');
dataFile.println();
Serial.println("Set-up header");
dataFile.close();
}
}


void WaagezelleEinstellung() {
//Waage_name.initialisierung(int DAT, float cal_factor, float steigung, float x1, float y1);
//steigung*(scale.get_units()-x1)+y1;
Waage1.initialisierung(26, -21114.3, 0.97, 0, 0);
Waage2.initialisierung(25, -29094.9, 1.289, -1.02, -1.32);
Waage3.initialisierung(33, -22538.8, 1.04, 0, 0);
Waage4.initialisierung(32, -22133.7, 1, 0, 0);
}
void Waagekalibrrierungsfunktion() {
//Beim Kalibrierung muss erst die WaageEinstellungen so sein
//Waage1.initialisierung(DAT PIN, 1, 0, 0, 0);
Serial.println("Waage 1 kalibrierung-------------------------------------------------------------------------------------------------" );
Waage1.kalibrieren();
Serial.println("Waage 2 kalibrierung-------------------------------------------------------------------------------------------------" );
Waage2.kalibrieren();
Serial.println("Waage 3 kalibrierung-------------------------------------------------------------------------------------------------" );
Waage3.kalibrieren();
Serial.println("Waage 4 kalibrierung-------------------------------------------------------------------------------------------------" );
Waage4.kalibrieren();

}
void setup() {
//rtc_clk_cpu_freq_set(RTC_CPU_FREQ_80M);
printDeviceInformation();
AccesPointEinstellung(ssid, password);
I2CDisplayEinstellung();
printWifiInfo();
SDKarteEinstellung();
IndexFilefinden();
WaagezelleEinstellung();
HeaderErstellen();
//Waagekalibrrierungsfunktion(); // uncommentieren wenn kalibrieren wollen.
}
void loop() {
client = server.available();
Daten.Time = MilliInSecondandMinutes(millis());
Daten.kraft1 = Waage1.getGewicht();
Daten.kraft2 = Waage2.getGewicht();
Daten.kraft3 = Waage3.getGewicht();
Daten.kraft4 = Waage4.getGewicht();
ADCinSleepMode();
if (client) { // got client?
boolean currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) { // client data available to read
char c = client.read(); // read 1 byte (character) from client
// buffer first part of HTTP request in HTTP_req array (string)
// leave last element in array as 0 to null terminate string (REQ_BUF_SZ - 1)
if (req_index < (REQ_BUF_SZ - 1)) {
HTTP_req[req_index] = c; // save HTTP request character
req_index++;
}
// last line of client request is blank and ends with \n
// respond to client only after last line received
if (c == '\n' && currentLineIsBlank) {
// send a standard http response header
client.println("HTTP/1.1 200 OK");
// remainder of header follows below, depending on if
// web page or XML page is requested
// Ajax request - send XML file
if (StrContains(HTTP_req, "ajax_inputs")) {
// send rest of HTTP header


client.println("Content-Type: text/xml");
client.println("Connection: keep-alive");
client.println();
client.print("<?xml version = \"1.0\" ?>");
client.print("<inputs>");
client.print("<kraft>"); client.print(Daten.kraft1); client.print("</kraft>");
client.print("<kraft>"); client.print(Daten.kraft2); client.print("</kraft>");
client.print("<kraft>"); client.print(Daten.kraft3); client.print("</kraft>");
client.print("<kraft>"); client.print(Daten.kraft4); client.print("</kraft>");
client.print("<time>"); client.print(Daten.Time.hours); client.print("</time>");
client.print("<time>"); client.print(Daten.Time.minutes); client.print("</time>");
client.print("<time>"); client.print(Daten.Time.seconds); client.print("</time>");
client.print("<time>"); client.print(Daten.Time.millisec); client.print("</time>");
client.print("<time>"); client.print(Daten.Time.gesamt); client.print("</time>");
client.print("</inputs>");
AnzeigewithSerial(WaagedataincharConverter(Daten));
AnzeigeinSDKartespeichern(WaagedataincharConverter(Daten));
}
else { // web page request
// send rest of HTTP header
client.println("Content-Type: text/html");
client.println("Connection: keep-alive");
client.println();
// send web page
webFile = SD.open(file); // open web page file
if (webFile) {
while (webFile.available()) {
client.write(webFile.read()); // send web page to client
}
webFile.close();
}
}
// display received HTTP request on serial port
//Serial.println(HTTP_req);
// reset buffer index and all buffer elements to 0
req_index = 0;
StrClear(HTTP_req, REQ_BUF_SZ);
break;
}
// every line of text received from the client ends with \r\n
if (c == '\n') {
// last character on line of received text
// starting new line with next character read
currentLineIsBlank = true;
}
else if (c != '\r') {
// a text character was received from client
currentLineIsBlank = false;
}
} // end if (client.available())
} // end while (client.connected())
delay(1); // give the web browser time to receive the data
client.stop(); // close the connection
} // end if (client)

AnzeigewithDisplayLCD(Daten);

}
void AnzeigewithDisplayLCD(Waagedata mDaten) {
display.clearDisplay();
display.setCursor(18, 0);
display.print("--:e-Vertical:--");
display.setCursor(0, 12);
display.print("1. Waage:\t"); display.print(mDaten.kraft1);
display.setCursor(0, 24);
display.print("2. Waage:\t"); display.print(mDaten.kraft2);
display.setCursor(0, 37);
display.print("3. Waage:\t"); display.print(mDaten.kraft3);
display.setCursor(0, 50);
display.print("4. Waage:\t"); display.print(mDaten.kraft4);
display.display();
}
void AnzeigewithSerial(charWaagedata mDaten) {

Serial.print(mDaten.hours);
Serial.print(":"); Serial.print(mDaten.minutes);
Serial.print(":"); Serial.print(mDaten.seconds);
Serial.print(":"); Serial.print(mDaten.millisec);
Serial.print(","); Serial.print(mDaten.kraft1);
Serial.print(","); Serial.print(mDaten.kraft2);
Serial.print(","); Serial.print(mDaten.kraft3);
Serial.print(","); Serial.println(mDaten.kraft4);
}
void AnzeigeinSDKartespeichern(charWaagedata mDaten) {
File file = SD.open(dateiName, FILE_APPEND);
if (!file) {
Serial.println("Failed to open file for appending");
return;
}
file.print(mDaten.hours); file.print(":");
file.print(mDaten.minutes); file.print(":");
file.print(mDaten.seconds); file.print(":");
file.print(mDaten.millisec);
file.print(","); file.print(mDaten.kraft1);
file.print(","); file.print(mDaten.kraft2);
file.print(","); file.print(mDaten.kraft3);
file.print(","); file.print(mDaten.kraft4); file.print("\n");
file.close();

}
Timestempel MilliInSecondandMinutes(int m_millis) {
Timestempel Ruckgabe;
Ruckgabe.gesamt = m_millis;
Ruckgabe.millisec = m_millis % 1000;
Ruckgabe.seconds = (m_millis / 1000) % 60;
Ruckgabe.minutes = ((m_millis / (1000 * 60)) % 60);
Ruckgabe.hours = ((m_millis / (1000 * 60 * 60)) % 24);
return Ruckgabe;
}
char * floatToChar(char * outstr, float value, int places, int minwidth = 0, bool rightjustify = false) {
int digit;
float tens = 0.1;
int tenscount = 0;
int i;
float tempfloat = value;
int c = 0;
int charcount = 1;
int extra = 0;
// make sure we round properly. this could use pow from <math.h>, but doesn't seem worth the import
// if this rounding step isn't here, the value 54.321 prints as 54.3209

// calculate rounding term d: 0.5/pow(10,places)
float d = 0.5;
if (value < 0)
d *= -1.0;
// divide by ten for each decimal place
for (i = 0; i < places; i++)
d /= 10.0;
// this small addition, combined with truncation will round our values properly
tempfloat += d;

// first get value tens to be the large power of ten less than value
if (value < 0)
tempfloat *= -1.0;
while ((tens * 10.0) <= tempfloat) {
tens *= 10.0;
tenscount += 1;
}

if (tenscount > 0)
charcount += tenscount;
else
charcount += 1;

if (value < 0)
charcount += 1;
charcount += 1 + places;

minwidth += 1; // both count the null final character
if (minwidth > charcount) {
extra = minwidth - charcount;
charcount = minwidth;
}

if (extra > 0 and rightjustify) {
for (int i = 0; i < extra; i++) {
outstr[c++] = ' ';
}
}

// write out the negative if needed
if (value < 0)
outstr[c++] = '-';

if (tenscount == 0)
outstr[c++] = '0';

for (i = 0; i < tenscount; i++) {
digit = (int) (tempfloat / tens);
itoa(digit, &outstr[c++], 10);
tempfloat = tempfloat - ((float)digit * tens);
tens /= 10.0;
}

// if no places after decimal, stop now and return

// otherwise, write the point and continue on
if (places > 0)
outstr[c++] = '.';


// now write out each decimal place by shifting digits one by one into the ones place and writing the truncated value
for (i = 0; i < places; i++) {
tempfloat *= 10.0;
digit = (int) tempfloat;
itoa(digit, &outstr[c++], 10);
// once written, subtract off that digit
tempfloat = tempfloat - (float) digit;
}
if (extra > 0 and not rightjustify) {
for (int i = 0; i < extra; i++) {
outstr[c++] = ' ';
}
}


outstr[c++] = '\0';
return outstr;
}
charWaagedata WaagedataincharConverter(Waagedata mData) {
charWaagedata lokalcharData;
/*String sgesamt = String(mData.Time.gesamt);
sgesamt.toCharArray(lokalcharData.gesamt,2);*/
itoa(mData.Time.hours, lokalcharData.hours, 10);
itoa(mData.Time.minutes, lokalcharData.minutes, 10);
itoa(mData.Time.seconds, lokalcharData.seconds, 10);
itoa(mData.Time.millisec, lokalcharData.millisec, 10);
//lokalcharData.gesamt= (char)mData.Time.gesamt;
floatToChar(lokalcharData.kraft1, mData.kraft1, 3);
floatToChar(lokalcharData.kraft2, mData.kraft2, 3);
floatToChar(lokalcharData.kraft3, mData.kraft3, 3);
floatToChar(lokalcharData.kraft4, mData.kraft4, 3);

return lokalcharData;
}
void StrClear(char *str, char length) { // sets every element of str to 0 (clears array)
for (int i = 0; i < length; i++) {
str[i] = 0;
}
}
char StrContains(char *str, char *sfind) { // searches for the string sfind in the string str
// returns 1 if string found
// returns 0 if string not found
char found = 0;
char index = 0;
char len;

len = strlen(str);

if (strlen(sfind) > len) {
return 0;
}
while (index < len) {
if (str[index] == sfind[found]) {
found++;
if (strlen(sfind) == found) {
return 1;
}
}
else {
found = 0;
}
index++;
}
return 0;
}
void ADCinSleepMode() {
Waage1.power_down();
Waage2.power_down();
Waage3.power_down();
Waage4.power_down();
delay(100);
Waage1.power_up();
Waage2.power_up();
Waage3.power_up();
Waage4.power_up();
}


  Mit Unterstützung von Prof. J. Walter Wintersemester 2017/18