Skip to content

Commit

Permalink
Add files via upload
Browse files Browse the repository at this point in the history
  • Loading branch information
newbee90 authored Apr 6, 2018
1 parent 1cf54a3 commit ea1dcae
Show file tree
Hide file tree
Showing 9 changed files with 17,760 additions and 0 deletions.
Binary file added IMG_0849.JPG
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added MCP3304.zip
Binary file not shown.
105 changes: 105 additions & 0 deletions Streaming.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/*
Streaming.h - Arduino library for supporting the << streaming operator
Copyright (c) 2010-2012 Mikal Hart. All rights reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/

#ifndef ARDUINO_STREAMING
#define ARDUINO_STREAMING

#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif

#define STREAMING_LIBRARY_VERSION 5

// Generic template
template<class T>
inline Print &operator <<(Print &stream, T arg)
{ stream.print(arg); return stream; }

struct _BASED
{
long val;
int base;
_BASED(long v, int b): val(v), base(b)
{}
};

#if ARDUINO >= 100

struct _BYTE_CODE
{
byte val;
_BYTE_CODE(byte v) : val(v)
{}
};
#define _BYTE(a) _BYTE_CODE(a)

inline Print &operator <<(Print &obj, const _BYTE_CODE &arg)
{ obj.write(arg.val); return obj; }

#else

#define _BYTE(a) _BASED(a, BYTE)

#endif

#define _HEX(a) _BASED(a, HEX)
#define _DEC(a) _BASED(a, DEC)
#define _OCT(a) _BASED(a, OCT)
#define _BIN(a) _BASED(a, BIN)

// Specialization for class _BASED
// Thanks to Arduino forum user Ben Combee who suggested this
// clever technique to allow for expressions like
// Serial << _HEX(a);

inline Print &operator <<(Print &obj, const _BASED &arg)
{ obj.print(arg.val, arg.base); return obj; }

#if ARDUINO >= 18
// Specialization for class _FLOAT
// Thanks to Michael Margolis for suggesting a way
// to accommodate Arduino 0018's floating point precision
// feature like this:
// Serial << _FLOAT(gps_latitude, 6); // 6 digits of precision

struct _FLOAT
{
float val;
int digits;
_FLOAT(double v, int d): val(v), digits(d)
{}
};

inline Print &operator <<(Print &obj, const _FLOAT &arg)
{ obj.print(arg.val, arg.digits); return obj; }
#endif

// Specialization for enum _EndLineCode
// Thanks to Arduino forum user Paul V. who suggested this
// clever technique to allow for expressions like
// Serial << "Hello!" << endl;

enum _EndLineCode { endl };

inline Print &operator <<(Print &obj, _EndLineCode arg)
{ obj.println(); return obj; }

#endif
Binary file added Streaming5.zip
Binary file not shown.
223 changes: 223 additions & 0 deletions StromMess_4fach.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,223 @@
// ProgrammName: StromMess
// Kurzbeschreibung: Strommessung, Effektivwertbildung, Datenaufbereitung und Übertragung
// Version: 1.0
// Datum: 04.03.2017
// Autor: Jürgen Stähr

//Fragen:
//Baudrate 115000 oder 115200?
//Werte ohne angeschlossenen Slave?
//Sensor ohne Strom -> zeigt 32mA an

// Konfiguration
//******* ACHTUNG ********** Hier an die vorhandene Hardware anpassen ******** ACHTUNG ***************
const int ADCAnz = 4; // Anzahl der angeschlossenen ADC
const int CRundAnz = 4; // Anzahl der Messungen je Sekunde
const int Korr = -7; // 0 Abgleich
// Pin Nummern der cs Eingänge der ADC. Erlaubt sind 2 - 10 (digital Pins)
// 14 - 17 (analogPins A0 - A3)
//const int cs[] = {10, 10,10,10,10,10,10,10,10,10}; // das geht auch, macht aber keinen Sinn
const int cs[] = {0, 2, 4, 6}; // Muss mit ADCAnz übereinstimmen oder größer sein
const int Shunt[] = {33, 33, 33, 33}; // Entsprechend dem cs[] Array die Widerstände eintragen
const unsigned long BaudRate = 115200; // hier die Baudrate des seriellen Interfaces einstellen
//********************************************************************
// Beschreibung
/*--------------------------------------------------------------------------
* Das Programm läuft auf einem Arduiono (Nano, Mini,...) und soll den Wechselstrom von mehreren Installationsleitungen messen.
*
* Max. können 10 Wandler angeschlossen werden. Bei jedem Wandler wird 4 mal pro Sekunde je eine Periode gemessen und aus den
* Messergebnissen der RMS gebildet. Der Arduino schafft 586 Messungen in 20 ms bei Verwendung von unsigned long zum Speichern
* der Messergebnisse. Bei Verwendung von float können nur 380 - 400 Messungen durchgeführt werden.
* Die Integer Berechnung begrenzt den max. gemessenen Strom auf 2707 Wandlerzählern, entspricht bei 50 Ohm 33A.
*
* Die Zusammengefassten Ergebnisse werden einmal pro Sekunde über die serielle Schnittstelle übertragen.
*
* Die Messwandler liefern 1mA pro 1A Messstrom, max. jedoch 2,5V. ( wenn das der Effektivwert ist, liegt der Spitzenwert schon zu hoch für den ADC!!!!)
* Ein 13 Bit ADC MCP 3301 digitalisiert die über einen Messshunt abfallende Spannung.
* Die Größe des Mess-Shunt ist je ADC wählbar und muss im Array Shunt[] eingetragen werden.
* Der ADC erhält eine Referenzspannung von 2,5V. Diese geteilt durch die halbe Auflösung=4096 ergibt den
* Spannungswert eines ADC-Zählers= 0,61035 mV. Die Referenzspannungsquelle muss damit hinreichend genau sein.
*
* Der ADC wird über SPI angesprochen. Er kann mit max 1,7 MHz getaktet werden. Der AVR läuft mit 16 MHz und kann den SPI Takt
* nur durch 2,4,8,16,.. teilen, so dass der ADC mit 1 MHz getaktet wird. Damit dauert die Übertragung eines
* Messwertes 16 uS. Weiter 18 uS werden für die Verarbeitung benötigt
*/

//#define debug

const unsigned long CPeriode = 20000; // Microsekunden einer Halbwelle
const unsigned long CRunde = 1000 / CRundAnz; // ms einer Messrunde über alle ADC
// Array zur Aufnanme der aller Messergebnisse einer Sekunde
int Erg[ADCAnz * CRundAnz];
const int Nr;

#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3f, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Set the LCD I2C address
#include <SPI.h> // SPI Bibliothek
#include <Streaming.h> // Bibliothek zur besseren Ausgabeformatierung ==> Streaming.h ins Arduino Bibliotheksverzeichni kopieren
#include <MCP3304.h>
MCP3304 adc1(10);

// Funktionsprototypen
int MessPeriode(int csADC);
void Ausgabe();
// Vorbereitung
void setup() {
Serial.begin(BaudRate); // Serielle Schnittstelle mit 115000 Baud starten
lcd.begin(20,4);
lcd.clear();
lcd.setCursor(0,0); //Start at character 2 on line 1
lcd.print("Strom L1: ");
lcd.setCursor(0,1); //Start at character 1 on line 2
lcd.print("Strom L2: ");
lcd.setCursor(0,2); //Start at character 1 on line 3
lcd.print("Strom L3: ");
lcd.setCursor(0,3); //Start at character 1 on line 4
lcd.print("Strom N: ");
SPI.begin(); // SPI Interface starten
for (int i = 0; i < ADCAnz; i++) { // cs Pins initialisieren
pinMode(cs[i], OUTPUT);
digitalWrite(cs[i], HIGH);
}
SPI.beginTransaction(SPISettings(1700000, MSBFIRST, SPI_MODE0)); // SPI Parameter
}



// Endlosschleife
void loop() {
// Diese Schleife wird jede Sek. einmal durchlaufen
for (int i = 0; i < ADCAnz * CRundAnz; i++) Erg[i] = 0; // Ergebniise des vorherigen Laufes löschen
// Schleife je Runde. In jeder Runde werden alle ADC für je 20ms abgefragt
for (int runde = 0; runde < CRundAnz; runde++) {
unsigned long ZeitRunde = millis(); // Startwert in ms für eine Messrunde nehmen
for (int ADCNr = 0; ADCNr < ADCAnz; ADCNr++) {
int Index = runde * ADCAnz + ADCNr; // Zeigt auf das Ergebnisarray, Reihenfolge: Ergs der ersten Runde, Ergs der 2. Runde, usw.
Erg[Index] = MessPeriode(cs[ADCNr]); // Messung für einen ADC durchführen und speichern
} // Ende, alle ADC einmal durchmessen
if (runde == CRundAnz - 1) Ausgabe(); // wenn es die letzte Runde war ==> Daten ausgeben
#ifdef debug
//Serial << "Wartezeit: " << (CRunde - (millis() - ZeitRunde)) << "ms; ";
#endif
while (millis() - ZeitRunde < CRunde); // warten, bis Rundenzeit abgelaufen
} // Ende Schleife über alle Mess-Runden

} //Ende loop
/* Function MessPeriode
Führt mit einem ADC die Messungen über eine Periode durch.
Der cs-PIN des ADC wird übergeben
summiert die quadrierten Werte auf
nach Ablauf wird durch die Anzahl der Messungen geteilt und die Wurzel gezogen ==> Rückgabewert*/
int MessPeriode(int csADC) {
unsigned long ZeitPeriode = micros();
int MessAnz = 0; // Anzahl der Messungen
int ADCdata; // nimmt den Messwert vom ADC auf
unsigned long Erg = 0; // nimmt die quadrierten Summen einer Periode auf

Serial.print("Korr: ");
Serial.println(adc1.readAdc(csADC,0));

do {
ADCdata=adc1.readAdc(csADC,0)- Korr;



Erg += (unsigned long)ADCdata * (unsigned long)ADCdata; // Quadrieren
MessAnz++; // Anzahl der Messungen erhöhen
} while (micros() - ZeitPeriode < CPeriode); // Ende MessSchleife über eine Periode
Erg /= MessAnz; // Das Ergebnis aller Messungen durch die Anzahl teilen (quadratischer Mittelwert)
#ifdef debug
Serial << "Anz:" << MessAnz;
Serial << "M:" << ADCdata << " E:" << (int(sqrt(Erg))) << "; ";
#endif
return int(sqrt(Erg)); // Rückgabe ist die Wurzel aus dem Mittelwert der Quadrate
}
/* Function Ausgabe
gibt jede Sekunde die Messergebnisse über die Serielle Schnittstelle aus
*/
const unsigned long Uadc = 610350; // Wert eines Zählers
unsigned long IuA; // Strom je Zähler eines ADC
void Ausgabe() {
unsigned long SekWert; // nimmt die Ergebnisse einer Runde eines ADC auf
// for (int ADCNr = 0; ADCNr < ADCAnz; ADCNr++) { // Schleife über alle ADC

SekWert = 0;
for (int Runde = 0; Runde < CRundAnz; Runde++) { // Schleife über alle Runden je ADC
SekWert += Erg[Runde * ADCAnz + 0]; // Messergebnisse eines ADC aufaddieren
} // Ende Schleife über Rnden eines ADC
SekWert /= CRundAnz; // Mittelwert bilden
IuA=Uadc/Shunt[1]; // Strom je Zähler in uA berechnen
SekWert *= IuA; // mit Strom-Zählerwert multiplizieren z.B. für 50 Ohm(12207 uA)
SekWert /= 1000; // auf mA runter rechnen
// Ausgeben



char buffer[7];
lcd.setCursor(10,0); //Start at character 1 on line 3

sprintf(buffer,"%4imA ",SekWert);
lcd.print (buffer);

Serial.print("3 ");
Serial.println(buffer);

SekWert = 0;
for (int Runde = 0; Runde < CRundAnz; Runde++) { // Schleife über alle Runden je ADC
SekWert += Erg[Runde * ADCAnz + 1]; // Messergebnisse eines ADC aufaddieren
} // Ende Schleife über Rnden eines ADC
SekWert /= CRundAnz; // Mittelwert bilden
IuA=Uadc/Shunt[0]; // Strom je Zähler in uA berechnen
SekWert *= IuA; // mit Strom-Zählerwert multiplizieren z.B. für 50 Ohm(12207 uA)
SekWert /= 1000; // auf mA runter rechnen
// Ausgeben


lcd.setCursor(10,1); //Start at character 1 on line 2

sprintf(buffer,"%4imA ",SekWert);
lcd.print (buffer);

Serial.print("2 ");
Serial.println(buffer);

SekWert = 0;
for (int Runde = 0; Runde < CRundAnz; Runde++) { // Schleife über alle Runden je ADC
SekWert += Erg[Runde * ADCAnz + 2]; // Messergebnisse eines ADC aufaddieren
} // Ende Schleife über Rnden eines ADC
SekWert /= CRundAnz; // Mittelwert bilden
IuA=Uadc/Shunt[1]; // Strom je Zähler in uA berechnen
SekWert *= IuA; // mit Strom-Zählerwert multiplizieren z.B. für 50 Ohm(12207 uA)
SekWert /= 1000; // auf mA runter rechnen
// Ausgeben

lcd.setCursor(10,2); //Start at character 1 on line 3

sprintf(buffer,"%4imA ",SekWert);
lcd.print (buffer);

Serial.print("1 ");
Serial.println(buffer);

SekWert = 0;
for (int Runde = 0; Runde < CRundAnz; Runde++) { // Schleife über alle Runden je ADC
SekWert += Erg[Runde * ADCAnz + 3]; // Messergebnisse eines ADC aufaddieren
} // Ende Schleife über Rnden eines ADC
SekWert /= CRundAnz; // Mittelwert bilden
IuA=Uadc/Shunt[2]; // Strom je Zähler in uA berechnen
SekWert *= IuA; // mit Strom-Zählerwert multiplizieren z.B. für 50 Ohm(12207 uA)
SekWert /= 1000; // auf mA runter rechnen
// Ausgeben

lcd.setCursor(10,3); //Start at character 1 on line 4

sprintf(buffer,"%4imA ",SekWert);
lcd.print (buffer);

Serial.print("0 ");
Serial.println(buffer);

// } // Ende Schleife über alle ADC

} // Ende Function Ausgabe

Binary file added StromMess_Disp.zip
Binary file not shown.
Binary file added StromMess_MCP3304.zip
Binary file not shown.
Loading

0 comments on commit ea1dcae

Please sign in to comment.