Skip to content

Commit f44097f

Browse files
committed
Initial commit
0 parents  commit f44097f

File tree

5 files changed

+1306
-0
lines changed

5 files changed

+1306
-0
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Arduino based electric energy meter with ethernet and xPL

S0Impulse.h

+283
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,283 @@
1+
#include <Arduino.h>
2+
3+
// #include <EEPROM.h>
4+
5+
#include <avr/eeprom.h>
6+
7+
#define S0_ADDR(A) ((EEPROM_S0_OFFSET) + ((id) * (EEPROM_S0_SIZE)) + (A))
8+
9+
/*
10+
EEPROM
11+
12+
Size Name
13+
14+
2 Use DHCP
15+
4 IP
16+
4 Netmask
17+
4 Broadcast Address
18+
19+
20+
16 S0 name
21+
2 Impulses per kWh
22+
2 Active
23+
2 Delta before send base
24+
2 Delta before send factor
25+
2 Recurring sending interval base
26+
2 Recurring sending interval factor
27+
2
28+
2
29+
30+
*/
31+
32+
#define EEPROM_S0_OFFSET 32
33+
#define EEPROM_S0_SIZE 32
34+
35+
#define EEPROM_S0_FLAGS 0 // Bitvalues see below
36+
#define EEPROM_S0_CNT_PER_KWH 2
37+
#define EEPROM_S0_DELTA_BASE 4
38+
#define EEPROM_S0_DELTA_FACTOR 6
39+
#define EEPROM_S0_TIME_BASE 8
40+
#define EEPROM_S0_TIME_FACTOR 10
41+
#define EEPROM_S0_1 12
42+
#define EEPROM_S0_2 14
43+
#define EEPROM_S0_NAME 16
44+
#define EEPROM_S0_NAME_LENGTH 15
45+
46+
#define EEPROM_S0_FLAG_ACTIVE 0
47+
#define EEPROM_S0_FLAG_UPDATE_VALUE_DELTA 1
48+
#define EEPROM_S0_FLAG_UPDATE_TIME_DELTA 2
49+
#define EEPROM_S0_FLAG_SEND_DELTA 3
50+
51+
// To use the library, define a class that subclasses CallBackInterface.
52+
// And also, include a method (C++ talk for "subroutine") called "cbmethod()" in the class.
53+
// Use this class as a template to create your own; it's not hard. You don't
54+
// even have to understand what you're doing at first.
55+
// How do you subclass? Like this:
56+
class S0Impulse : public CallBackInterface
57+
{
58+
public:
59+
uint16_t countHigh;
60+
uint16_t countLow;
61+
uint16_t countLowPerHigh;
62+
uint32_t count;
63+
64+
uint16_t deltaBase;
65+
uint16_t deltaFactor;
66+
uint32_t delta;
67+
uint32_t reqNextUpdate;
68+
69+
uint16_t timeBase;
70+
uint16_t timeFactor;
71+
uint32_t updateInterval;
72+
73+
uint8_t pin;
74+
uint8_t id;
75+
uint8_t flags;
76+
uint8_t isActive;
77+
uint8_t reqDeltaUpdate;
78+
uint8_t reqTimeUpdate;
79+
uint8_t * requestUpdatePtr;
80+
81+
S0Impulse(void)
82+
{
83+
};
84+
85+
#if 0
86+
S0Impulse(uint8_t _pin, uint16_t _countLowPerHigh):
87+
pin(_pin),
88+
countLowPerHigh(_countLowPerHigh)
89+
{
90+
init();
91+
};
92+
#endif
93+
94+
S0Impulse(uint8_t _pin, uint8_t _id):
95+
pin(_pin),
96+
id(_id)
97+
{
98+
initFromEEPROM();
99+
};
100+
101+
S0Impulse(uint8_t _pin, uint16_t _countLowPerHigh, uint8_t _id):
102+
pin(_pin),
103+
countLowPerHigh(_countLowPerHigh),
104+
id(_id)
105+
{
106+
init();
107+
};
108+
109+
// this gets called on a pin change event on pin "pin"
110+
// Increment low count. on overflow increment high count and reset low count.
111+
void cbmethod()
112+
{
113+
countLow ++;
114+
115+
if (countLow >= countLowPerHigh)
116+
{
117+
countHigh ++;
118+
countLow = 0;
119+
}
120+
};
121+
122+
uint16_t getCountLow()
123+
{
124+
return countLow;
125+
}
126+
127+
uint16_t getCountHigh()
128+
{
129+
return countHigh;
130+
}
131+
132+
uint16_t getCountLowPerHigh()
133+
{
134+
return countLowPerHigh;
135+
}
136+
137+
uint16_t setCountLowPerHigh(uint16_t _countLowPerHigh)
138+
{
139+
eeprom_write_word((uint16_t *)S0_ADDR(EEPROM_S0_CNT_PER_KWH), _countLowPerHigh);
140+
141+
return countLowPerHigh = _countLowPerHigh;
142+
}
143+
144+
float getCount()
145+
{
146+
// Disable interrupts - Prevent updates during calculations leading to loosing ticks
147+
// Disable interrupts as short as possible
148+
noInterrupts();
149+
// Make local copies of counters to work with
150+
uint16_t _high = countHigh;
151+
uint16_t _low = countLow;
152+
// Resume interrupts again
153+
interrupts();
154+
155+
float f = (float) _high + (float) _low / (float) countLowPerHigh;
156+
return f;
157+
}
158+
159+
float getCountClear()
160+
{
161+
// Disable interrupts - Prevent updates during calculations leading to loosing ticks
162+
// Disable interrupts as short as possible
163+
noInterrupts();
164+
// Make local copies of counters to work with
165+
uint16_t _high = countHigh;
166+
uint16_t _low = countLow;
167+
// Clear counters
168+
countLow = countHigh = 0;
169+
// Resume interrupts again
170+
interrupts();
171+
172+
float f = (float) _high + (float) _low / (float) countLowPerHigh;
173+
return f;
174+
}
175+
176+
uint8_t getPin()
177+
{
178+
return pin;
179+
}
180+
181+
uint8_t getID()
182+
{
183+
return id;
184+
}
185+
186+
uint8_t setID(uint8_t _id)
187+
{
188+
return id = _id;
189+
}
190+
191+
uint8_t getIsActive ()
192+
{
193+
return isActive;
194+
}
195+
196+
uint8_t setActive()
197+
{
198+
if (isActive)
199+
return isActive;
200+
201+
isActive = 1;
202+
flags |= (1 << EEPROM_S0_FLAG_ACTIVE);
203+
eeprom_write_word((uint16_t *)S0_ADDR(EEPROM_S0_FLAGS), flags);
204+
return isActive;
205+
}
206+
207+
uint8_t setInactive()
208+
{
209+
if (! isActive)
210+
return isActive;
211+
212+
isActive = 0;
213+
flags &= ~(1 << EEPROM_S0_FLAG_ACTIVE);
214+
eeprom_write_word((uint16_t *)S0_ADDR(EEPROM_S0_FLAGS), flags);
215+
return isActive;
216+
}
217+
218+
void reset()
219+
{
220+
countLow = countHigh = 0;
221+
}
222+
223+
void setName(const char * _cp)
224+
{
225+
uint8_t nameLength = strlen(_cp);
226+
if (nameLength > EEPROM_S0_NAME_LENGTH)
227+
nameLength = EEPROM_S0_NAME_LENGTH;
228+
229+
eeprom_write_block(_cp, (void *)S0_ADDR(EEPROM_S0_NAME), nameLength);
230+
eeprom_write_byte((uint8_t *)S0_ADDR(EEPROM_S0_NAME + nameLength), 0);
231+
232+
return;
233+
}
234+
235+
236+
private:
237+
void init ()
238+
{
239+
pinMode(pin, INPUT);
240+
digitalWrite(pin, HIGH);
241+
PCintPort::attachInterrupt(pin, this, FALLING);
242+
countLow = countHigh = 0;
243+
isActive = 0;
244+
}
245+
246+
void initFromEEPROM()
247+
{
248+
pinMode(pin, INPUT);
249+
digitalWrite(pin, HIGH);
250+
PCintPort::attachInterrupt(pin, this, FALLING);
251+
countLow = countHigh = 0;
252+
253+
// Flags
254+
flags = eeprom_read_byte((uint8_t *)S0_ADDR(EEPROM_S0_FLAGS));
255+
isActive = flags & (1 << EEPROM_S0_FLAG_ACTIVE);
256+
reqDeltaUpdate = flags & (1 << EEPROM_S0_FLAG_UPDATE_VALUE_DELTA);
257+
reqTimeUpdate = flags & (1 << EEPROM_S0_FLAG_UPDATE_TIME_DELTA);
258+
259+
// countLowPerHigh
260+
countLowPerHigh = eeprom_read_word((uint16_t *)S0_ADDR(EEPROM_S0_CNT_PER_KWH));
261+
262+
// delta values
263+
deltaBase = eeprom_read_word((uint16_t *)S0_ADDR(EEPROM_S0_DELTA_BASE));
264+
deltaFactor = eeprom_read_word((uint16_t *)S0_ADDR(EEPROM_S0_DELTA_FACTOR));
265+
266+
// time values
267+
timeBase = eeprom_read_word((uint16_t *)S0_ADDR(EEPROM_S0_TIME_BASE));
268+
timeFactor = eeprom_read_word((uint16_t *)S0_ADDR(EEPROM_S0_TIME_FACTOR));
269+
270+
}
271+
272+
};
273+
274+
275+
276+
277+
278+
279+
280+
281+
282+
283+

0 commit comments

Comments
 (0)