Forum

Please consider registering
guest

Log In Register

Register | Lost password?
Advanced Search

— Forum Scope —

  

— Match —

   

— Forum Options —

   

Minimum search word length is 4 characters - maximum search word length is 84 characters

Topic RSS
PWM start at negative edge
2016 年 03 月 24 日
16:31:15
garpastym
Moderator
Forum Posts: 20
Member Since:
2016 年 02 月 12 日
Offline

Hello. I have a simple question. I have bought several 86duino ONE. PWM works ok. I have programmed a spesial formula to rotate a potentiometer to analog pin 5 to simulate encoder. Now I am in need of a counterphase PWM wave. I mean that I always have a positive edge starting pwm. But i need a mirrored image of that pwm starting on negative edge. Please advise.

2016 年 03 月 24 日
19:59:47
zerozaber
Moderator
Forum Posts: 52
Member Since:
2015 年 02 月 11 日
Offline

USE THIS AT YOUR OWN RISK, DO NOT USE ENCODER LIBRARY IF NOT SURE.
Please note that these code will turn Encoder0 pin (A, B, C) into mirror PWM output, so if you connect encoder to these pin, It may burn your encoder and the board.
Because using different pin result in different code, I will use pin 9 as pwm output, and Enc0A for counterphase (mirror) output, the ENC0A pin is 42 (packed with SPI pins)

You need to modify TimerOne.h and TimerOne.cpp library in Directory\hardware\86duino\x86\libraries\TimerOne

in TimerOne.h
add void complementaryEnable(); below void (*isrCallback)(); in class TimerOne

in TimerOne.cpp
add somewhere
void TimerOne::complementaryEnable(){
unsigned short crossbar_ioaddr = sb_Read16(0x64)&0xfffe;
io_DisableINT();
mc_outp(MC_GENERAL, MCG_MODEREG1, mc_inp(MC_GENERAL, MCG_MODEREG1) & ~(3L));
io_outpb(crossbar_ioaddr + 0x90 + 16, 0x08);
io_outpb(crossbar_ioaddr + 0x90 + 18, 0x08);
io_outpb(crossbar_ioaddr + 0x90 + 21, 0x08);
io_RestoreINT();
}

In your code (INO)
call Timer1.complementaryEnable(); before Timer1.initialize();

and whenever you change duty of pin#9, pin 42 will automatically change.

2016 年 03 月 24 日
20:38:30
garpastym
Moderator
Forum Posts: 20
Member Since:
2016 年 02 月 12 日
Offline

Let me begin step by step.
I have taken your exasmple of analogWriteResolutiion() and downloaded it on the board. Then with a digital osciloscope I cheked the waveform and frequency. It showed 1 kHz and a duty cycle forming a nice wave. Then I рhave atached a potentiometer to analog input 5 and with boards 5 volts gradualy sent it to analog input. Using the function I have counet (looks like down below)

int sensorValue = analogRead(A5);
float voltage = sensorValue * (5.0 / 1023.0);
float degree = sensorValue;// * (360.0 / 1023.0);
float rads = degree*(pi/180);
float sinus = sin(rads);
float sin3alpha = sinus*(3*((2*pi*degree)/360));
int PWM1 = squ*amplitude*(sin(rads)+1/6*sin(3*rads))+511;
int PWM2 = squ*amplitude*(sin(rads-(2*pi/3))+1/6*sin(3*rads))+511;
int PWM3 = squ*amplitude*(sin(rads-(4*pi/3))+1/6*sin(3*rads))+511;

analogWriteResolution(12);
analogWrite(9, map(PWM1, 0, 1023, 0, 4095));

analogWriteResolution(12);
analogWrite(10, map(PWM2, 0, 1023, 0, 4095));

analogWriteResolution(12);
analogWrite(11, map(PWM3, 0, 1023, 0, 4095));

I generate a pulsewave for a three phase servo drive. But I need a rising edge and falling edge waves simultaniously, if you understand what i mean.

"By the way, what do you mean simulating encoder? Do you mean create encoder quadrature signal out?"
I use the potentiometr to simulate the position of the motor to where it shoud turn to.

P.S.

And other question I have seen in your slideshare brochure the example thet the MCM can generate theese waves. Isnt there a vbasic function to do that. And one more thing. Please be so kind to make a normal grouped FULLY described possibilities of your MCM with vast amount of examples (let them be simple but covering all the MCMs possibilities) and full not demo libraries.

P.P.S. your board is the coolest i have ever seen but you guys really have to speed up supporting your customers whith data nad full open source for libraries of your divices with detailed examples of coding.

Thanks for the reply.

2016 年 03 月 24 日
21:17:02
zerozaber
Moderator
Forum Posts: 52
Member Since:
2015 年 02 月 11 日
Offline

----------------------------------SORRY FOR MISTAKE, COPY NEW CODE (I miss copied it before, already fix in this post)-------------------------------

I have change my post above, reread it.
Before answer your question, I would like to tell you that I am not 86duino team, just a user that has rewrite my own version of MCM library (including PWM and Encoder) because I need 6 PWM and 6 encoder :D

OK, I already understand what are you doing
Firstly, I suggest you use Timer1 library for PWM instead of analogwrite, Timer1PWM can output at any frequency. Its sampling time is in resolution of 10ns

So what you need is "Synchronus Complementary PWM mode"
Now, you have to choose MCM module. I suggest you use module 0 which include pin# 9, 6, 5 and complementary pin 42 43 44 (pin 42 is complementary with pin 9)

You need to modify TimerOne.h and TimerOne.cpp library in Directory\hardware\86duino\x86\libraries\TimerOne
in TimerOne.h
add void complementaryEnable(); below void (*isrCallback)(); in class TimerOne
in TimerOne.cpp
add somewhere
void TimerOne::complementaryEnable(){
unsigned short crossbar_ioaddr = sb_Read16(0x64)&0xfffe;
io_DisableINT();
mc_outp(MC_GENERAL, MCG_MODEREG1, mc_inp(MC_GENERAL, MCG_MODEREG1) & ~(3L));
io_outpb(crossbar_ioaddr + 0x90 + 16, 0x08);
io_outpb(crossbar_ioaddr + 0x90 + 18, 0x08);
io_outpb(crossbar_ioaddr + 0x90 + 21, 0x08);
io_RestoreINT();
}
In your code (INO)
call Timer1.complementaryEnable(); before Timer1.initialize();

please see example of Timer1 library, you will know how to adjust duty and frequency

Also, as an extreme user of 86duino in arduino mode.
I think 86duino team try to write library that very arduino-like API, by not squeeze out its power much. Timer1 library is an example, if they want user to squeeze its performance, they should make API that let you modify duty and period in 10ns resolution instead of Double variable.
However, their libraries are very easy to read, so it is possible to use their library as example to write your own library.
To write library, you need to ask them for MCM datasheet and read their library.

Also note that 86Duino ONE's last MCM pin is not brought out, they use the last MCM pin to do Timer1.interrupt method.

PS. I would like to know your servo drive interface. Did you mean 3-Phase motor driver?

2016 年 03 月 24 日
22:32:13
garpastym
Moderator
Forum Posts: 20
Member Since:
2016 年 02 月 12 日
Offline

Hello again. I have done all the steps kindly provided from your side but i get a compilation error. I have added Timer1.complementaryEnable(); before Timer1.initialize(); in demo sketch FanSpeed but the compiler says

86DuinoONE
D:\VORTEX\86Duino_Coding_211_WIN\hardware\86duino\x86\libraries\TimerOne\TimerOne.cpp: In member function 'void TimerOne::complementaryEnable()':
D:\VORTEX\86Duino_Coding_211_WIN\hardware\86duino\x86\libraries\TimerOne\TimerOne.cpp:106:21: error: 'MCG_MODEREG1' was not declared in this scope
mc_outp(MC_GENERAL, MCG_MODEREG1, mc_inp(MC_GENERAL, MCG_MODEREG1) & ~(3L));

Oh... and i try to run a parker motor Cool

2016 年 03 月 24 日
22:58:24
zerozaber
Moderator
Forum Posts: 52
Member Since:
2015 年 02 月 11 日
Offline

garpastym said

Hello again. I have done all the steps kindly provided from your side but i get a compilation error. I have added Timer1.complementaryEnable(); before Timer1.initialize(); in demo sketch FanSpeed but the compiler says

86DuinoONE
D:\VORTEX\86Duino_Coding_211_WIN\hardware\86duino\x86\libraries\TimerOne\TimerOne.cpp: In member function 'void TimerOne::complementaryEnable()':
D:\VORTEX\86Duino_Coding_211_WIN\hardware\86duino\x86\libraries\TimerOne\TimerOne.cpp:106:21: error: 'MCG_MODEREG1' was not declared in this scope
mc_outp(MC_GENERAL, MCG_MODEREG1, mc_inp(MC_GENERAL, MCG_MODEREG1) & ~(3L));

Oh... and i try to run a parker motor Cool

I hate this.
MCG_MODEREG1 is defined in mcm.cpp, not mcm.h
but you cannot include mcm.cpp due to some error at delay() function
so replace MCG_MODEREG1 with 0x00L instead.

By the way, copy my code again since last time I miss copied them
the last time
v
v
io_outpb(crossbar_ioaddr + 0x90 + 16, 0x08);
io_outpb(crossbar_ioaddr + 0x90 + 19, 0x08);
io_outpb(crossbar_ioaddr + 0x90 + 20, 0x08);

Correction
v
v
io_outpb(crossbar_ioaddr + 0x90 + 16, 0x08);
io_outpb(crossbar_ioaddr + 0x90 + 18, 0x08);
io_outpb(crossbar_ioaddr + 0x90 + 21, 0x08);

So you use this mode to drive motor driver or servo controller?

2016 年 03 月 24 日
23:26:40
garpastym
Moderator
Forum Posts: 20
Member Since:
2016 年 02 月 12 日
Offline

YES! Everything works great! I have a reverse pwm signal with 25 Khz on output! Thank you very mch for the advise.Smile
And I have recieved rotation of the motor shaft.

I use this code to directtly send pwm signal to my Parker motor power supplying board I have developed myself.

86Duino+power board = ready to use servo motor driver!

2016 年 03 月 24 日
23:40:57
zerozaber
Moderator
Forum Posts: 52
Member Since:
2015 年 02 月 11 日
Offline

Congratuation

because 86duino ONE hide its last mcm pin, so only 3 module available, thus driving maximum of 3 motors
To drive 3 motors change the code into

void TimerOne::complementaryEnable(){
unsigned short crossbar_ioaddr = sb_Read16(0x64)&0xfffe;
io_DisableINT();
mc_outp(MC_GENERAL, MCG_MODEREG1, mc_inp(MC_GENERAL, MCG_MODEREG1) & ~(3L));//module 0
mc_outp(MC_GENERAL, MCG_MODEREG1, mc_inp(MC_GENERAL, MCG_MODEREG1) & ~(3L << 4));//module 1
mc_outp(MC_GENERAL, MCG_MODEREG1, mc_inp(MC_GENERAL, MCG_MODEREG1) & ~(3L << 8));// module 2
io_outpb(crossbar_ioaddr + 0x90 + 16, 0x08);//module0
io_outpb(crossbar_ioaddr + 0x90 + 18, 0x08);
io_outpb(crossbar_ioaddr + 0x90 + 21, 0x08);
io_outpb(crossbar_ioaddr + 0x90 + 24, 0x08);//module1
io_outpb(crossbar_ioaddr + 0x90 + 26, 0x08);
io_outpb(crossbar_ioaddr + 0x90 + 29, 0x08);
io_outpb(crossbar_ioaddr + 0x90 + 0, 0x08);// module2
io_outpb(crossbar_ioaddr + 0x90 + 2, 0x08);
io_outpb(crossbar_ioaddr + 0x90 + 5, 0x08);
io_RestoreINT();
}

for pin and complimentary pin, see PIN DEFINE table in 86duino ONE Schematic
The MCM pin will be list as MPXY,
X is module
Y=1 is mdn = 0, complimentary is Y = 0
Y=3 is mdn = 1 complimentary is Y = 2
Y=5 is mdn = 2 complimentary is Y = 4

2016 年 03 月 25 日
15:44:48
garpastym
Moderator
Forum Posts: 20
Member Since:
2016 年 02 月 12 日
Offline

Good morning! (or what time is there at your placeWink) I have made changes according to your last post. Also I havent forgot to change the name of MCG_MODEREG1 to 0x00L and the function in cpp file now looks like this

void TimerOne::complementaryEnable(){
unsigned short crossbar_ioaddr = sb_Read16(0x64)&0xfffe;
io_DisableINT();
mc_outp(MC_GENERAL, 0x00L, mc_inp(MC_GENERAL, 0x00L) & ~(3L));//module0
mc_outp(MC_GENERAL, 0x00L, mc_inp(MC_GENERAL, 0x00L) & ~(3L << 4));//module 1
mc_outp(MC_GENERAL, 0x00L, mc_inp(MC_GENERAL, 0x00L) & ~(3L << 8));// module 2
io_outpb(crossbar_ioaddr + 0x90 + 16, 0x08);//module0
io_outpb(crossbar_ioaddr + 0x90 + 18, 0x08);
io_outpb(crossbar_ioaddr + 0x90 + 21, 0x08);
io_outpb(crossbar_ioaddr + 0x90 + 24, 0x08);//module1
io_outpb(crossbar_ioaddr + 0x90 + 26, 0x08);
io_outpb(crossbar_ioaddr + 0x90 + 29, 0x08);
io_outpb(crossbar_ioaddr + 0x90 + 0, 0x08);// module2
io_outpb(crossbar_ioaddr + 0x90 + 2, 0x08);
io_outpb(crossbar_ioaddr + 0x90 + 5, 0x08);
io_RestoreINT();
}

Then i take the example TimerOne programm and add two more pins in the code before void setup();

const int fanPin1 = 9;
const int fanPin2 = 10;
const int fanPin3 = 11;

void setup(void)
{
Timer1.complementaryEnable();
Timer1.initialize(40); // 40 us = 25 kHz
Serial.begin(9600);
}

void loop(void)
{
// slowly increase the PWM fan speed
//
for (float dutyCycle = 30.0; dutyCycle < 100.0; dutyCycle++) {
Serial.print("PWM Fan, Duty Cycle = ");
Serial.println(dutyCycle);
Timer1.pwm(fanPin1, (dutyCycle / 100) * 1023);
Timer1.pwm(fanPin2, (dutyCycle / 100) * 1023);
Timer1.pwm(fanPin3, (dutyCycle / 100) * 1023);
delay(500);
}
}

but I only get PWM on pin 9 and the coresponding pin 42 inverted PWM, all ther pins are silent. Maybe i shouldn't have made changes of MCG_MODEREG1 to 0x00L?

Maybe There should also be added two more lines like this first in function
unsigned short crossbar_ioaddr = sb_Read16(0x64)&0xfffe; but with different parameters?

2016 年 03 月 25 日
18:54:31
zerozaber
Moderator
Forum Posts: 52
Member Since:
2015 年 02 月 11 日
Offline

After code change, can you still use pin 9, 6, 5?
if all pin of module 0 works, it should be mistake in bit shifting, I still don't understand digit syntax,

First solution, change
mc_outp(MC_GENERAL, 0x00L, mc_inp(MC_GENERAL, 0x00L) & ~(3L));//module0
mc_outp(MC_GENERAL, 0x00L, mc_inp(MC_GENERAL, 0x00L) & ~(3L << 4));//module 1
mc_outp(MC_GENERAL, 0x00L, mc_inp(MC_GENERAL, 0x00L) & ~(3L << 8));// module 2

into
mc_outp(MC_GENERAL, 0x00L, mc_inp(MC_GENERAL, 0x00L) & ~(0x0fL));//module0
mc_outp(MC_GENERAL, 0x00L, mc_inp(MC_GENERAL, 0x00L) & ~(0x0fL << 4));//module 1
mc_outp(MC_GENERAL, 0x00L, mc_inp(MC_GENERAL, 0x00L) & ~(0x0fL << 8));// module 2

Please try the first three module, every pin

2016 年 03 月 25 日
19:45:02
garpastym
Moderator
Forum Posts: 20
Member Since:
2016 年 02 月 12 日
Offline

Nope. No change on pins. Only pin 9 and 42 are active. Iven the rising edge oscilogram on pins 10 and 11 doestn't work< not mentioning the inverted one Confused

But if I comment out the Timer1.complementaryEnable(); all ports 9 10 11 work great. But no reverse PWM though. duhhh....

2016 年 03 月 25 日
20:36:44
zerozaber
Moderator
Forum Posts: 52
Member Since:
2015 年 02 月 11 日
Offline
12

OK, I have test it with my oscilloscope.
I already know the problem.
There is a problem using synchronous mode., is it fine if you use independent mode instead of synchronous?
for module0 independent mode is when pin 9, 6, 5 start not exactly the same, however, their compliment pin will start exactly the same time as main pins.

if you want to use indepentdent, just change

mc_outp(MC_GENERAL, 0x00L, mc_inp(MC_GENERAL, 0x00L) & ~(3L));//module0
mc_outp(MC_GENERAL, 0x00L, mc_inp(MC_GENERAL, 0x00L) & ~(3L << 4));//module 1
mc_outp(MC_GENERAL, 0x00L, mc_inp(MC_GENERAL, 0x00L) & ~(3L << 8));// module 2

into
mc_outp(MC_GENERAL, 0x00L, mc_inp(MC_GENERAL, 0x00L) & ~(0xeeeL));//module 0-3

I have tested this and works
Tell me if you want to use synchronous mode, because I have to study about this mode a little.

2016 年 03 月 25 日
21:16:20
garpastym
Moderator
Forum Posts: 20
Member Since:
2016 年 02 月 12 日
Offline

On pins 9,10,11 and coresponding mirror edge pins 19, 20, 42 I recieve good sincronus mirrored pwm waves. It means that pwm pins marked with "~" are outputs with positive edge and pins marked as "*" are ouput for negative edge.

Pairs are
pin 9 positive edge pin 42 negative edge => pwm pair phase A
pin 10 positive edge pin 20 negative edge => pwm pair phase B
pin 11 positive edge pin 19 negative edge => pwm pair phase C

I will now try to programm the mathemetical formula for the modulation of pwm and run the motor. After everything sucseeds I will post the code.

Up to this moment everything works great and pwm works in sinchronus mode.It means that all of the signal are mirrored equaly whithout any phase shift.

By the way what did you mean about asinchron mode - does it mean that i have a much easear way to parameries the waves offset to form a PWM turning magnets 120* degree offset whith a simpler function or what?

2016 年 03 月 25 日
21:41:32
garpastym
Moderator
Forum Posts: 20
Member Since:
2016 年 02 月 12 日
Offline
14

Yep Frown You were right.

I need a slight slower negative edge pwm to differ from the positive one to allow the transistors on the power board to have some dead time to open and close.

2016 年 03 月 25 日
21:48:14
zerozaber
Moderator
Forum Posts: 52
Member Since:
2015 年 02 月 11 日
Offline
15

Please use whole module0 for 1 motor, using different module will make you have less pin for another function
For module0
PWM A is pin 9 and its compliment is 42
PWM B is pin 6 and its compliment is 43
PWM C is pin 5 and its compliment is 44

Pin 10 11 and 13 is belong to module 1

Please see schematic for pin mapping

Pin that mark with ~ means main PWM pin
* means encoder pins, but we change them to compliment pin.

For synchronous mode, let me study a bit more
If 86duino team here, please explain it to me.

2016 年 03 月 25 日
22:06:02
garpastym
Moderator
Forum Posts: 20
Member Since:
2016 年 02 月 12 日
Offline

______ |*******|___________ positeve PWM
********* |********|
********* | --------|
******* | -------- | Some deadtime befor negative comes after positive.
****** |********|
___ __ |********|__________ negative PWM

Some improvisation - sorry no pic possible to upload - that is what i need to resieve. Deadtime is what i need but now they work mirrored like. Is it possible to delay rising edge for 3 microseconds and falling edge also for 3 microseconds. simply them or some other way from ino code?

the code so far

#include

const float pi = 3.14;
const float squ = 1/sqrt(3);
const int amplitude = 511;
const int fanPin1 = 9;
const int fanPin2 = 6;
const int fanPin3 = 5;

void setup(void)
{
Timer1.complementaryEnable();
Timer1.initialize(500); // 40 us = 25 kHz
Serial.begin(9600);

}

void loop(void)
{
int sensorValue = analogRead(A5);
float voltage = sensorValue * (5.0 / 1023.0);
float degree = sensorValue;// * (360.0 / 1023.0);
float rads = degree*(pi/180);
float sinus = sin(rads);
float sin3alpha = sinus*(3*((2*pi*degree)/360));
int PWM1 = squ*amplitude*(sin(rads)+1/6*sin(3*rads))+511;
int PWM2 = squ*amplitude*(sin(rads-(2*pi/3))+1/6*sin(3*rads))+511;
int PWM3 = squ*amplitude*(sin(rads-(4*pi/3))+1/6*sin(3*rads))+511;

Timer1.pwm(fanPin1, PWM1);
Timer1.pwm(fanPin2, PWM2);
Timer1.pwm(fanPin3, PWM3);

}

2016 年 03 月 25 日
22:17:18
zerozaber
Moderator
Forum Posts: 52
Member Since:
2015 年 02 月 11 日
Offline
17

garpastym said

______ |*******|___________ positeve PWM
********* |********|
********* | --------|
******* | -------- | Some deadtime befor negative comes after positive.
****** |********|
___ __ |********|__________ negative PWM

Some improvisation - sorry no pic possible to upload - that is what i need to resieve. Deadtime is what i need but now they work mirrored like. Is it possible to delay rising edge for 3 microseconds and falling edge also for 3 microseconds. simply them or some other way from ino code?

I couldn't understand you at all.
Please draw picture for me, post it somewhere.
I need
1. All six waveform( A, A-, B, B-, C, C-) of current system.
2. All six waveform of desired system.

2016 年 03 月 25 日
22:31:47
garpastym
Moderator
Forum Posts: 20
Member Since:
2016 年 02 月 12 日
Offline

What i have so far http://s21.postimg.org/i6nfq29....._16183.jpg
http://s21.postimg.org/y4w5g739v/IMG_20160325_16183.jpg

What i need to acheeve http://s24.postimg.org/5ejyarz....._16183.jpg
http://s24.postimg.org/5rbcgyha9/IMG_20160325_16183.jpg

And I need that PWM deadtime on all A-;B-;C- PWN equal. As you can understand if I will not have dead time the tansistorsa will have straight through current and the IGBT module will go in error because of current. The deadtime between firs and second PWM on each phase allows transistors to have some time to close before opening on commking of second wave.

2016 年 03 月 25 日
22:47:53
zerozaber
Moderator
Forum Posts: 52
Member Since:
2015 年 02 月 11 日
Offline
19

garpastym said

What i have so far http://s21.postimg.org/i6nfq29....._16183.jpg
http://s21.postimg.org/y4w5g739v/IMG_20160325_16183.jpg

What i need to acheeve http://s24.postimg.org/5ejyarz....._16183.jpg
http://s24.postimg.org/5rbcgyha9/IMG_20160325_16183.jpg

So you don't need to change offset between PWM A and PWM B and C
All you need is shifting between A and A- right? Apply those to B andC too.
Let me read MCM datasheet for a while.

2016 年 03 月 25 日
23:12:37
zerozaber
Moderator
Forum Posts: 52
Member Since:
2015 年 02 月 11 日
Offline

After study...
It is possible to insert deadband of 3us. But inserting deadband will make rising edge of you yellow signal shift to the right by 3us which you want. However, rising edge of blue signal will also shifted to the right by 3us, not shifting falling edge to the left as you want.
If this is fine with you, I will tell you how to do it.

But if you want to do as the picture, it is very hard as you have to use module1 PWM A as your A-, and you have to synchronize the edge, also reload both pwm at the same time. Modifying TimerOne library will be harder than writing your new library.

giving me you system schematic will help me to understand you better, and I may suggest alternative.

Forum Timezone: Asia/Taipei

Most Users Ever Online: 66

Currently Online:
2 Guest(s)

Currently Browsing this Page:
1 Guest(s)

Top Posters:

Dinosaur: 27

leutenecker: 13

mrZagg: 10

lukeross: 8

tomka: 8

smeezekitty: 8

hippy: 8

Ekkehard: 8

UIdahoCIT: 8

blaxxun: 7

Member Stats:

Guest Posters: 0

Members: 1509

Moderators: 14

Admins: 5

Forum Stats:

Groups: 2

Forums: 10

Topics: 238

Posts: 1079

Newest Members: Carol Chou, Kai-Jung Chou, 1789, RegLiu, ameerawwad, asmanko, nekotwingo, ttronic, Davidpag, zaskia12

Moderators: Glaux: 70, uaa: 11, guigra: 17, asian55: 22, Android_Lin: 208, bcarroll: 12, cucubutter: 84, recycled-air: 12, stevemork: 16, zerozaber: 52, pongraczi: 20, George Andrews III: 56, poto: 11, garpastym: 20

Administrators: eveshih: 1, anthony: 31, viky6: 0, roboard: 135, hcl: 0