diff --git a/README.md b/README.md index 2c0cf5c..58f5d5f 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,83 @@ # QO-100-modem The purpose of this project is to transfer data (pictures...) via a 2,7kHz SSB channel on the narrow band transponder as fast as possible. -# the actual version is hosted in the Amsat-DL Github Repo: +# this is work in progress +Version 0.4 is working on: +Windows 10 (should work on Win7, not tested) +linux Desktop PC, +Odroid SBC +Raspberry 4 (3B+) -https://github.com/amsat-dl/QO-100-Modem +# Prerequisites +* Windopws 10 Desktop PC ... working +* LINUX Desktop PC ... working +* Raspberry PI 4 ... working +* Raspberry PI 3B+ ... working, but not 100% error free in fullduplex mode (RX only or TX only is working) +* Odroid N2 ... working +* Odroid C2 ... working +* Odroid C4 ... working + +* Raspberry: Raspian OS ist NOT working, instead Ubuntu 64bit is required + +* Application Software "oscardata.exe" running on Windows, Linux, (possibly MAC-OS, not tested) + +# 3rd Party Libraries +this software uses these programs: +* Shifra Reed Solomon code: https://www.schifra.com/ (GPL V.2) +* liquid-SDR: https://github.com/jgaeddert/liquid-dsp (MIT License) +* libsoundio: https://github.com/andrewrk/libsoundio (MIT License) +* fftw3: http://www.fftw.org (GPL V.2 or later) +* libcodec2: https://github.com/drowe67/codec2 (LGPL 2.1, Linux: standard lib, Windows: from freeDV) + +# Download alternatives +* download from github and build from source +* download windows installer and download Odroid and Raspberry images: +https://dj0abr.de/german/technik/sat/modem/images.htm +# building the software for Linux +* Linux +1. Download from github the file hsmodem/hsmodem.sh, ONLY ! Do not clone the repository, download ONLY this single file. +2. copy hsmodem.hs to your home directory and make it executable (chmod 755 hsmodem.sh) +3. run the file: ./hsmodem.sh +this will make download, compile hsmodem an install all required files +the resulting project is in ./SSB_HighSpeed_Modem/hsmodemLinux + +# starting the modem and application + +you need to run 2 programs, the first one is "hsmodem" which runs in a termimal without GUI. This is the modem doing all modulation and demodulation staff. +The second program is the user interface "oscardata.exe". +oscardata.exe starts hsmodem automatically in the background. If you want to run hsmodem on one machine and oscardata on another then deactivate the autostart in the Setup menu in oscardata.exe + +* Windows +if the software was installed with this setup file: +https://wx.spdns.de/german/technik/sat/modem/images.htm +then you find the program under the program group "amsat" in the Window's start menu + +* Linux +1. go into the folder ..../SSB_HighSpeed_Modem/hsmodemLinux +2. run the software: mono oscardata.exe + +# tested scenarious + +* QO-100 via IC-9700, IC-7300 or IC-7100 ... working +* Short Wave 6m band via IC-7300, IC-7100 ... working. In case of significant noise, use the lowest bit rate (3000 bit/s) + + +# usage + +In the IC-9700 activate the DATA mode and the RX filter FIL1 to full range of 3.6kHz. + +In oscardata.exe go to the "BER" tab. Then click START. If you change the bitrate, wait a few seconds before starting again. + +The program is now sending test data frames to the default sound card. If your sound card is properly connected to the transceiver then switch the transceiver to TX and the data will be sent to QO-100. +Receive your transmission, feed it to the default soundcard. As soon as oscardata.exe detects a correct data frame it will display status messages on the screen. + +(For testing purposes you can just connect Line-Out of your soundcard with Line-IN with a cable.) + +To assign the soundcard to the modem I recommend to use pavucontrol. Using the TX volume set a signal level of about 20 to 24 dB over noise floor. You will need about -10dB compared to the BPSK400 beacon. The received audio volume can be adjusted with help of the spectrum display in oscardata.exe- + +Now as the transmission is OK, you can go to the "Image RX/TX" tab. First, select a picture quality then load a picture and finally press SEND to send it to QO-100. When you correctly receive your own transmission the RX picture will be displayed line by line. + +vy 73, DJ0ABR + diff --git a/WinRelease/Satellite-icon.ico b/WinRelease/Satellite-icon.ico new file mode 100755 index 0000000..86160c1 Binary files /dev/null and b/WinRelease/Satellite-icon.ico differ diff --git a/WinRelease/hsmodem.exe b/WinRelease/hsmodem.exe index 05ff01f..e96d11e 100755 Binary files a/WinRelease/hsmodem.exe and b/WinRelease/hsmodem.exe differ diff --git a/WinRelease/hsmodem.iobj b/WinRelease/hsmodem.iobj new file mode 100755 index 0000000..6cb9595 Binary files /dev/null and b/WinRelease/hsmodem.iobj differ diff --git a/WinRelease/hsmodem.ipdb b/WinRelease/hsmodem.ipdb new file mode 100755 index 0000000..e241513 Binary files /dev/null and b/WinRelease/hsmodem.ipdb differ diff --git a/WinRelease/hsmodem.pdb b/WinRelease/hsmodem.pdb new file mode 100755 index 0000000..10c216a Binary files /dev/null and b/WinRelease/hsmodem.pdb differ diff --git a/WinRelease/oscardata.exe b/WinRelease/oscardata.exe index c628888..bdff112 100755 Binary files a/WinRelease/oscardata.exe and b/WinRelease/oscardata.exe differ diff --git a/WinRelease/sio_list_devices.exe b/WinRelease/sio_list_devices.exe new file mode 100755 index 0000000..0bc7bf8 Binary files /dev/null and b/WinRelease/sio_list_devices.exe differ diff --git a/WinRelease/sio_sine.exe b/WinRelease/sio_sine.exe new file mode 100755 index 0000000..785f254 Binary files /dev/null and b/WinRelease/sio_sine.exe differ diff --git a/hsmodem/fft.cpp b/hsmodem/fft.cpp index 401ac7f..4c6451f 100755 --- a/hsmodem/fft.cpp +++ b/hsmodem/fft.cpp @@ -128,7 +128,7 @@ uint16_t *make_waterfall(float fre, int *retlen) // check if signal detected or not if (idiff > 100) sig = 0; - if (idiff < 20) sig = 1; + if (idiff < 30) sig = 1; rxlevel_deteced = sig; diff --git a/hsmodem/hsmodem.cpp b/hsmodem/hsmodem.cpp index 4cbf684..4d66f24 100755 --- a/hsmodem/hsmodem.cpp +++ b/hsmodem/hsmodem.cpp @@ -307,11 +307,6 @@ void bc_rxdata(uint8_t* pdata, int len, struct sockaddr_in* rxsock) * 110 .. 209 ... CAP device name */ - //printf("%d %d %d %d %d %d %d \n",pdata[1], pdata[2], pdata[3], pdata[4], pdata[5], pdata[6], pdata[7]); - io_setAudioDevices(pdata[1], pdata[2], pdata[3], pdata[4], pdata[5], (char *)(pdata + 10), (char *)(pdata + 110)); - - safemode = pdata[6]; - char rxip[20]; strcpy(rxip, inet_ntoa(rxsock->sin_addr)); @@ -336,14 +331,19 @@ void bc_rxdata(uint8_t* pdata, int len, struct sockaddr_in* rxsock) if (!strcmp(appIP, rxip)) { //printf("app (%s) is searching modem. Sending modem IP to the app\n",appIP); - restart_modems = 1; // App searches for the modem IP, mirror the received messages // so the app gets an UDP message with this local IP int alen; uint8_t* txdata = io_getAudioDevicelist(&alen); sendUDP(appIP, UdpDataPort_ModemToApp, txdata, alen); } + else + return; } + + //printf("%d %d %d %d %d %d %d \n",pdata[1], pdata[2], pdata[3], pdata[4], pdata[5], pdata[6], pdata[7]); + io_setAudioDevices(pdata[1], pdata[2], pdata[3], pdata[4], pdata[5], (char*)(pdata + 10), (char*)(pdata + 110)); + safemode = pdata[6]; } } @@ -560,16 +560,14 @@ void GRdata_rxdata(uint8_t* pdata, int len, struct sockaddr_in* rxsock) uint8_t* pl = unpack_data(pdata, len); if (pl != NULL) { - if (VoiceAudioMode != VOICEMODE_DV_FULLDUPLEX) - { - // complete frame received - // send payload to app - uint8_t txpl[PAYLOADLEN + 10 + 1]; - memcpy(txpl + 1, pl, PAYLOADLEN + 10); - txpl[0] = 1; // type 1: payload data follows - sendUDP(appIP, UdpDataPort_ModemToApp, txpl, PAYLOADLEN + 10 + 1); - } - else + // complete frame received + // send payload to app + uint8_t txpl[PAYLOADLEN + 10 + 1]; + memcpy(txpl + 1, pl, PAYLOADLEN + 10); + txpl[0] = 1; // type 1: payload data follows + sendUDP(appIP, UdpDataPort_ModemToApp, txpl, PAYLOADLEN + 10 + 1); + + if (VoiceAudioMode == VOICEMODE_DV_FULLDUPLEX) { // send to Codec decoder if (*(pl + 3) != 0) // minfo=0 ... just a filler, ignore diff --git a/hsmodem/liquid_if.cpp b/hsmodem/liquid_if.cpp index 8e15489..559b606 100755 --- a/hsmodem/liquid_if.cpp +++ b/hsmodem/liquid_if.cpp @@ -429,7 +429,7 @@ static int ccol_idx = 0; // we have about 2000 S/s, but this many points would make the GUI slow // so we send only every x static int ev = 0; - if (++ev >= 10) + if (++ev >= 5)//10) { ev = 0; int32_t re = (int32_t)(syms.real * 16777216.0); diff --git a/oscardata/oscardata/Form1.Designer.cs b/oscardata/oscardata/Form1.Designer.cs index 1d6200e..5d6b123 100755 --- a/oscardata/oscardata/Form1.Designer.cs +++ b/oscardata/oscardata/Form1.Designer.cs @@ -33,6 +33,7 @@ this.timer_udpTX = new System.Windows.Forms.Timer(this.components); this.timer_udprx = new System.Windows.Forms.Timer(this.components); this.statusStrip1 = new System.Windows.Forms.StatusStrip(); + this.toolStrip_Type = new System.Windows.Forms.ToolStripStatusLabel(); this.toolStripStatusLabel = new System.Windows.Forms.ToolStripStatusLabel(); this.ts_ip = new System.Windows.Forms.ToolStripStatusLabel(); this.RXstatus = new System.Windows.Forms.ToolStripStatusLabel(); @@ -107,8 +108,6 @@ this.bt_resetmodem = new System.Windows.Forms.Button(); this.textBox3 = new System.Windows.Forms.TextBox(); this.groupBox3 = new System.Windows.Forms.GroupBox(); - this.vu_cap = new oscardata.KmProgressBar(); - this.vu_pb = new oscardata.KmProgressBar(); this.pb_audioCAPstatus = new System.Windows.Forms.PictureBox(); this.pb_audioPBstatus = new System.Windows.Forms.PictureBox(); this.label6 = new System.Windows.Forms.Label(); @@ -135,15 +134,17 @@ this.cb_speed = new System.Windows.Forms.ComboBox(); this.label_speed = new System.Windows.Forms.Label(); this.timer_searchmodem = new System.Windows.Forms.Timer(this.components); - this.progressBar_fifo = new oscardata.KmProgressBar(); this.label_fifo = new System.Windows.Forms.Label(); this.bt_blockinfo = new System.Windows.Forms.Button(); - this.progressBar_capfifo = new oscardata.KmProgressBar(); this.label_capfifo = new System.Windows.Forms.Label(); this.lb_rxsignal = new System.Windows.Forms.Label(); this.lb_rxsync = new System.Windows.Forms.Label(); this.pb_rxsync = new System.Windows.Forms.PictureBox(); this.pb_rxsignal = new System.Windows.Forms.PictureBox(); + this.progressBar_capfifo = new oscardata.KmProgressBar(); + this.progressBar_fifo = new oscardata.KmProgressBar(); + this.vu_cap = new oscardata.KmProgressBar(); + this.vu_pb = new oscardata.KmProgressBar(); this.statusStrip1.SuspendLayout(); this.tabPage_ber.SuspendLayout(); this.tabPage_image.SuspendLayout(); @@ -188,6 +189,7 @@ // this.statusStrip1.ImageScalingSize = new System.Drawing.Size(20, 20); this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.toolStrip_Type, this.toolStripStatusLabel, this.ts_ip, this.RXstatus}); @@ -197,6 +199,13 @@ this.statusStrip1.TabIndex = 4; this.statusStrip1.Text = "statusStrip1"; // + // toolStrip_Type + // + this.toolStrip_Type.Font = new System.Drawing.Font("Verdana", 9F, System.Drawing.FontStyle.Bold); + this.toolStrip_Type.ForeColor = System.Drawing.Color.Red; + this.toolStrip_Type.Name = "toolStrip_Type"; + this.toolStrip_Type.Size = new System.Drawing.Size(0, 17); + // // toolStripStatusLabel // this.toolStripStatusLabel.Name = "toolStripStatusLabel"; @@ -1070,20 +1079,6 @@ this.groupBox3.TabStop = false; this.groupBox3.Text = "Transceiver Audio"; // - // vu_cap - // - this.vu_cap.Location = new System.Drawing.Point(479, 87); - this.vu_cap.Name = "vu_cap"; - this.vu_cap.Size = new System.Drawing.Size(100, 10); - this.vu_cap.TabIndex = 20; - // - // vu_pb - // - this.vu_pb.Location = new System.Drawing.Point(479, 45); - this.vu_pb.Name = "vu_pb"; - this.vu_pb.Size = new System.Drawing.Size(100, 10); - this.vu_pb.TabIndex = 19; - // // pb_audioCAPstatus // this.pb_audioCAPstatus.BackgroundImage = global::oscardata.Properties.Resources.ok; @@ -1375,17 +1370,6 @@ this.timer_searchmodem.Interval = 1000; this.timer_searchmodem.Tick += new System.EventHandler(this.timer_searchmodem_Tick); // - // progressBar_fifo - // - this.progressBar_fifo.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(128)))), ((int)(((byte)(255)))), ((int)(((byte)(255))))); - this.progressBar_fifo.Location = new System.Drawing.Point(658, 618); - this.progressBar_fifo.Maximum = 20; - this.progressBar_fifo.Name = "progressBar_fifo"; - this.progressBar_fifo.Size = new System.Drawing.Size(304, 18); - this.progressBar_fifo.Step = 11; - this.progressBar_fifo.Style = System.Windows.Forms.ProgressBarStyle.Continuous; - this.progressBar_fifo.TabIndex = 13; - // // label_fifo // this.label_fifo.AutoSize = true; @@ -1405,16 +1389,6 @@ this.bt_blockinfo.UseVisualStyleBackColor = true; this.bt_blockinfo.Click += new System.EventHandler(this.bt_blockinfo_Click); // - // progressBar_capfifo - // - this.progressBar_capfifo.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(192)))), ((int)(((byte)(128))))); - this.progressBar_capfifo.Location = new System.Drawing.Point(658, 642); - this.progressBar_capfifo.Name = "progressBar_capfifo"; - this.progressBar_capfifo.Size = new System.Drawing.Size(304, 18); - this.progressBar_capfifo.Step = 1; - this.progressBar_capfifo.Style = System.Windows.Forms.ProgressBarStyle.Continuous; - this.progressBar_capfifo.TabIndex = 15; - // // label_capfifo // this.label_capfifo.AutoSize = true; @@ -1462,6 +1436,41 @@ this.pb_rxsignal.TabIndex = 17; this.pb_rxsignal.TabStop = false; // + // progressBar_capfifo + // + this.progressBar_capfifo.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(192)))), ((int)(((byte)(128))))); + this.progressBar_capfifo.Location = new System.Drawing.Point(658, 642); + this.progressBar_capfifo.Name = "progressBar_capfifo"; + this.progressBar_capfifo.Size = new System.Drawing.Size(304, 18); + this.progressBar_capfifo.Step = 1; + this.progressBar_capfifo.Style = System.Windows.Forms.ProgressBarStyle.Continuous; + this.progressBar_capfifo.TabIndex = 15; + // + // progressBar_fifo + // + this.progressBar_fifo.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(128)))), ((int)(((byte)(255)))), ((int)(((byte)(255))))); + this.progressBar_fifo.Location = new System.Drawing.Point(658, 618); + this.progressBar_fifo.Maximum = 20; + this.progressBar_fifo.Name = "progressBar_fifo"; + this.progressBar_fifo.Size = new System.Drawing.Size(304, 18); + this.progressBar_fifo.Step = 11; + this.progressBar_fifo.Style = System.Windows.Forms.ProgressBarStyle.Continuous; + this.progressBar_fifo.TabIndex = 13; + // + // vu_cap + // + this.vu_cap.Location = new System.Drawing.Point(479, 87); + this.vu_cap.Name = "vu_cap"; + this.vu_cap.Size = new System.Drawing.Size(100, 10); + this.vu_cap.TabIndex = 20; + // + // vu_pb + // + this.vu_pb.Location = new System.Drawing.Point(479, 45); + this.vu_pb.Name = "vu_pb"; + this.vu_pb.Size = new System.Drawing.Size(100, 10); + this.vu_pb.TabIndex = 19; + // // Form1 // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); @@ -1485,7 +1494,7 @@ this.ForeColor = System.Drawing.SystemColors.ControlText; this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); this.Name = "Form1"; - this.Text = "QO-100 NB Transponder HS Multimedia Modem AMSAT-DL V0.50 by DJ0ABR"; + this.Text = "AMSAT-DL Multimedia HS Modem V0.51 by DJ0ABR"; this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form1_FormClosing); this.statusStrip1.ResumeLayout(false); this.statusStrip1.PerformLayout(); @@ -1648,6 +1657,7 @@ private System.Windows.Forms.ComboBox cb_safemode; private KmProgressBar vu_cap; private KmProgressBar vu_pb; + private System.Windows.Forms.ToolStripStatusLabel toolStrip_Type; } } diff --git a/oscardata/oscardata/Form1.cs b/oscardata/oscardata/Form1.cs index 987c837..fbd033a 100755 --- a/oscardata/oscardata/Form1.cs +++ b/oscardata/oscardata/Form1.cs @@ -397,6 +397,22 @@ namespace oscardata } } + int lasttype = -1; + void showType(int rxtype) + { + if(rxtype != lasttype) + { + if (rxtype == statics.Image) toolStrip_Type.Text = "RX: IMAGE"; + if (rxtype == statics.AsciiFile) toolStrip_Type.Text = "RX: TEXT"; + if (rxtype == statics.HTMLFile) toolStrip_Type.Text = "RX: HTML/Web"; + if (rxtype == statics.BinaryFile) toolStrip_Type.Text = "RX: BINARY"; + if (rxtype == statics.BERtest) toolStrip_Type.Text = "RX: BER TEST"; + if (rxtype == statics.Audio) toolStrip_Type.Text = "RX: DV-Audio"; + if (rxtype == -1) toolStrip_Type.Text = "no RX"; + lasttype = rxtype; + } + } + // RX timer int rxstat = 0; int speed; @@ -426,6 +442,8 @@ namespace oscardata Byte[] rxdata = new byte[rxd.Length - 10]; Array.Copy(rxd, 10, rxdata, 0, rxd.Length - 10); + showType(rxtype); + //Console.WriteLine("minfo:" + minfo + " data:" + rxdata[0].ToString("X2") + " " + rxdata[1].ToString("X2")); // ========= receive file ========== @@ -578,7 +596,15 @@ namespace oscardata if (statics.CAPfifousage > 50) progressBar_capfifo.ForeColor = Color.Red; else progressBar_capfifo.ForeColor = Color.Green; // Show RX Status LEDs - if (statics.RXlevelDetected == 1) pb_rxsignal.BackgroundImage = Resources.greenmarker; else pb_rxsignal.BackgroundImage = Resources.redmarker; + if (statics.RXlevelDetected == 1) + { + pb_rxsignal.BackgroundImage = Resources.greenmarker; + } + else + { + pb_rxsignal.BackgroundImage = Resources.redmarker; + showType(-1); + } if (statics.RXinSync == 1 && statics.RXlevelDetected == 1) pb_rxsync.BackgroundImage = Resources.greenmarker; else pb_rxsync.BackgroundImage = Resources.redmarker; // update rx,tx level progress bar diff --git a/oscardata/oscardata/Form1.resx b/oscardata/oscardata/Form1.resx index 5b75622..3468f37 100755 --- a/oscardata/oscardata/Form1.resx +++ b/oscardata/oscardata/Form1.resx @@ -137,7 +137,7 @@ AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAABw - FwAAAk1TRnQBSQFMAgEBDQEAAUgBAgFIAQIBEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo + FwAAAk1TRnQBSQFMAgEBDQEAAaABAgGgAQIBEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo AwABQAMAAUADAAEBAQABCAYAARAYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5 AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA @@ -241,11 +241,13 @@ - QO-100 Multimedia High Speed Modem (Linux & Windows) + Amsat-DL Multimedia High Speed Modem (Linux & Windows) -(c) DJ0ABR, Kurt Moraw, Germany https://dj0abr.de/ +Author: (c) DJ0ABR, Kurt Moraw, Germany https://dj0abr.de/ +Wiki: https://hsmodem.dj0abr.de/doku.php +License: GPL V2 or later Amsat-DL: https://amsat-dl.org/ -Open Source: https://github.com/dj0abr/SSB_HighSpeed_Modem +Open Source: https://github.com/amsat-dl 3rd Party, Credits and Licensing: diff --git a/oscardata/oscardata/bin/Release/oscardata.exe b/oscardata/oscardata/bin/Release/oscardata.exe index c628888..bdff112 100755 Binary files a/oscardata/oscardata/bin/Release/oscardata.exe and b/oscardata/oscardata/bin/Release/oscardata.exe differ diff --git a/oscardata/oscardata/receivefile.cs b/oscardata/oscardata/receivefile.cs index f4babcd..fdc9c27 100755 --- a/oscardata/oscardata/receivefile.cs +++ b/oscardata/oscardata/receivefile.cs @@ -189,7 +189,7 @@ namespace oscardata if (!autoRXnum) blockidx = rxfrmnum; - Console.WriteLine("minfo:" + minfo + " framenum:" + rxfrmnum + " blockidx:" + blockidx); + //Console.WriteLine("minfo:" + minfo + " framenum:" + rxfrmnum + " blockidx:" + blockidx); Array.Copy(rxd, 10, rxdata, 0, rxd.Length - 10); return true; diff --git a/oscardata/oscardata/udp.cs b/oscardata/oscardata/udp.cs index 474fa42..645144a 100755 --- a/oscardata/oscardata/udp.cs +++ b/oscardata/oscardata/udp.cs @@ -175,7 +175,7 @@ namespace oscardata } static int panelw = 75, panelh = 75; - static int maxdrawanz = 160; + static int maxdrawanz = 350;//160; static int drawanz = 0; static Bitmap bm; static void drawBitmap(Int32 re, Int32 im)